in reply to Command line question

Here it is spread out:

while (<>) { s+${SOURCE}/${SAMS}/++g; s+${SOURCE}/${SAMLIB}/++g; s+${SOURCE}/${SMCLIB}/+${SOURCE}/${KENO}/+g; if ( not m+^${SOURCE}/+ ) { s+${SOURCE}/+\$$\{OBJECT\}/+g; print } }

This is run on a file named ".depend", and then something else runs after that.

I'm guessing that ${SOURCE} and friends are being interpolated somehow (even though they're in single quotes) because there's nothing in the Perl to give those variables values.

Anyway, this is using "+" instead of "/" for the delimiters on s///, probably so that it can put a literal slash in there without having to backslash it. What it does (for each line) is something like:

  1. Remove "${SOURCE}/${SAMS}/" and "${SOURCE}/${SAMLIB}/" anywhere in the line.
  2. Replace every "${SOURCE}/${SMCLIB}/" with "${SOURCE}/${KENO}/"
  3. If the line starts with "${SOURCE}/", replace every "${SOURCE}" with a literal "${OBJECT}" (I think), and print the line.
  4. (Lines that don't start with "${SOURCE}/" are not printed and so removed.)

Replies are listed 'Best First'.
Re^2: Command line question
by ikegami (Patriarch) on Jun 17, 2008 at 23:39 UTC

    I'm guessing that ${SOURCE} and friends are being interpolated somehow (even though they're in single quotes)

    Those quotes are processed by the shell. In the bourne shell or a derivative like bash, single quote don't perform any interpolation.

    $ echo "${PATH}" .:/home/ikegami/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/gam +es $ echo '${PATH}' ${PATH}

    ( Here on end, assuming the bourne shell or a derivative like bash )

    So Perl sees

    BEGIN { $^I = ''; } while (<>) { s+${SOURCE}/${SAMS}/++g; s+${SOURCE}/${SAMLIB}/++g; s+${SOURCE}/${SMCLIB}/+${SOURCE}/${KENO}/+g; if ( not m+^${SOURCE}/+ ) { s+${SOURCE}/+\$$\{OBJECT\}/+g; print } }

    On the other hand, Perl regexp and replace expressions *do* interpolate. So the above is equivalent to

    BEGIN { $^I = ''; } while (<>) { s+//++g; s+//++g; s+//+//+g; if ( not m+^/+ ) { s+/+\${OBJECT}/+g; print } }

    Depending on what the OP wants to do, he needs to use -e"" instead of -e'', to escape the dollar signs, or to define those variables in Perl.

      My guess is that the code snippet is from a make file (while we are guessing).

      Ordinarily, I'd agree with you, but I get the impression that the OP's code works as-is, and he's just trying to figure out what it does and how. My guess is that the whole thing is in double quotes, and what perl actually sees is:

      BEGIN { $^I = ""; } LINE: while (defined($_ = <ARGV>)) { s[value-of-SOURCE/value-of-SAMS/][]g; s[value-of-SOURCE/value-of-SAMLIB/][]g; s[value-of-SOURCE/value-of-SMCLIB/][value-of-SOURCE/value-of-KENO/ +]g; if (not m[^value-of-SOURCE/]) { s[value-of-SOURCE/][$${OBJECT}/]g; print $_; } }

      That $${OBJECT} in there still seems wrong, though, and the OP is ambiguous about whether this is working code or not, so I'm pretty far from sure about this.

        Yeah, you're dead on. This line is from a Makefile from an old code. This line has been stumping us a bit, and I'm the only one that knows Perl (and I don't know it that well), so I got lost trying to search this through as so many of the delimiters were odd to me (the s+ and ++g etc...).

        So this is working code that does what it's supposed to, but I'm having trouble totally seeing what it does. I'd like to actually get the .depend file before the Perl script, then again after it to compare ... it may shed some light for me.

        So what you're thinking is that each instance of ${something} is actually some value, stored in ${something} being passed in to the Perl script? Is that roughly correct?

        Finally, could the $${OBJECT} be right? Could it be substituting the value of ${OBJECT}, with a preceding "$" sign into the code, to be read and interpreted by the shell?

        I may be way off and talking over my head too, if it doesn't make sense, don't try to make it as it's probably wrong.

        Thanks!

        ~Jack