Fix conflicts. Add $FreeBSD$ as needed.
This commit is contained in:
parent
4d6ff07db5
commit
1abc97f5cf
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=51731
@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1986, 1988, 1989, 1991-1997 the Free Software Foundation, Inc.
|
||||
* Copyright (C) 1986, 1988, 1989, 1991-1999 the Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GAWK, the GNU implementation of the
|
||||
* AWK Programming Language.
|
||||
@ -21,10 +21,20 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* ------------------------------ Includes ------------------------------ */
|
||||
|
||||
/*
|
||||
* config.h absolutely, positively, *M*U*S*T* be included before
|
||||
* any system headers. Otherwise, extreme death, destruction
|
||||
* and loss of life results.
|
||||
*
|
||||
* Well, OK, gawk just won't work on systems using egcs and LFS. But
|
||||
* that's almost as bad.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
@ -34,6 +44,7 @@
|
||||
#endif /* _GNU_SOURCE */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif /* HAVE_LIMITS_H */
|
||||
@ -588,7 +599,8 @@ extern char casetable[]; /* for case-independent regexp matching */
|
||||
/* ------------------------- Pseudo-functions ------------------------- */
|
||||
|
||||
#define is_identchar(c) (isalnum(c) || (c) == '_')
|
||||
#define isnondecimal(str) (((str)[0]) == '0')
|
||||
#define isnondecimal(str) (((str)[0]) == '0' && (ISDIGIT((str)[1]) \
|
||||
|| (str)[1] == 'x' || (str)[1] == 'X'))
|
||||
|
||||
#ifdef MPROF
|
||||
#define getnode(n) emalloc(n, NODE *, sizeof(NODE), "getnode")
|
||||
|
@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1986, 1988, 1989, 1991-1997 the Free Software Foundation, Inc.
|
||||
* Copyright (C) 1986, 1988, 1989, 1991-1999 the Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GAWK, the GNU implementation of the
|
||||
* AWK Programming Language.
|
||||
@ -21,11 +21,12 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
|
||||
#include "awk.h"
|
||||
#include <assert.h>
|
||||
#undef HUGE
|
||||
#undef CHARBITS
|
||||
#undef INTBITS
|
||||
@ -410,6 +411,7 @@ register NODE *carg;
|
||||
double tmpval;
|
||||
char signchar = FALSE;
|
||||
size_t len;
|
||||
int zero_flag = FALSE;
|
||||
static char sp[] = " ";
|
||||
static char zero_string[] = "0";
|
||||
static char lchbuf[] = "0123456789abcdef";
|
||||
@ -437,6 +439,7 @@ register NODE *carg;
|
||||
prec = 0;
|
||||
have_prec = FALSE;
|
||||
signchar = FALSE;
|
||||
zero_flag = FALSE;
|
||||
lj = alt = big = bigbig = small = FALSE;
|
||||
fill = sp;
|
||||
cp = cend;
|
||||
@ -460,10 +463,9 @@ register NODE *carg;
|
||||
break;
|
||||
|
||||
case '0':
|
||||
zero_flag = TRUE;
|
||||
if (lj)
|
||||
goto retry;
|
||||
if (cur == &fw)
|
||||
fill = zero_string;
|
||||
/* FALL through */
|
||||
case '1':
|
||||
case '2':
|
||||
@ -587,6 +589,8 @@ register NODE *carg;
|
||||
goto retry;
|
||||
case 'c':
|
||||
need_format = FALSE;
|
||||
if (zero_flag && ! lj)
|
||||
fill = zero_string;
|
||||
parse_next_arg();
|
||||
/* user input that looks numeric is numeric */
|
||||
if ((arg->flags & (MAYBE_NUM|NUMBER)) == MAYBE_NUM)
|
||||
@ -611,6 +615,8 @@ register NODE *carg;
|
||||
goto pr_tail;
|
||||
case 's':
|
||||
need_format = FALSE;
|
||||
if (zero_flag && ! lj)
|
||||
fill = zero_string;
|
||||
parse_next_arg();
|
||||
arg = force_string(arg);
|
||||
if (! have_prec || prec > arg->stlen)
|
||||
@ -622,6 +628,14 @@ register NODE *carg;
|
||||
need_format = FALSE;
|
||||
parse_next_arg();
|
||||
tmpval = force_number(arg);
|
||||
|
||||
/*
|
||||
* ``The result of converting a zero value with a
|
||||
* precision of zero is no characters.''
|
||||
*/
|
||||
if (have_prec && prec == 0 && tmpval == 0)
|
||||
goto pr_tail;
|
||||
|
||||
if (tmpval < 0) {
|
||||
if (tmpval < LONG_MIN)
|
||||
goto out_of_range;
|
||||
@ -639,17 +653,28 @@ register NODE *carg;
|
||||
*--cp = (char) ('0' + uval % 10);
|
||||
uval /= 10;
|
||||
} while (uval > 0);
|
||||
|
||||
/* add more output digits to match the precision */
|
||||
if (have_prec) {
|
||||
while (cend - cp < prec)
|
||||
*--cp = '0';
|
||||
}
|
||||
|
||||
if (sgn)
|
||||
*--cp = '-';
|
||||
else if (signchar)
|
||||
*--cp = signchar;
|
||||
/*
|
||||
* precision overrides '0' flags. however, for
|
||||
* integer formats, precsion is minimum number of
|
||||
* *digits*, not characters, thus we want to fill
|
||||
* with zeroes.
|
||||
* When to fill with zeroes is of course not simple.
|
||||
* First: No zero fill if left-justifying.
|
||||
* Next: There seem to be two cases:
|
||||
* A '0' without a precision, e.g. %06d
|
||||
* A precision with no field width, e.g. %.10d
|
||||
* Any other case, we don't want to fill with zeroes.
|
||||
*/
|
||||
if (have_prec)
|
||||
if (! lj
|
||||
&& ((zero_flag && ! have_prec)
|
||||
|| (fw == 0 && have_prec)))
|
||||
fill = zero_string;
|
||||
if (prec > fw)
|
||||
fw = prec;
|
||||
@ -673,6 +698,22 @@ register NODE *carg;
|
||||
need_format = FALSE;
|
||||
parse_next_arg();
|
||||
tmpval = force_number(arg);
|
||||
|
||||
/*
|
||||
* ``The result of converting a zero value with a
|
||||
* precision of zero is no characters.''
|
||||
*
|
||||
* If I remember the ANSI C standard, though,
|
||||
* it says that for octal conversions
|
||||
* the precision is artificially increased
|
||||
* to add an extra 0 if # is supplied.
|
||||
* Indeed, in C,
|
||||
* printf("%#.0o\n", 0);
|
||||
* prints a single 0.
|
||||
*/
|
||||
if (! alt && have_prec && prec == 0 && tmpval == 0)
|
||||
goto pr_tail;
|
||||
|
||||
if (tmpval < 0) {
|
||||
if (tmpval < LONG_MIN)
|
||||
goto out_of_range;
|
||||
@ -685,18 +726,29 @@ register NODE *carg;
|
||||
uval = (unsigned long) tmpval;
|
||||
}
|
||||
/*
|
||||
* precision overrides '0' flags. however, for
|
||||
* integer formats, precsion is minimum number of
|
||||
* *digits*, not characters, thus we want to fill
|
||||
* with zeroes.
|
||||
* When to fill with zeroes is of course not simple.
|
||||
* First: No zero fill if left-justifying.
|
||||
* Next: There seem to be two cases:
|
||||
* A '0' without a precision, e.g. %06d
|
||||
* A precision with no field width, e.g. %.10d
|
||||
* Any other case, we don't want to fill with zeroes.
|
||||
*/
|
||||
if (have_prec)
|
||||
if (! lj
|
||||
&& ((zero_flag && ! have_prec)
|
||||
|| (fw == 0 && have_prec)))
|
||||
fill = zero_string;
|
||||
do {
|
||||
*--cp = chbuf[uval % base];
|
||||
uval /= base;
|
||||
} while (uval > 0);
|
||||
if (alt) {
|
||||
|
||||
/* add more output digits to match the precision */
|
||||
if (have_prec) {
|
||||
while (cend - cp < prec)
|
||||
*--cp = '0';
|
||||
}
|
||||
|
||||
if (alt && tmpval != 0) {
|
||||
if (base == 16) {
|
||||
*--cp = cs1;
|
||||
*--cp = '0';
|
||||
@ -755,7 +807,7 @@ register NODE *carg;
|
||||
*cp++ = signchar;
|
||||
if (alt)
|
||||
*cp++ = '#';
|
||||
if (fill != sp)
|
||||
if (zero_flag)
|
||||
*cp++ = '0';
|
||||
cp = strcpy(cp, "*.*") + 3;
|
||||
*cp++ = cs1;
|
||||
@ -1084,6 +1136,7 @@ register NODE *tree;
|
||||
register FILE *fp;
|
||||
int numnodes, i;
|
||||
NODE *save;
|
||||
NODE *tval;
|
||||
|
||||
if (tree->rnode) {
|
||||
int errflg; /* not used, sigh */
|
||||
@ -1117,25 +1170,29 @@ register NODE *tree;
|
||||
t[i] = dupnode(n);
|
||||
free_temp(n);
|
||||
|
||||
if (t[i]->flags & NUMBER) {
|
||||
if ((t[i]->flags & (NUMBER|STRING)) == NUMBER) {
|
||||
if (OFMTidx == CONVFMTidx)
|
||||
(void) force_string(t[i]);
|
||||
else
|
||||
t[i] = format_val(OFMT, OFMTidx, t[i]);
|
||||
else {
|
||||
tval = tmp_number(t[i]->numbr);
|
||||
unref(t[i]);
|
||||
t[i] = format_val(OFMT, OFMTidx, tval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < numnodes; i++) {
|
||||
efwrite(t[i]->stptr, sizeof(char), t[i]->stlen, fp, "print", rp, FALSE);
|
||||
unref(t[i]);
|
||||
if (i != numnodes - 1) {
|
||||
if (OFSlen > 0)
|
||||
efwrite(OFS, sizeof(char), (size_t) OFSlen,
|
||||
fp, "print", rp, FALSE);
|
||||
}
|
||||
|
||||
if (i != numnodes - 1 && OFSlen > 0)
|
||||
efwrite(OFS, sizeof(char), (size_t) OFSlen,
|
||||
fp, "print", rp, FALSE);
|
||||
|
||||
}
|
||||
if (ORSlen > 0)
|
||||
efwrite(ORS, sizeof(char), (size_t) ORSlen, fp, "print", rp, TRUE);
|
||||
|
||||
free(t);
|
||||
}
|
||||
|
||||
@ -1512,6 +1569,7 @@ int how_many, backdigs;
|
||||
*/
|
||||
if (lastmatchnonzero && matchstart == matchend) {
|
||||
lastmatchnonzero = FALSE;
|
||||
matches--;
|
||||
goto empty;
|
||||
}
|
||||
/*
|
||||
@ -2022,6 +2080,7 @@ size_t len;
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
val = *str - 'a' + 10;
|
||||
break;
|
||||
case 'A':
|
||||
@ -2029,6 +2088,7 @@ size_t len;
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
val = *str - 'A' + 10;
|
||||
break;
|
||||
default:
|
||||
@ -2039,11 +2099,12 @@ size_t len;
|
||||
} else if (*str == '0') {
|
||||
for (; len > 0; len--) {
|
||||
if (! isdigit(*str) || *str == '8' || *str == '9')
|
||||
goto done;
|
||||
goto decimal;
|
||||
retval = (retval * 8) + (*str - '0');
|
||||
str++;
|
||||
}
|
||||
} else {
|
||||
decimal:
|
||||
save = str[len];
|
||||
retval = atof(str);
|
||||
str[len] = save;
|
||||
|
@ -1,7 +1,8 @@
|
||||
.\" $FreeBSD$
|
||||
.ds PX \s-1POSIX\s+1
|
||||
.ds UX \s-1UNIX\s+1
|
||||
.ds AN \s-1ANSI\s+1
|
||||
.TH GAWK 1 "Dec 19 1996" "Free Software Foundation" "Utility Commands"
|
||||
.TH GAWK 1 "Apr 28 1999" "Free Software Foundation" "Utility Commands"
|
||||
.SH NAME
|
||||
gawk \- pattern scanning and processing language
|
||||
.SH SYNOPSIS
|
||||
@ -2150,6 +2151,12 @@ Functions may call each other and may be recursive.
|
||||
Function parameters used as local variables are initialized
|
||||
to the null string and the number zero upon function invocation.
|
||||
.PP
|
||||
Use
|
||||
.BI return " expr"
|
||||
to return a value from a function. The return value is undefined if no
|
||||
value is provided, or if the function returns by ``falling off'' the
|
||||
end.
|
||||
.PP
|
||||
If
|
||||
.B \-\^\-lint
|
||||
has been provided,
|
||||
@ -2535,7 +2542,7 @@ and the effort to do so really is not worth it.
|
||||
.SH VERSION INFORMATION
|
||||
This man page documents
|
||||
.IR gawk ,
|
||||
version 3.0.2.
|
||||
version 3.0.4.
|
||||
.SH AUTHORS
|
||||
The original version of \*(UX
|
||||
.I awk
|
||||
@ -2566,10 +2573,10 @@ help from Darrel Hankerson. Fred Fish supplied support for the Amiga.
|
||||
If you find a bug in
|
||||
.IR gawk ,
|
||||
please send electronic mail to
|
||||
.BR bug-gnu-utils@prep.ai.mit.edu ,
|
||||
.BR bug-gnu-utils@gnu.org ,
|
||||
.I with
|
||||
a carbon copy to
|
||||
.BR arnold@gnu.ai.mit.edu .
|
||||
.BR arnold@gnu.org .
|
||||
Please include your operating system and its revision, the version of
|
||||
.IR gawk ,
|
||||
what C compiler you used to compile it, and a test program
|
||||
@ -2598,7 +2605,7 @@ Brian Kernighan of Bell Labs
|
||||
provided valuable assistance during testing and debugging.
|
||||
We thank him.
|
||||
.SH COPYING PERMISSIONS
|
||||
Copyright \(co\) 1996 Free Software Foundation, Inc.
|
||||
Copyright \(co) 1996,97,98,99 Free Software Foundation, Inc.
|
||||
.PP
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual page provided the copyright notice and this permission
|
||||
|
@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1986, 1988, 1989, 1991-1997 the Free Software Foundation, Inc.
|
||||
* Copyright (C) 1986, 1988, 1989, 1991-1999 the Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GAWK, the GNU implementation of the
|
||||
* AWK Programming Language.
|
||||
@ -21,12 +21,12 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "awk.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
extern double pow P((double x, double y));
|
||||
extern double modf P((double x, double *yp));
|
||||
extern double fmod P((double x, double y));
|
||||
@ -566,14 +566,26 @@ register NODE *volatile tree;
|
||||
break;
|
||||
|
||||
case Node_K_next:
|
||||
if (in_begin_rule)
|
||||
fatal("`next' cannot be called from a BEGIN rule");
|
||||
else if (in_end_rule)
|
||||
fatal("`next' cannot be called from an END rule");
|
||||
|
||||
if (in_function())
|
||||
pop_fcall_stack();
|
||||
|
||||
longjmp(rule_tag, TAG_CONTINUE);
|
||||
break;
|
||||
|
||||
case Node_K_nextfile:
|
||||
if (in_begin_rule)
|
||||
fatal("`nextfile' cannot be called from a BEGIN rule");
|
||||
else if (in_end_rule)
|
||||
fatal("`nextfile' cannot be called from an END rule");
|
||||
|
||||
if (in_function())
|
||||
pop_fcall_stack();
|
||||
|
||||
do_nextfile();
|
||||
break;
|
||||
|
||||
@ -759,7 +771,8 @@ int iscond;
|
||||
register size_t len;
|
||||
char *str;
|
||||
register char *dest;
|
||||
int count;
|
||||
int alloc_count, str_count;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* This is an efficiency hack for multiple adjacent string
|
||||
@ -773,16 +786,16 @@ int iscond;
|
||||
/*
|
||||
* But first, no arbitrary limits. Count the number of
|
||||
* nodes and malloc the treelist and strlist arrays.
|
||||
* There will be count + 1 items to concatenate. We
|
||||
* There will be alloc_count + 1 items to concatenate. We
|
||||
* also leave room for an extra pointer at the end to
|
||||
* use as a sentinel. Thus, start count at 2.
|
||||
* use as a sentinel. Thus, start alloc_count at 2.
|
||||
*/
|
||||
save_tree = tree;
|
||||
for (count = 2; tree && tree->type == Node_concat; tree = tree->lnode)
|
||||
count++;
|
||||
for (alloc_count = 2; tree && tree->type == Node_concat; tree = tree->lnode)
|
||||
alloc_count++;
|
||||
tree = save_tree;
|
||||
emalloc(treelist, NODE **, sizeof(NODE *) * count, "tree_eval");
|
||||
emalloc(strlist, NODE **, sizeof(NODE *) * count, "tree_eval");
|
||||
emalloc(treelist, NODE **, sizeof(NODE *) * alloc_count, "tree_eval");
|
||||
emalloc(strlist, NODE **, sizeof(NODE *) * alloc_count, "tree_eval");
|
||||
|
||||
/* Now, here we go. */
|
||||
treep = treelist;
|
||||
@ -795,15 +808,26 @@ int iscond;
|
||||
* Now, evaluate to strings in LIFO order, accumulating
|
||||
* the string length, so we can do a single malloc at the
|
||||
* end.
|
||||
*
|
||||
* Evaluate the expressions first, then get their
|
||||
* lengthes, in case one of the expressions has a
|
||||
* side effect that changes one of the others.
|
||||
* See test/nasty.awk.
|
||||
*/
|
||||
strp = strlist;
|
||||
len = 0;
|
||||
while (treep >= treelist) {
|
||||
*strp = force_string(tree_eval(*treep--));
|
||||
len += (*strp)->stlen;
|
||||
strp++;
|
||||
}
|
||||
*strp = NULL;
|
||||
|
||||
str_count = strp - strlist;
|
||||
strp = strlist;
|
||||
for (i = 0; i < str_count; i++) {
|
||||
len += (*strp)->stlen;
|
||||
strp++;
|
||||
}
|
||||
emalloc(str, char *, len+2, "tree_eval");
|
||||
str[len] = str[len+1] = '\0'; /* for good measure */
|
||||
dest = str;
|
||||
@ -1397,6 +1421,11 @@ NODE *arg_list; /* Node_expression_list of calling args. */
|
||||
* r_get_lhs:
|
||||
* This returns a POINTER to a node pointer. get_lhs(ptr) is the current
|
||||
* value of the var, or where to store the var's new value
|
||||
*
|
||||
* For the special variables, don't unref their current value if it's
|
||||
* the same as the internal copy; perhaps the current one is used in
|
||||
* a concatenation or some other expression somewhere higher up in the
|
||||
* call chain. Ouch.
|
||||
*/
|
||||
|
||||
NODE **
|
||||
@ -1409,8 +1438,11 @@ Func_ptr *assign;
|
||||
|
||||
if (assign)
|
||||
*assign = NULL; /* for safety */
|
||||
if (ptr->type == Node_param_list)
|
||||
if (ptr->type == Node_param_list) {
|
||||
if ((ptr->flags & FUNC) != 0)
|
||||
fatal("can't use function name `%s' as variable or array", ptr->vname);
|
||||
ptr = stack_ptr[ptr->param_cnt];
|
||||
}
|
||||
|
||||
switch (ptr->type) {
|
||||
case Node_var_array:
|
||||
@ -1444,26 +1476,32 @@ Func_ptr *assign;
|
||||
break;
|
||||
|
||||
case Node_FNR:
|
||||
unref(FNR_node->var_value);
|
||||
FNR_node->var_value = make_number((AWKNUM) FNR);
|
||||
if (FNR_node->var_value->numbr != FNR) {
|
||||
unref(FNR_node->var_value);
|
||||
FNR_node->var_value = make_number((AWKNUM) FNR);
|
||||
}
|
||||
aptr = &(FNR_node->var_value);
|
||||
if (assign != NULL)
|
||||
*assign = set_FNR;
|
||||
break;
|
||||
|
||||
case Node_NR:
|
||||
unref(NR_node->var_value);
|
||||
NR_node->var_value = make_number((AWKNUM) NR);
|
||||
if (NR_node->var_value->numbr != NR) {
|
||||
unref(NR_node->var_value);
|
||||
NR_node->var_value = make_number((AWKNUM) NR);
|
||||
}
|
||||
aptr = &(NR_node->var_value);
|
||||
if (assign != NULL)
|
||||
*assign = set_NR;
|
||||
break;
|
||||
|
||||
case Node_NF:
|
||||
if (NF == -1)
|
||||
(void) get_field(HUGE-1, assign); /* parse record */
|
||||
unref(NF_node->var_value);
|
||||
NF_node->var_value = make_number((AWKNUM) NF);
|
||||
if (NF == -1 || NF_node->var_value->numbr != NF) {
|
||||
if (NF == -1)
|
||||
(void) get_field(HUGE-1, assign); /* parse record */
|
||||
unref(NF_node->var_value);
|
||||
NF_node->var_value = make_number((AWKNUM) NF);
|
||||
}
|
||||
aptr = &(NF_node->var_value);
|
||||
if (assign != NULL)
|
||||
*assign = set_NF;
|
||||
|
@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1986, 1988, 1989, 1991-1997 the Free Software Foundation, Inc.
|
||||
* Copyright (C) 1986, 1988, 1989, 1991-1999 the Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GAWK, the GNU implementation of the
|
||||
* AWK Programming Language.
|
||||
@ -21,10 +21,11 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "awk.h"
|
||||
#include <assert.h>
|
||||
|
||||
typedef void (* Setfunc) P((long, char *, long, NODE *));
|
||||
|
||||
@ -63,6 +64,9 @@ int default_FS; /* TRUE when FS == " " */
|
||||
Regexp *FS_regexp = NULL;
|
||||
static NODE *Null_field = NULL;
|
||||
|
||||
/* using_FIELDWIDTHS --- static function, macro to avoid overhead */
|
||||
#define using_FIELDWIDTHS() (parse_field == fw_parse_field)
|
||||
|
||||
/* init_fields --- set up the fields array to start with */
|
||||
|
||||
void
|
||||
@ -140,7 +144,6 @@ rebuild_record()
|
||||
char *ops;
|
||||
register char *cops;
|
||||
long i;
|
||||
char *f0start, *f0end;
|
||||
|
||||
assert(NF != -1);
|
||||
|
||||
@ -184,15 +187,27 @@ rebuild_record()
|
||||
* any fields that still point into it, and have them point
|
||||
* into the new field zero.
|
||||
*/
|
||||
f0start = fields_arr[0]->stptr;
|
||||
f0end = fields_arr[0]->stptr + fields_arr[0]->stlen;
|
||||
for (cops = ops, i = 1; i <= NF; i++) {
|
||||
char *field_data = fields_arr[i]->stptr;
|
||||
if (fields_arr[i]->stlen > 0) {
|
||||
NODE *n;
|
||||
getnode(n);
|
||||
|
||||
if (fields_arr[i]->stlen > 0
|
||||
&& f0start <= field_data && field_data < f0end)
|
||||
fields_arr[i]->stptr = cops;
|
||||
if ((fields_arr[i]->flags & FIELD) == 0) {
|
||||
*n = *Null_field;
|
||||
n->stlen = fields_arr[i]->stlen;
|
||||
if ((fields_arr[i]->flags & (NUM|NUMBER)) != 0) {
|
||||
n->flags |= (fields_arr[i]->flags & (NUM|NUMBER));
|
||||
n->numbr = fields_arr[i]->numbr;
|
||||
}
|
||||
} else {
|
||||
*n = *(fields_arr[i]);
|
||||
n->flags &= ~(MALLOC|TEMP|PERM|STRING);
|
||||
}
|
||||
|
||||
n->stptr = cops;
|
||||
unref(fields_arr[i]);
|
||||
fields_arr[i] = n;
|
||||
}
|
||||
cops += fields_arr[i]->stlen + ofslen;
|
||||
}
|
||||
|
||||
@ -751,7 +766,7 @@ NODE *tree;
|
||||
arr->type = Node_var_array;
|
||||
assoc_clear(arr);
|
||||
|
||||
if (sep->re_flags & FS_DFLT) {
|
||||
if ((sep->re_flags & FS_DFLT) != 0 && ! using_FIELDWIDTHS()) {
|
||||
parseit = parse_field;
|
||||
fs = force_string(FS_node->var_value);
|
||||
rp = FS_regexp;
|
||||
@ -851,20 +866,20 @@ set_FS()
|
||||
if (fields_arr != NULL)
|
||||
(void) get_field(HUGE - 1, 0);
|
||||
|
||||
if (save_fs && cmp_nodes(FS_node->var_value, save_fs) == 0
|
||||
&& save_rs && cmp_nodes(RS_node->var_value, save_rs) == 0)
|
||||
return;
|
||||
unref(save_fs);
|
||||
save_fs = dupnode(FS_node->var_value);
|
||||
unref(save_rs);
|
||||
save_rs = dupnode(RS_node->var_value);
|
||||
resave_fs = TRUE;
|
||||
buf[0] = '\0';
|
||||
default_FS = FALSE;
|
||||
if (FS_regexp) {
|
||||
refree(FS_regexp);
|
||||
FS_regexp = NULL;
|
||||
if (! (save_fs && cmp_nodes(FS_node->var_value, save_fs) == 0
|
||||
&& save_rs && cmp_nodes(RS_node->var_value, save_rs) == 0)) {
|
||||
unref(save_fs);
|
||||
save_fs = dupnode(FS_node->var_value);
|
||||
unref(save_rs);
|
||||
save_rs = dupnode(RS_node->var_value);
|
||||
resave_fs = TRUE;
|
||||
if (FS_regexp) {
|
||||
refree(FS_regexp);
|
||||
FS_regexp = NULL;
|
||||
}
|
||||
}
|
||||
buf[0] = '\0';
|
||||
default_FS = FALSE;
|
||||
fs = force_string(FS_node->var_value);
|
||||
if (! do_traditional && fs->stlen == 0)
|
||||
parse_field = null_parse_field;
|
||||
@ -887,7 +902,7 @@ set_FS()
|
||||
if (fs->stptr[0] == ' ' && fs->stlen == 1)
|
||||
default_FS = TRUE;
|
||||
else if (fs->stptr[0] != ' ' && fs->stlen == 1) {
|
||||
if (! IGNORECASE)
|
||||
if (! IGNORECASE || ! isalpha(fs->stptr[0]))
|
||||
parse_field = sc_parse_field;
|
||||
else if (fs->stptr[0] == '\\')
|
||||
/* yet another special case */
|
||||
@ -910,6 +925,5 @@ set_FS()
|
||||
int
|
||||
using_fieldwidths()
|
||||
{
|
||||
return parse_field == fw_parse_field;
|
||||
return using_FIELDWIDTHS();
|
||||
}
|
||||
|
||||
|
105
contrib/awk/io.c
105
contrib/awk/io.c
@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1986, 1988, 1989, 1991-1997 the Free Software Foundation, Inc.
|
||||
* Copyright (C) 1976, 1988, 1989, 1991-1999 the Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GAWK, the GNU implementation of the
|
||||
* AWK Programming Language.
|
||||
@ -21,6 +21,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "awk.h"
|
||||
@ -49,8 +51,6 @@
|
||||
#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#if ! defined(S_ISREG) && defined(S_IFREG)
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
@ -95,19 +95,8 @@ static int specfdopen P((IOBUF *iop, const char *name, const char *mode));
|
||||
static int pidopen P((IOBUF *iop, const char *name, const char *mode));
|
||||
static int useropen P((IOBUF *iop, const char *name, const char *mode));
|
||||
|
||||
#if defined (MSDOS) && !defined (__GO32__)
|
||||
#if defined (HAVE_POPEN_H)
|
||||
#include "popen.h"
|
||||
#define popen(c, m) os_popen(c, m)
|
||||
#define pclose(f) os_pclose(f)
|
||||
#else
|
||||
#if defined (OS2) /* OS/2, but not family mode */
|
||||
#if defined (_MSC_VER)
|
||||
#define popen(c, m) _popen(c, m)
|
||||
#define pclose(f) _pclose(f)
|
||||
#endif
|
||||
#else
|
||||
extern FILE *popen();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static struct redirect *red_head = NULL;
|
||||
@ -125,6 +114,15 @@ extern NODE **fields_arr;
|
||||
|
||||
static jmp_buf filebuf; /* for do_nextfile() */
|
||||
|
||||
#ifdef VMS
|
||||
/* File pointers have an extra level of indirection, and there are cases where
|
||||
`stdin' can be null. That can crash gawk if fileno() is used as-is. */
|
||||
static int vmsrtl_fileno P((FILE *));
|
||||
static int vmsrtl_fileno(fp) FILE *fp; { return fileno(fp); }
|
||||
#undef fileno
|
||||
#define fileno(FP) (((FP) && *(FP)) ? vmsrtl_fileno(FP) : -1)
|
||||
#endif /* VMS */
|
||||
|
||||
/* do_nextfile --- implement gawk "nextfile" extension */
|
||||
|
||||
void
|
||||
@ -487,9 +485,10 @@ int *errflg;
|
||||
/* too many files open -- close one and try again */
|
||||
if (errno == EMFILE || errno == ENFILE)
|
||||
close_one();
|
||||
#ifdef HAVE_MMAP
|
||||
#if defined __MINGW32__ || defined HAVE_MMAP
|
||||
/* this works for solaris 2.5, not sunos */
|
||||
else if (errno == 0) /* HACK! */
|
||||
/* it is also needed for MINGW32 */
|
||||
else if (errno == 0) /* HACK! */
|
||||
close_one();
|
||||
#endif
|
||||
else {
|
||||
@ -573,24 +572,22 @@ NODE *tree;
|
||||
|
||||
tmp = force_string(tree_eval(tree->subnode));
|
||||
|
||||
/* icky special case: close(FILENAME) called. */
|
||||
if (tree->subnode == FILENAME_node
|
||||
|| (tmp->stlen == FILENAME_node->var_value->stlen
|
||||
&& STREQN(tmp->stptr, FILENAME_node->var_value->stptr, tmp->stlen))) {
|
||||
(void) nextfile(TRUE);
|
||||
free_temp(tmp);
|
||||
return tmp_number((AWKNUM) 0.0);
|
||||
}
|
||||
|
||||
for (rp = red_head; rp != NULL; rp = rp->next) {
|
||||
if (strlen(rp->value) == tmp->stlen
|
||||
&& STREQN(rp->value, tmp->stptr, tmp->stlen))
|
||||
break;
|
||||
}
|
||||
|
||||
if (rp == NULL) { /* no match */
|
||||
if (do_lint)
|
||||
/* icky special case: close(FILENAME) called. */
|
||||
if (tree->subnode == FILENAME_node
|
||||
|| (tmp->stlen == FILENAME_node->var_value->stlen
|
||||
&& STREQN(tmp->stptr, FILENAME_node->var_value->stptr, tmp->stlen))) {
|
||||
(void) nextfile(TRUE);
|
||||
} else if (do_lint)
|
||||
warning("close: `%.*s' is not an open file or pipe",
|
||||
tmp->stlen, tmp->stptr);
|
||||
|
||||
free_temp(tmp);
|
||||
return tmp_number((AWKNUM) 0.0);
|
||||
}
|
||||
@ -888,11 +885,11 @@ const char *name, *mode;
|
||||
int i;
|
||||
|
||||
if (name[6] == 'g')
|
||||
sprintf(tbuf, "%d\n", getpgrp(getpgrp_arg()));
|
||||
sprintf(tbuf, "%d\n", (int) getpgrp(getpgrp_arg()));
|
||||
else if (name[6] == 'i')
|
||||
sprintf(tbuf, "%d\n", getpid());
|
||||
sprintf(tbuf, "%d\n", (int) getpid());
|
||||
else
|
||||
sprintf(tbuf, "%d\n", getppid());
|
||||
sprintf(tbuf, "%d\n", (int) getppid());
|
||||
i = strlen(tbuf);
|
||||
spec_setup(iop, i, TRUE);
|
||||
strcpy(iop->buf, tbuf);
|
||||
@ -923,7 +920,7 @@ const char *name, *mode;
|
||||
int ngroups;
|
||||
#endif
|
||||
|
||||
sprintf(tbuf, "%d %d %d %d", getuid(), geteuid(), getgid(), getegid());
|
||||
sprintf(tbuf, "%d %d %d %d", (int) getuid(), (int) geteuid(), (int) getgid(), (int) getegid());
|
||||
|
||||
cp = tbuf + strlen(tbuf);
|
||||
#if defined(NGROUPS_MAX) && NGROUPS_MAX > 0
|
||||
@ -1008,7 +1005,7 @@ IOBUF *iop;
|
||||
if (openfd == INVALID_HANDLE)
|
||||
openfd = open(name, flag, 0666);
|
||||
if (openfd != INVALID_HANDLE && fstat(openfd, &buf) > 0)
|
||||
if ((buf.st_mode & S_IFMT) == S_IFDIR)
|
||||
if (S_ISDIR(buf.st_mode))
|
||||
fatal("file `%s' is a directory", name);
|
||||
return iop_alloc(openfd, name, iop);
|
||||
}
|
||||
@ -1120,7 +1117,7 @@ struct redirect *rp;
|
||||
* except if popen() provides real pipes too
|
||||
*/
|
||||
|
||||
#if defined(VMS) || defined(OS2) || defined (MSDOS)
|
||||
#if defined(VMS) || defined(OS2) || defined (MSDOS) || defined(WIN32)
|
||||
|
||||
/* gawk_popen --- open an IOBUF on a child process */
|
||||
|
||||
@ -1135,7 +1132,7 @@ struct redirect *rp;
|
||||
return NULL;
|
||||
rp->iop = iop_alloc(fileno(current), cmd, NULL);
|
||||
if (rp->iop == NULL) {
|
||||
(void) fclose(current);
|
||||
(void) pclose(current);
|
||||
current = NULL;
|
||||
}
|
||||
rp->ifp = current;
|
||||
@ -1434,7 +1431,12 @@ IOBUF *iop;
|
||||
iop->name = name;
|
||||
iop->getrec = get_a_record;
|
||||
#ifdef HAVE_MMAP
|
||||
if (S_ISREG(sbuf.st_mode) && sbuf.st_size > 0) {
|
||||
/* Use mmap only for regular files with positive sizes.
|
||||
The size must fit into size_t, so that mmap works correctly.
|
||||
Also, it must fit into int, so that iop->cnt won't overflow. */
|
||||
if (S_ISREG(sbuf.st_mode) && sbuf.st_size > 0
|
||||
&& sbuf.st_size == (size_t) sbuf.st_size
|
||||
&& sbuf.st_size == (int) sbuf.st_size) {
|
||||
register char *cp;
|
||||
|
||||
iop->buf = iop->off = mmap((caddr_t) 0, sbuf.st_size,
|
||||
@ -1535,7 +1537,7 @@ int *errcode; /* pointer to error variable */
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (grRS == FALSE) /* special case: RS == "" */
|
||||
if (RS_is_null) /* special case: RS == "" */
|
||||
rs = '\n';
|
||||
else
|
||||
rs = (char) grRS;
|
||||
@ -1648,7 +1650,7 @@ int *errcode; /* pointer to error variable */
|
||||
*/
|
||||
if (! do_traditional && RSre != NULL) /* regexp */
|
||||
rsre = RSre;
|
||||
else if (grRS == FALSE) /* RS = "" */
|
||||
else if (RS_is_null) /* RS = "" */
|
||||
rsre = RS_null_re;
|
||||
else
|
||||
rsre = NULL;
|
||||
@ -1675,6 +1677,21 @@ int *errcode; /* pointer to error variable */
|
||||
/* cases 1 and 2 are simple, just keep going */
|
||||
if (research(rsre, start, 0, iop->end - start, TRUE) == -1
|
||||
|| RESTART(rsre, start) == REEND(rsre, start)) {
|
||||
/*
|
||||
* Leading newlines at the beginning of the file
|
||||
* should be ignored. Whew!
|
||||
*/
|
||||
if (RS_is_null && *start == '\n') {
|
||||
/*
|
||||
* have to catch the case of a
|
||||
* single newline at the front of
|
||||
* the record, which the regex
|
||||
* doesn't. gurr.
|
||||
*/
|
||||
while (*start == '\n' && start < iop->end)
|
||||
start++;
|
||||
goto again;
|
||||
}
|
||||
bp = iop->end;
|
||||
continue;
|
||||
}
|
||||
@ -1690,8 +1707,10 @@ int *errcode; /* pointer to error variable */
|
||||
/*
|
||||
* Leading newlines at the beginning of the file
|
||||
* should be ignored. Whew!
|
||||
*
|
||||
* Is this code ever executed?
|
||||
*/
|
||||
if (grRS == FALSE && RESTART(rsre, start) == 0) {
|
||||
if (RS_is_null && RESTART(rsre, start) == 0) {
|
||||
start += REEND(rsre, start);
|
||||
goto again;
|
||||
}
|
||||
@ -1737,7 +1756,7 @@ int *errcode; /* pointer to error variable */
|
||||
bstart = bp;
|
||||
}
|
||||
*bp = '\0';
|
||||
} else if (grRS == FALSE && iop->cnt == EOF) {
|
||||
} else if (RS_is_null && iop->cnt == EOF) {
|
||||
/*
|
||||
* special case, delete trailing newlines,
|
||||
* should never be more than one.
|
||||
@ -1811,7 +1830,7 @@ int *errcode; /* pointer to error variable */
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (grRS == FALSE) /* special case: RS == "" */
|
||||
if (RS_is_null) /* special case: RS == "" */
|
||||
rs = '\n';
|
||||
else
|
||||
rs = (char) grRS;
|
||||
@ -1821,7 +1840,7 @@ int *errcode; /* pointer to error variable */
|
||||
rs = casetable[rs];
|
||||
|
||||
/* if RS = "", skip leading newlines at the front of the file */
|
||||
if (grRS == FALSE && iop->off == iop->buf) {
|
||||
if (RS_is_null && iop->off == iop->buf) {
|
||||
for (bp = iop->off; *bp == '\n'; bp++)
|
||||
continue;
|
||||
|
||||
@ -1835,7 +1854,7 @@ int *errcode; /* pointer to error variable */
|
||||
*/
|
||||
if (! do_traditional && RSre != NULL) /* regexp */
|
||||
rsre = RSre;
|
||||
else if (grRS == FALSE) /* RS = "" */
|
||||
else if (RS_is_null) /* RS = "" */
|
||||
rsre = RS_null_re;
|
||||
else
|
||||
rsre = NULL;
|
||||
@ -1862,7 +1881,7 @@ int *errcode; /* pointer to error variable */
|
||||
iop->off = iop->end; /* all done with the record */
|
||||
set_RT_to_null();
|
||||
/* special case, don't allow trailing newlines */
|
||||
if (grRS == FALSE && *(iop->end - 1) == '\n')
|
||||
if (RS_is_null && *(iop->end - 1) == '\n')
|
||||
return iop->end - start - 1;
|
||||
else
|
||||
return iop->end - start;
|
||||
|
@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1986, 1988, 1989, 1991-1997 the Free Software Foundation, Inc.
|
||||
* Copyright (C) 1986, 1988, 1989, 1991-1999 the Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GAWK, the GNU implementation of the
|
||||
* AWK Programming Language.
|
||||
@ -21,6 +21,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "awk.h"
|
||||
@ -439,8 +441,8 @@ FILE *fp;
|
||||
fputs("\t-W traditional\t\t--traditional\n", fp);
|
||||
fputs("\t-W usage\t\t--usage\n", fp);
|
||||
fputs("\t-W version\t\t--version\n", fp);
|
||||
fputs("\nReport bugs to bug-gnu-utils@prep.ai.mit.edu,\n", fp);
|
||||
fputs("with a Cc: to arnold@gnu.ai.mit.edu\n", fp);
|
||||
fputs("\nReport bugs to bug-gnu-utils@gnu.org,\n", fp);
|
||||
fputs("with a Cc: to arnold@gnu.org\n", fp);
|
||||
exit(exitval);
|
||||
}
|
||||
|
||||
@ -450,7 +452,7 @@ static void
|
||||
copyleft()
|
||||
{
|
||||
static char blurb_part1[] =
|
||||
"Copyright (C) 1989, 1991-1997 Free Software Foundation.\n\
|
||||
"Copyright (C) 1989, 1991-1999 Free Software Foundation.\n\
|
||||
\n\
|
||||
This program is free software; you can redistribute it and/or modify\n\
|
||||
it under the terms of the GNU General Public License as published by\n\
|
||||
|
@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 1986, 1988, 1989, 1991-1997 the Free Software Foundation, Inc.
|
||||
* Copyright (C) 1986, 1988, 1989, 1991-1999 the Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GAWK, the GNU implementation of the
|
||||
* AWK Programming Language.
|
||||
@ -21,6 +21,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "awk.h"
|
||||
@ -36,6 +38,7 @@ register NODE *n;
|
||||
char save;
|
||||
char *ptr;
|
||||
unsigned int newflags;
|
||||
extern double strtod();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (n == NULL)
|
||||
@ -140,7 +143,16 @@ register NODE *s;
|
||||
/* not an integral value, or out of range */
|
||||
if ((val = double_to_int(s->numbr)) != s->numbr
|
||||
|| val < LONG_MIN || val > LONG_MAX) {
|
||||
#ifdef GFMT_WORKAROUND
|
||||
/*
|
||||
* Once upon a time, if GFMT_WORKAROUND wasn't defined,
|
||||
* we just blindly did this:
|
||||
* sprintf(sp, format, s->numbr);
|
||||
* s->stlen = strlen(sp);
|
||||
* s->stfmt = (char) index;
|
||||
* but that's no good if, e.g., OFMT is %s. So we punt,
|
||||
* and just always format the value ourselves.
|
||||
*/
|
||||
|
||||
NODE *dummy, *r;
|
||||
unsigned short oflags;
|
||||
extern NODE *format_tree P((const char *, int, NODE *));
|
||||
@ -161,15 +173,6 @@ register NODE *s;
|
||||
freenode(dummy); /* to keep s->stptr == r->stpr. */
|
||||
|
||||
goto no_malloc;
|
||||
#else
|
||||
/*
|
||||
* no need for a "replacement" formatting by gawk,
|
||||
* just use sprintf
|
||||
*/
|
||||
sprintf(sp, format, s->numbr);
|
||||
s->stlen = strlen(sp);
|
||||
s->stfmt = (char) index;
|
||||
#endif /* GFMT_WORKAROUND */
|
||||
} else {
|
||||
/* integral value */
|
||||
/* force conversion to long only once */
|
||||
@ -183,11 +186,9 @@ register NODE *s;
|
||||
}
|
||||
s->stfmt = -1;
|
||||
}
|
||||
emalloc(s->stptr, char *, s->stlen + 2, "force_string");
|
||||
emalloc(s->stptr, char *, s->stlen + 2, "format_val");
|
||||
memcpy(s->stptr, sp, s->stlen+1);
|
||||
#ifdef GFMT_WORKAROUND
|
||||
no_malloc:
|
||||
#endif /* GFMT_WORKAROUND */
|
||||
s->stref = 1;
|
||||
s->flags |= STR;
|
||||
return s;
|
||||
@ -495,7 +496,9 @@ char **string_ptr;
|
||||
}
|
||||
i = 0;
|
||||
for (;;) {
|
||||
if (ISXDIGIT((c = *(*string_ptr)++))) {
|
||||
/* do outside test to avoid multiple side effects */
|
||||
c = *(*string_ptr)++;
|
||||
if (ISXDIGIT(c)) {
|
||||
i *= 16;
|
||||
if (ISDIGIT(c))
|
||||
i += c - '0';
|
||||
|
Loading…
Reference in New Issue
Block a user