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:38:10

I forgot to mention:

with the pcre structure as shown by D. the different alignment logic between
PL/1 and C is not a problem, because the structure starts with a series of BIN
FIXED (31) fields, which is the highest alignment need appearing in the
structure. But in the general case you have to be very careful with this topic.

Kind regards


Am 25.02.2014 09:28, schrieb Bernd Oppolzer:
> 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 (31).
> 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
> Bernd
> 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