Bugs in -P and -I handling

111 views
Skip to first unread message

Craig Johnson

unread,
Oct 31, 1990, 8:20:55 PM10/31/90
to

Masochist that I am, I just finished bringing up patchlevel 37 on a 3B1
running OS release 3.0 [sic]. (I'll post further info on this to
unix-pc.general shortly). In the process of trying to pass all the
regression tests, I could find no way to pass test 3 in "comp.cpp" as
given. Checking further, I found that test 3 passes ok on a Sun 4 running
OS 4.0.3.

In this test perl is invoked with -P and -I`pwd`. The C preprocessor
(invoked through cc -E) is asked to #include <Comp.cpp.inc> which has been
constructed in the current working directory. Notice the angle-brackets.
Looking at the perl sources it can be seen that cpp is invoked with -I to
specify additional include directories but only PRIVLIB (compiled in perl
library path) is passed to it. The 3B1 fails because its cpp doesn't
include "." in the standard set of system include directories, whereas
the Sun passes because "." is included in its list of standard include
directories.

-------------------------
Assert bug #1:
The test "comp.cpp" depends on system-specific implementations
of cpp that have different ideas about standard system include
directories.

The 3B1 will pass the test if the angle-brackets are changed to
double-quotes.

Assert bug #2:
The man page says -I affects the directories cpp will look at
if -P is also used. Presently if -P is specified, cpp looks
only at standard cpp places (i.e. /usr/include) and PRIVLIB
(e.g. /usr/lib/perl). The perl -I switch has no effect on cpp.
All -I arguments are apparently added to @INC for use only by
"require".
-------------------------

While trying to put this posting together I whipped up an example which
failed miserably and exposed yet another couple of bugs (probably closely
related).

In ./tmp/perltest.h:
$ok = "We got the include file\n";

Execute the following in ".":

#!/usr/local/perl -Itmp -P

$ok = "Include file not seen\n";
#include <perltest.h>;
print $ok;
printf "%s\n", join(" ",@INC);

We get on the output:

Include file not seen
tmp -P /usr/local/lib/perl .

-------------------------
Assert bug #3:
In the above example, "-P" does not belong as a member of @INC.
-------------------------

I'm on a roll now. In the above example, changing #include to require
we have:

#!/usr/local/perl -Itmp -P

$ok = "Include file not seen\n";
require 'perltest.h';
print $ok;
printf "%s\n", join(" ",@INC);

And get:

Can't locate perltest.h in @INC (change .h to .ph maybe?) (did you run h2ph?) at xxx line 4.


One more time. Moving the -P to the left of -I:

#!/usr/local/perl -P -Itmp

Yields:

Unrecognized switch: - -Itmp.

-------------------------
Assert bug #4:
Command line parsing in the presence of "-P" when "require" is
used is fouled up.
-------------------------

Finally, remove the "-P" switch altogether and the script runs correctly
outputting:

We got the include file
tmp /usr/local/lib/perl .

I'm sure someone will let me know if I've fantisized all this. I haven't
been getting enough sleep since I started in to bring up PL37 on my old
clunker ;-). Thanks for the good work Larry! I couldn't live without
perl.

==========================================================
Craig V. Johnson ...!fluke!vince
John Fluke Mfg. Co. or
Everett, WA vi...@tc.fluke.com
==========================================================

Larry Wall

unread,
Nov 1, 1990, 2:35:00 PM11/1/90
to
In article <1990Nov1.0...@tc.fluke.COM> vi...@tc.fluke.COM (Craig Johnson) writes:
:
: Masochist that I am, I just finished bringing up patchlevel 37 on a 3B1

