[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: config files substitution with awk

From: Paul Eggert
Subject: Re: config files substitution with awk
Date: Tue, 21 Nov 2006 13:04:01 -0800
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)

Ralf Wildenhues <address@hidden> writes:

> Thanks.  FWIW, Solaris awk seems to choose only the first character,
> rather than erroring out (which seemed unobvious to me from the above
> description).

Sorry, I'll improve the description.  See below.

> - Choose for FS a character unlikely to occur often; I'd guess # or ~
>   should work?

Yes.  I'd prefer something like that to invoking sed twice extra.
You could even use control-G, say.  (But please see below.)

> I have another Solaris awk issue, and don't know how to get around
> this easily: it supports `index in array' only in for statements:

That should be documented.  I'll install the patch enclosed at the
end of this message.

> Note that rewriting this to, say, test for nonempty 'array[index]'
> instead (and using a marker to distinguish empty replacement strings)
> could be quite memory-intensive, due to all the new array members
> created on the way, so I'd prefer not to go that way, but I admit to
> not having tested this.

I wouldn't worry about this unless it's demonstratably bad.  But if it
is, then perhaps we can use a dynamic test like this:

if awk 'BEGIN {a[1] = 1; if (1 in a) exit}' </dev/null 2>/dev/null; then
  ... use "if (x in a)" ...
  ... use "if (a_is_set[x])" ...

That way, only ancient implementations will have the performance
penalty.  (But please see below.)

> +        while ((getline aline < (F[key])) > 0)

I don't think this'll work with Solaris /bin/awk; it has only plain
'getline', with no support for | or <.  (Old traditional Awk didn't
have getline at all.)

One way to work around this would be to pipe the output of 'awk' into
'sh', and have 'sh' do the interpolation by calling 'cat'.  Or we
could go back to using 'sed' for file interpolation.  In either case,
we could use getline if our dynamic test succeeds.

Or, if we can't come up with a better solution, perhaps we should go
back to using AC_PROG_AWK.  Perhaps that's simpler.  After all, we'd
have to go back quite a ways to find a host without a modern Awk.  But
if we go this route, perhaps we should check that the Awk that we use
actually has all the features we need.

2006-11-21  Paul Eggert  <address@hidden>

        * doc/autoconf.texi (Limitations of Usual Tools):
        Mention that if (i in a) doesn't work with traditional Awk.
        Clarify previous patch.

--- autoconf.texi.~1.1108~      2006-11-21 12:15:23.000000000 -0800
+++ autoconf.texi       2006-11-21 12:50:47.000000000 -0800
@@ -13046,23 +13046,26 @@ Traditional Awk supports only the predef
 Traditional Awk @code{getline} is not at all compatible with Posix;
 avoid it.
-In traditional Awk, @code{FS} must be a string containing just one
-ordinary character, and similarly for the field-separator argument to
+Traditional Awk has @code{for (i in a) @dots{}} but no other uses of the
address@hidden keyword.  For example, it lacks @code{if (i in a) @dots{}}.
+In code portable to both traditional and modern Awk, @code{FS} must be a
+string containing just one ordinary character, and similarly for the
+field-separator argument to @code{split}.
 Traditional Awk has a limit of 99
 fields in a record.  You may be able to circumvent this problem by using
+Traditional Awk has a limit of at most 99 bytes in a number formatted by
address@hidden; for example, @code{OFMT="%.300e"; print 0.1;} typically
+dumps core.
 The original version of Awk had a limit of at most 99 bytes per
 @code{split} field, 99 bytes per @code{substr} substring, and 99 bytes
 per run of non-special characters in a @code{printf} format, but these
 bugs have been fixed on all practical hosts that we know of.
-Traditional Awk has a limit of at most 99 bytes in a number formatted by
address@hidden; for example, @code{OFMT="%.300e"; print 0.1;} will dump
 @item @command{basename}
 @c ---------------------
 @prindex @command{basename}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]