aboutsummaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2010-07-16 14:47:02 +0300
committerArnold D. Robbins <arnold@skeeve.com>2010-07-16 14:47:02 +0300
commit315bd501ca696bc3e3c938b4604d8dac7a6f512f (patch)
treecf992f0df002126292f7487ca6c0d36d7fe748b9 /main.c
parent85c0d5edb781c9f31b79e48452b1ca68643f41de (diff)
downloadegawk-315bd501ca696bc3e3c938b4604d8dac7a6f512f.tar.gz
egawk-315bd501ca696bc3e3c938b4604d8dac7a6f512f.tar.bz2
egawk-315bd501ca696bc3e3c938b4604d8dac7a6f512f.zip
Move to gawk 3.1.5.
Diffstat (limited to 'main.c')
-rw-r--r--main.c87
1 files changed, 72 insertions, 15 deletions
diff --git a/main.c b/main.c
index 87a22958..847ae54e 100644
--- a/main.c
+++ b/main.c
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2004 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2005 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -20,9 +20,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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
+/* FIX THIS BEFORE EVERY RELEASE: */
+#define UPDATE_YEAR 2005
+
#include "awk.h"
#include "getopt.h"
@@ -44,6 +47,8 @@ static void copyleft P((void)) ATTRIBUTE_NORETURN;
static void cmdline_fs P((char *str));
static void init_args P((int argc0, int argc, char *argv0, char **argv));
static void init_vars P((void));
+static NODE *load_environ P((void));
+static NODE *load_procinfo P((void));
static void add_src P((struct src **data, long *num, long *alloc, enum srctype stype, char *val));
static RETSIGTYPE catchsig P((int sig)) ATTRIBUTE_NORETURN;
static void nostalgia P((void)) ATTRIBUTE_NORETURN;
@@ -82,9 +87,9 @@ int errcount = 0; /* error counter, used by yyerror() */
NODE *Nnull_string; /* The global null string */
-#if ENABLE_NLS && defined(HAVE_LOCALE_H)
+#if defined(HAVE_LOCALE_H)
struct lconv loc; /* current locale */
-#endif /* ENABLE_NLS && defined(HAVE_LOCALE_H) */
+#endif /* defined(HAVE_LOCALE_H) */
/* The name the program was invoked under, for error messages */
const char *myname;
@@ -113,6 +118,8 @@ static struct src *preassigns = NULL; /* requested via -v or -F */
static long numassigns = -1; /* how many of them */
static long allocassigns; /* for how many is allocated */
+static int disallow_var_assigns = FALSE; /* true for --exec */
+
#define preassigns_add(stype, val) \
add_src(&preassigns, &numassigns, &allocassigns, stype, val)
@@ -135,7 +142,9 @@ int in_begin_rule = FALSE; /* we're in a BEGIN rule */
int in_end_rule = FALSE; /* we're in a END rule */
int whiny_users = FALSE; /* do things that whiny users want */
#ifdef MBS_SUPPORT
-int gawk_mb_cur_max = 1; /* MB_CUR_MAX value, see comment in main() */
+int gawk_mb_cur_max; /* MB_CUR_MAX value, see comment in main() */
+#else
+const int gawk_mb_cur_max = 1;
#endif
int output_is_tty = FALSE; /* control flushing of output */
@@ -181,6 +190,7 @@ static const struct option optab[] = {
{ "version", no_argument, NULL, 'V' },
{ "usage", no_argument, NULL, 'u' },
{ "help", no_argument, NULL, 'u' },
+ { "exec", required_argument, NULL, 'S' },
#ifdef GAWKDEBUG
{ "parsedebug", no_argument, NULL, 'D' },
#endif
@@ -207,6 +217,7 @@ main(int argc, char **argv)
extern int opterr;
extern char *optarg;
int i;
+ int stdio_problem = FALSE;
/* do these checks early */
if (getenv("TIDYMEM") != NULL)
@@ -226,7 +237,7 @@ main(int argc, char **argv)
#if defined(LC_COLLATE)
setlocale(LC_COLLATE, "");
#endif
-#if HAVE_LC_MESSAGES && defined(LC_MESSAGES)
+#if defined(LC_MESSAGES)
setlocale(LC_MESSAGES, "");
#endif
#if defined(LC_NUMERIC)
@@ -249,6 +260,7 @@ main(int argc, char **argv)
* this value once makes a speed difference.
*/
gawk_mb_cur_max = MB_CUR_MAX;
+ /* Without MBS_SUPPORT, gawk_mb_cur_max is 1. */
#endif
(void) bindtextdomain(PACKAGE, LOCALEDIR);
@@ -292,6 +304,9 @@ main(int argc, char **argv)
preassigns_add(PRE_ASSIGN_FS, optarg);
break;
+ case 'S':
+ disallow_var_assigns = TRUE;
+ /* fall through */
case 'f':
/*
* a la MKS awk, allow multiple -f options.
@@ -436,6 +451,8 @@ main(int argc, char **argv)
let getopt print error message for us */
break;
}
+ if (c == 'S') /* --exec ends option processing */
+ break;
}
out:
@@ -532,6 +549,15 @@ out:
init_args(optind, argc, (char *) myname, argv);
(void) tokexpand();
+#if defined(LC_NUMERIC)
+ /*
+ * FRAGILE! CAREFUL!
+ * Pre-initing the variables with arg_assign() can change the
+ * locale. Force it to C before parsing the program.
+ */
+ setlocale(LC_NUMERIC, "C");
+#endif
+
/* Read in the program */
if (yyparse() != 0 || errcount != 0)
exit(1);
@@ -555,7 +581,7 @@ out:
setlocale(LC_NUMERIC, "");
#endif
-#if ENABLE_NLS && defined(HAVE_LOCALE_H)
+#if defined(HAVE_LOCALE_H)
loc = *localeconv(); /* Make a local copy of locale numeric info */
#endif
@@ -572,7 +598,23 @@ out:
(void) interpret(end_block);
}
in_end_rule = FALSE;
- if (close_io() != 0 && ! exiting && exit_val == 0)
+ /*
+ * This used to be:
+ *
+ * if (close_io() != 0 && ! exiting && exit_val == 0)
+ * exit_val = 1;
+ *
+ * Other awks don't care about problems closing open files
+ * and pipes, in that it doesn't affect their exit status.
+ * So we no longer do either.
+ */
+ (void) close_io(& stdio_problem);
+ /*
+ * However, we do want to exit non-zero if there was a problem
+ * with stdout/stderr, so we reinstate a slightly different
+ * version of the above:
+ */
+ if (stdio_problem && ! exiting && exit_val == 0)
exit_val = 1;
if (do_profiling) {
@@ -636,6 +678,7 @@ usage(int exitval, FILE *fp)
fputs(_("\t-W copyleft\t\t--copyleft\n"), fp);
fputs(_("\t-W copyright\t\t--copyright\n"), fp);
fputs(_("\t-W dump-variables[=file]\t--dump-variables[=file]\n"), fp);
+ fputs(_("\t-W exec=file\t\t--exec=file\n"), fp);
fputs(_("\t-W gen-po\t\t--gen-po\n"), fp);
fputs(_("\t-W help\t\t\t--help\n"), fp);
fputs(_("\t-W lint[=fatal]\t\t--lint[=fatal]\n"), fp);
@@ -670,8 +713,11 @@ By default it reads standard input and writes standard output.\n\n"), fp);
fflush(fp);
- if (ferror(fp))
+ if (ferror(fp)) {
+ if (fp == stdout)
+ warning(_("error writing standard output (%s)"), strerror(errno));
exit(1);
+ }
exit(exitval);
}
@@ -698,16 +744,18 @@ GNU General Public License for more details.\n\
static const char blurb_part3[] =
N_("You should have received a copy of the GNU General Public License\n\
along with this program; if not, write to the Free Software\n\
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n");
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n");
/* multiple blurbs are needed for some brain dead compilers. */
- printf(_(blurb_part1), 2003); /* Last update year */
+ printf(_(blurb_part1), UPDATE_YEAR); /* Last update year */
fputs(_(blurb_part2), stdout);
fputs(_(blurb_part3), stdout);
fflush(stdout);
- if (ferror(stdout))
+ if (ferror(stdout)) {
+ warning(_("error writing standard output (%s)"), strerror(errno));
exit(1);
+ }
exit(0);
}
@@ -816,11 +864,16 @@ init_vars()
if (vp->assign)
(*(vp->assign))();
}
+
+ /* Set up deferred variables (loaded only when accessed). */
+ if (! do_traditional)
+ register_deferred_variable("PROCINFO", load_procinfo);
+ register_deferred_variable("ENVIRON", load_environ);
}
/* load_environ --- populate the ENVIRON array */
-NODE *
+static NODE *
load_environ()
{
#if ! defined(TANDEM)
@@ -867,7 +920,7 @@ load_environ()
/* load_procinfo --- populate the PROCINFO array */
-NODE *
+static NODE *
load_procinfo()
{
int i;
@@ -952,6 +1005,9 @@ arg_assign(char *arg, int initing)
NODE *it;
NODE **lhs;
+ if (! initing && disallow_var_assigns)
+ return FALSE; /* --exec */
+
cp = strchr(arg, '=');
if (cp == NULL) {
@@ -1066,6 +1122,7 @@ init_fds()
struct stat sbuf;
int fd;
int newfd;
+ char const *const opposite_mode[] = {"w", "r", "r"};
/* maybe no stderr, don't bother with error mesg */
for (fd = 0; fd <= 2; fd++) {
@@ -1074,7 +1131,7 @@ init_fds()
if (do_lint)
lintwarn(_("no pre-opened fd %d"), fd);
#endif
- newfd = devopen("/dev/null", "r+");
+ newfd = devopen("/dev/null", opposite_mode[fd]);
/* turn off some compiler warnings "set but not used" */
newfd += 0;
#ifdef MAKE_A_HEROIC_EFFORT