: running OS release 3.0 [sic]. (I'll post further info on this to
: unix-pc.general shortly). In the process of trying to pass all the
: regression tests, I could find no way to pass test 3 in "comp.cpp" as
: given. Checking further, I found that test 3 passes ok on a Sun 4 running
: OS 4.0.3.
:
: In this test perl is invoked with -P and -I`pwd`. The C preprocessor
: (invoked through cc -E) is asked to #include <Comp.cpp.inc> which has been
: constructed in the current working directory. Notice the angle-brackets.
: Looking at the perl sources it can be seen that cpp is invoked with -I to
: specify additional include directories but only PRIVLIB (compiled in perl
: library path) is passed to it. The 3B1 fails because its cpp doesn't
: include "." in the standard set of system include directories, whereas
: the Sun passes because "." is included in its list of standard include
: directories.
:
: -------------------------
: Assert bug #1:
: The test "comp.cpp" depends on system-specific implementations
: of cpp that have different ideas about standard system include
: directories.
:
: The 3B1 will pass the test if the angle-brackets are changed to
: double-quotes.

This one's a real bug, and will be fixed in 38 (by changing to double quotes).

: Assert bug #2:


: The man page says -I affects the directories cpp will look at
: if -P is also used. Presently if -P is specified, cpp looks
: only at standard cpp places (i.e. /usr/include) and PRIVLIB
: (e.g. /usr/lib/perl). The perl -I switch has no effect on cpp.
: All -I arguments are apparently added to @INC for use only by
: "require".

I think you're misreading the source. Note that -I accumulates into
the STR* str, which is str_cat'ed to add PRIVLIB. Anyway, it works
right here.

: While trying to put this posting together I whipped up an example which


: failed miserably and exposed yet another couple of bugs (probably closely
: related).

Well, there's definitely a common theme...

: In ./tmp/perltest.h:


: $ok = "We got the include file\n";
:
: Execute the following in ".":
:
: #!/usr/local/perl -Itmp -P
:
: $ok = "Include file not seen\n";
: #include <perltest.h>;
: print $ok;
: printf "%s\n", join(" ",@INC);
:
: We get on the output:
:
: Include file not seen
: tmp -P /usr/local/lib/perl .
:
: -------------------------
: Assert bug #3:
: In the above example, "-P" does not belong as a member of @INC.
: -------------------------

This makes perfect sense when you realize that #! only allows a single
argument. What you've got is in invocation that is effectively:

perl -I"tmp -P"

: I'm on a roll now. In the above example, changing #include to require


: we have:
:
: #!/usr/local/perl -Itmp -P
:
: $ok = "Include file not seen\n";
: require 'perltest.h';
: print $ok;
: printf "%s\n", join(" ",@INC);
:
: And get:
:
: Can't locate perltest.h in @INC (change .h to .ph maybe?) (did you run h2ph?) at xxx line 4.

Same reason, it's looking in directory "tmp -P".

: One more time. Moving the -P to the left of -I:


:
: #!/usr/local/perl -P -Itmp
:
: Yields:
:
: Unrecognized switch: - -Itmp.
:
: -------------------------
: Assert bug #4:
: Command line parsing in the presence of "-P" when "require" is
: used is fouled up.
: -------------------------

No, it knows that -P allows switch bundling, and since there's a non-null
character (a space) after the P, it must be another switch, " -Itmp".
And don't tell me there isn't one bit of difference between null and space,
because that's exactly how much difference there is. :-)

: Finally, remove the "-P" switch altogether and the script runs correctly


: outputting:
:
: We got the include file
: tmp /usr/local/lib/perl .

Because you've only used one switch.

: I'm sure someone will let me know if I've fantisized all this.

No, you're sane, just misguided... :-)

To do what you wanted in the first place, just make use of switch bundling:

#!/usr/local/perl -PItmp

To get more switches than one, you have to invoke perl explicitly, or use
a variant of the eval-exec hack.

: I haven't


: been getting enough sleep since I started in to bring up PL37 on my old
: clunker ;-). Thanks for the good work Larry! I couldn't live without
: perl.

You're welcome.

Larry

Reply all
Reply to author
Forward
0 new messages