Hi Z.,
in my original solution, the call to the original package inside of
pcrepli_compile was pcre_compile, not COMPILE8; the name was translated by
#pragma map.
You replaced this by COMPILE8, which is part of the COBOL glue code, if I recall
it correctly.
Although not necessary in my opinion, you are free to do this.
But: if COMPILE8 has the same signature as pcre_compile of the original package,
the call must be
*p6 = COMPILE8 (*p1, *p2, p3, p4, *p5);
not the way you did it in your post below.
See p2 for example; you have to pass an int to COMPILE8 as a second parameter,
not a pointer to an int.
Kind regards
Bernd
Am 24.03.2014 01:31, schrieb Z.A.:
> >I think all the argument twiddling could be done in the C program
> >(caller or callee) assuming you're willing to accept changes to the C code.
>
> This is a port of an open source library to classic z/OS (Specifically NOT OS/2).
> The C code cannot be changed because
> a) I have no control over the C code, and
> b) the COBOL interface does not need any twiddling since it can communicate
> with C without any issue whatever. The need for twiddling is in order to
> overcome PL/1 specific issues which are not shared by either C or COBOL
> or any other LE language.
>
> This classic z/OS environment also rules out any use of Iron Spring PL/I specific niceties.
> Also, I cannot dictate to people who want to use the library that they should compile
> their classic z/OS PL/I source code in any way that may jeopardize their normal
> (none-C) calling convention or any other normal things that they do.
>
> My issue is how to pass parameters correctly when the PL/1 descriptors are in the middle.
> C has to see a pure string or a struct without the descriptors.
> The C signature may expect any of
>
> int
> int *
> char *
> char **
> sometype *
>
> I used Bernd's glue program technique. For example look at these snpetts:
>
> #pragma map (pcrepli_compile , "PPRECOM ")
>
> int pcrepli_compile (const char **p1,
> int *p2,
> const char **p3,
> int *p4,
> const unsigned char **p5,
> pcre **p6)
>
> {
> *p6 = COMPILE8 (*p1, p2, **p3, *p4, *p5);
>
> /* => COMPILE8 C library native signature
> pcre *pcre_compile(const char *pattern, int options,
> const char **errptr, int *erroffset,
> const unsigned char *tableptr);*/
>
> return (*p6 == NULL ? -1 : 0);
> }
>
> and in the PL/1 side
>
> /* PCRE_COMPILE */
>
> DCL PPRECOM EXTERNAL ENTRY
> (PTR, /* ADDR (CHAR) */
> BIN FIXED (31),
> PTR, /* ADDR (CHAR) */
> PTR, /* ADDR INT */
> PTR, /* ADDR (CHAR) */
> PTR); /* ADDR (PCRE) */
>
>
> Dcl
> rcx fixed bin (31);
>
> Pattern = '(?<char>A)\g<char>' || '00'X;
> Subject = 'AN_AARDWARK_JAKE_AND_AARDWARK' || '00'X;
> Subject_length = Length(Subject);
> Re = Sysnull();
> rcx = PPRECOM (Addr(Pattern), /* the pattern */
> Zero, /* default options */
> Addr(Error), /* for error message */
> Addr(Erroffset), /* for error offset */
> Sysnull(), /* use default character tables */
> addr(Re));
>
> But that does not work right and with my limitted C knowledge,
I cannot figure out what is passed wrong and in which direction.
>
>
> Z.A.
> From: P.F.
> To: PL1-L@LISTSERV.DARTMOUTH.EDU
> Sent: Sunday, March 23, 2014 11:09 PM
> Subject: Re: Passing parameters to C
>
>
>
> On 03/23/2014 06:28 PM, Bernd Oppolzer wrote:
> >
> > The glue functions have to do the transformation of the PL/1 compatible
> > interface to the original interface of the C library.
>
> I think all the argument twiddling could be done in the C program
> (caller or callee) assuming you're willing to accept changes to the C code.
>
> ...
>
> >
> > With the problem of NUL-terminated strings, you have to make a decision;
> > either PL/1 or C has to accept the logic of the other side. If the PL/1 side
> > wants the strings to be filled with blanks and have no NULL termination;
> > C can cope with this (but you have to take care, if you want to use some
> > of ther str... functions, anyway). If you want the strings to have nulls, you
> > have some troubles on the PL/1 side ... with old compilers, the new
> > ones have CHAR (x) VARZ, which is one of the nicest things if you
> > have to deal with C functions from PL/1 callers.
>
> On the other hand this is (mostly) easily handled by PL/I. A PL/I
> program passing a (nonassignable) string argument to a C function can
> just pass the argument as the expression ('string' || '00'x).
>
> [To digress a bit, Iron Spring PL/I has the procedure and entry option
> LINKAGE(SYSTEM) - borrowed from OS/2 PL/I - to generate C-compatible
> calls and entries. I haven't yet implemented the new(ish) options like
> BYVALUE, etc., but I have found I can do everything I need using this.]
>
> ...
> >
> > Kind regards
> >
> > Bernd
> >
> > Am 23.03.2014 21:44, schrieb S.H.:
> >>
> >> One thing you can do to alleviate a bit of pain is to have parallel PL/I and C
> >> include files that declare such things as array dimensions and string lengths,
> >> to avoid the trap of parallel maintenance. You could even do a script that
> >> would generate both from a common source, and make that a step in the build
> >> script.
>
>
> S. - here I'm not on as sure ground, but I used to generate
> dual-language PL/I and ASM include files using logic stolen from IBM's
> PL/S and ASM macros. I think you could do the same with PL/I and C.
> For example having the PL/I left margin start at 4 you could code the
> PL/I definition first surrounded by '/*' in columns 2 and 3 to make them
> comments for C. At the end the PL/I code could %GOTO the end, the %GOTO
> followed by the C code.
>
> What we really need is SDL (like your script) to maintain a set of
> language-independent definitions and then generate both the C and PL/I
> declarations. Oh well, someday.
>
>
>
|