Oppolzer - Informatik / Blog

Blog-Hauptseite      Neuester Artikel      Älterer Artikel      Neuerer Artikel      Älterer gleiche Kategorie      Neuerer gleiche Kategorie

PL1-L - Diskussion über PL/1-Interface für PCRE (Perl compatible Reg. Ex)


Re: calling C from PL/I....


Bernd Oppolzer <bernd.oppolzer@T-ONLINE.DE>


PL1 (language) discussions <PL1-L@LISTSERV.DARTMOUTH.EDU>


2014.02.25 09:28:15

Hello D. and P.,

sorry for jumping in late, in fact P. has made most of the comments that I
would have made.

I would like to take a look at the C prototype again:

extern pcre *COMPILE8 (const char *, int, const char **, int *,
                       const unsigned char *);

I don't know exactly what the function is supposed to do, but:

from earlier posts I recall that the 3. and 4. parameter are pointers to
pointers to errortext buffers and pointers to error code. Dont forget the
second, which is an int byvalue.

Another issue could be that it may be necessary to define the struct pcre at the
PL/1 side - if the caller needs access to the individual components.

My approach would be

dcl compile8 entry
    (ptr byvalue,
     bin fixed (31) byvalue,
     ptr byaddr,
     bin fixed (31) byaddr,
     ptr byvalue)
returns (ptr byvalue);

then the call would look like this:

pcre_result = compile8
    (addr (charz1), int1, ptr2, int2, addr (charz3));

ptr2 and int2 are results from the compile8 call, too.

I hope, I got the meaning of the function right.

When defining structures in PL/1 with a given C layout, you need to keep in mind
that the alignment logic of C and PL/1 is different !!!

To keep it short: in C every structure starts with a boundary that is defined by
the highest alignment need which appears inside the structure (2, 4, 8) - in
PL/1, the beginning of the structure is selected in such a way that paddings are
minimized, that is: a structure containing BIN FIXED (31) may start on a uneven
address, if, for example, a CHAR(3) field is located before the first BIN FIXED

This leads to strange errors, if you are not aware of this.

To cope with this problem, we regularly define a DEC FLOAT field on top of each
structure in PL/1 and C. Doing this, all structures start on an 8 byte boundary,
and the alignment logic of PL/1 and C is then the same.

Then, last comment for today:

Porting a C function or library and moving it to z/OS, for example (and making
it available for PL/1) is not "reinventing the wheel"; in fact, it normally
takes one or two hours, and the function or library will run without issues, if
done properly. Sometimes there are portability issues with the character set,
but in this case, this has already been fixed, because there is a working z/OS
solution, which can be accessed from COBOL. So the one or two hours in my
opinion are well worth the effort.

Z.A.: I'm sorry, that I didn't find the time to support you more in doing
this, but I hope, my comments on those topics where helpful anyway. And thanks
to D. for jumping in.

Kind regards


Am 24.02.2014 19:50, schrieb D.J.:
> Hi, Bernd.
> Many thanks for the tips here; I appreciate it.
> Since C is not my native language (PL/I and Rexx are, btw), let me see
> if I understand what you are saying. The pure C code after being through
> the preprocessor, is this:
> typedef struct real_pcre {
>    pcre_uint32 magic_number;
>    pcre_uint32 size;
>    pcre_uint32 options;
>    pcre_uint16 flags;
>    pcre_uint16 max_lookbehind;
>    pcre_uint16 top_bracket;
>    pcre_uint16 top_backref;
>    pcre_uint16 first_char;
>    pcre_uint16 req_char;
>    pcre_uint16 name_table_offset;
>    pcre_uint16 name_entry_size;
>    pcre_uint16 name_count;
>    pcre_uint16 ref_count;
>    const pcre_uint8 *tables;
>    const pcre_uint8 *nullpad;
> } real_pcre;
> struct real_pcre;
> typedef struct real_pcre pcre;
> extern pcre *COMPILE8(const char *, int, const char **, int *,
>                    const unsigned char *);
> In PL/I it would look like this:
>         char(*) varyingz BYADDR,
>         FIXED BIN(31) BYVAUE,
>         char(*) varyingz BYADDR,
>         FIXED BIN(31) BYADDR,
>         char(*) varyingz BYADDR)
>    RETURNS(byvalue pcre):
> and the call would be:
> pcre =  compile8( string1  /* a varyingz string */
>                  some_int,  /* fixed bin(31)  */
>                  addr(string2),  /* need addr because of indirection */
>                  int2, /* fixed bin(31) by addr here */
>                  some_string /* another varyingz string */  );
> How close did I get?  Did I get the double "* *" correct?
> Another question: would this be possible using the older PL/I for MVS
> and VM that is still in use at some sites?
> Thanks again.
> DJ

Blog-Hauptseite      Neuester Artikel      Älterer Artikel      Neuerer Artikel      Älterer gleiche Kategorie      Neuerer gleiche Kategorie