|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* main.c -- Code generator and main program for gawk.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Copyright (C) 1986, 1988, 1989, 1991-2018 the Free Software Foundation, Inc.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* This file is part of GAWK, the GNU implementation of the
|
|
Packit Service |
f629e6 |
* AWK Programming Language.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* GAWK is free software; you can redistribute it and/or modify
|
|
Packit Service |
f629e6 |
* it under the terms of the GNU General Public License as published by
|
|
Packit Service |
f629e6 |
* the Free Software Foundation; either version 3 of the License, or
|
|
Packit Service |
f629e6 |
* (at your option) any later version.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* GAWK is distributed in the hope that it will be useful,
|
|
Packit Service |
f629e6 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
f629e6 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
f629e6 |
* GNU General Public License for more details.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
f629e6 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
f629e6 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* FIX THIS BEFORE EVERY RELEASE: */
|
|
Packit Service |
f629e6 |
#define UPDATE_YEAR 2018
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#include "awk.h"
|
|
Packit Service |
f629e6 |
#include "getopt.h"
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MCHECK_H
|
|
Packit Service |
f629e6 |
#include <mcheck.h>
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef HAVE_LIBSIGSEGV
|
|
Packit Service |
f629e6 |
#include <sigsegv.h>
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
typedef void *stackoverflow_context_t;
|
|
Packit Service |
f629e6 |
/* the argument to this macro is purposely not used */
|
|
Packit Service |
f629e6 |
#define sigsegv_install_handler(catchsegv) signal(SIGSEGV, catchsig)
|
|
Packit Service |
f629e6 |
/* define as 0 rather than empty so that (void) cast on it works */
|
|
Packit Service |
f629e6 |
#define stackoverflow_install_handler(catchstackoverflow, extra_stack, STACK_SIZE) 0
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#define DEFAULT_PROFILE "awkprof.out" /* where to put profile */
|
|
Packit Service |
f629e6 |
#define DEFAULT_VARFILE "awkvars.out" /* where to put vars */
|
|
Packit Service |
f629e6 |
#define DEFAULT_PREC 53
|
|
Packit Service |
f629e6 |
#define DEFAULT_ROUNDMODE "N" /* round to nearest */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static const char *varfile = DEFAULT_VARFILE;
|
|
Packit Service |
f629e6 |
const char *command_file = NULL; /* debugger commands */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void usage(int exitval, FILE *fp) ATTRIBUTE_NORETURN;
|
|
Packit Service |
f629e6 |
static void copyleft(void) ATTRIBUTE_NORETURN;
|
|
Packit Service |
f629e6 |
static void cmdline_fs(char *str);
|
|
Packit Service |
f629e6 |
static void init_args(int argc0, int argc, const char *argv0, char **argv);
|
|
Packit Service |
f629e6 |
static void init_vars(void);
|
|
Packit Service |
f629e6 |
static NODE *load_environ(void);
|
|
Packit Service |
f629e6 |
static NODE *load_procinfo(void);
|
|
Packit Service |
f629e6 |
static void catchsig(int sig);
|
|
Packit Service |
f629e6 |
#ifdef HAVE_LIBSIGSEGV
|
|
Packit Service |
f629e6 |
static int catchsegv(void *fault_address, int serious);
|
|
Packit Service |
f629e6 |
static void catchstackoverflow(int emergency, stackoverflow_context_t scp);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
static void nostalgia(void) ATTRIBUTE_NORETURN;
|
|
Packit Service |
f629e6 |
static void version(void) ATTRIBUTE_NORETURN;
|
|
Packit Service |
f629e6 |
static void init_fds(void);
|
|
Packit Service |
f629e6 |
static void init_groupset(void);
|
|
Packit Service |
f629e6 |
static void save_argv(int, char **);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
extern int debug_prog(INSTRUCTION *pc); /* debug.c */
|
|
Packit Service |
f629e6 |
extern int init_debug(); /* debug.c */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* These nodes store all the special variables AWK uses */
|
|
Packit Service |
f629e6 |
NODE *ARGC_node, *ARGIND_node, *ARGV_node, *BINMODE_node, *CONVFMT_node;
|
|
Packit Service |
f629e6 |
NODE *ENVIRON_node, *ERRNO_node, *FIELDWIDTHS_node, *FILENAME_node;
|
|
Packit Service |
f629e6 |
NODE *FNR_node, *FPAT_node, *FS_node, *IGNORECASE_node, *LINT_node;
|
|
Packit Service |
f629e6 |
NODE *NF_node, *NR_node, *OFMT_node, *OFS_node, *ORS_node, *PROCINFO_node;
|
|
Packit Service |
f629e6 |
NODE *RLENGTH_node, *RSTART_node, *RS_node, *RT_node, *SUBSEP_node;
|
|
Packit Service |
f629e6 |
NODE *PREC_node, *ROUNDMODE_node;
|
|
Packit Service |
f629e6 |
NODE *TEXTDOMAIN_node;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
long NF;
|
|
Packit Service |
f629e6 |
long NR;
|
|
Packit Service |
f629e6 |
long FNR;
|
|
Packit Service |
f629e6 |
int BINMODE;
|
|
Packit Service |
f629e6 |
bool IGNORECASE;
|
|
Packit Service |
f629e6 |
char *OFS;
|
|
Packit Service |
f629e6 |
char *ORS;
|
|
Packit Service |
f629e6 |
char *OFMT;
|
|
Packit Service |
f629e6 |
char *TEXTDOMAIN;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* CONVFMT is a convenience pointer for the current number to string format.
|
|
Packit Service |
f629e6 |
* We must supply an initial value to avoid recursion problems of
|
|
Packit Service |
f629e6 |
* set_CONVFMT -> fmt_index -> force_string: gets NULL CONVFMT
|
|
Packit Service |
f629e6 |
* Fun, fun, fun, fun.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
char *CONVFMT = "%.6g";
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
NODE *Nnull_string; /* The global null string */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if defined(HAVE_LOCALE_H)
|
|
Packit Service |
f629e6 |
struct lconv loc; /* current locale */
|
|
Packit Service |
f629e6 |
static void init_locale(struct lconv *l);
|
|
Packit Service |
f629e6 |
#endif /* defined(HAVE_LOCALE_H) */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* The name the program was invoked under, for error messages */
|
|
Packit Service |
f629e6 |
const char *myname;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* A block of AWK code to be run */
|
|
Packit Service |
f629e6 |
INSTRUCTION *code_block = NULL;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
char **d_argv; /* saved argv for debugger restarting */
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* List of rules and functions with first and last instruction (source_line)
|
|
Packit Service |
f629e6 |
* information; used for profiling and debugging.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
INSTRUCTION *rule_list;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
int exit_val = EXIT_SUCCESS; /* exit value */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if defined(YYDEBUG) || defined(GAWKDEBUG)
|
|
Packit Service |
f629e6 |
extern int yydebug;
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
SRCFILE *srcfiles; /* source files */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* structure to remember variable pre-assignments
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
struct pre_assign {
|
|
Packit Service |
f629e6 |
enum assign_type { PRE_ASSIGN = 1, PRE_ASSIGN_FS } type;
|
|
Packit Service |
f629e6 |
char *val;
|
|
Packit Service |
f629e6 |
};
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static struct pre_assign *preassigns = NULL; /* requested via -v or -F */
|
|
Packit Service |
f629e6 |
static long numassigns = -1; /* how many of them */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static bool disallow_var_assigns = false; /* true for --exec */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void add_preassign(enum assign_type type, char *val);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void parse_args(int argc, char **argv);
|
|
Packit Service |
f629e6 |
static void set_locale_stuff(void);
|
|
Packit Service |
f629e6 |
static bool stopped_early = false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
int do_flags = false;
|
|
Packit Service |
f629e6 |
bool do_optimize = true; /* apply default optimizations */
|
|
Packit Service |
f629e6 |
static int do_nostalgia = false; /* provide a blast from the past */
|
|
Packit Service |
f629e6 |
static int do_binary = false; /* hands off my data! */
|
|
Packit Service |
f629e6 |
static int do_version = false; /* print version info */
|
|
Packit Service |
f629e6 |
static const char *locale = ""; /* default value to setlocale */
|
|
Packit Service |
f629e6 |
static char *locale_dir = LOCALEDIR; /* default locale dir */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
int use_lc_numeric = false; /* obey locale for decimal point */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
int gawk_mb_cur_max; /* MB_CUR_MAX value, see comment in main() */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
FILE *output_fp; /* default gawk output, can be redirected in the debugger */
|
|
Packit Service |
f629e6 |
bool output_is_tty = false; /* control flushing of output */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* default format for strftime(), available via PROCINFO */
|
|
Packit Service |
f629e6 |
const char def_strftime_format[] = "%a %b %e %H:%M:%S %Z %Y";
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
extern const char *version_string;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
|
|
Packit Service |
f629e6 |
GETGROUPS_T *groupset; /* current group set */
|
|
Packit Service |
f629e6 |
int ngroups; /* size of said set */
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
void (*lintfunc)(const char *mesg, ...) = r_warning;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Sorted by long option name! */
|
|
Packit Service |
f629e6 |
static const struct option optab[] = {
|
|
Packit Service |
f629e6 |
{ "assign", required_argument, NULL, 'v' },
|
|
Packit Service |
f629e6 |
{ "bignum", no_argument, NULL, 'M' },
|
|
Packit Service |
f629e6 |
{ "characters-as-bytes", no_argument, & do_binary, 'b' },
|
|
Packit Service |
f629e6 |
{ "copyright", no_argument, NULL, 'C' },
|
|
Packit Service |
f629e6 |
{ "debug", optional_argument, NULL, 'D' },
|
|
Packit Service |
f629e6 |
{ "dump-variables", optional_argument, NULL, 'd' },
|
|
Packit Service |
f629e6 |
{ "exec", required_argument, NULL, 'E' },
|
|
Packit Service |
f629e6 |
{ "field-separator", required_argument, NULL, 'F' },
|
|
Packit Service |
f629e6 |
{ "file", required_argument, NULL, 'f' },
|
|
Packit Service |
f629e6 |
{ "gen-pot", no_argument, NULL, 'g' },
|
|
Packit Service |
f629e6 |
{ "help", no_argument, NULL, 'h' },
|
|
Packit Service |
f629e6 |
{ "include", required_argument, NULL, 'i' },
|
|
Packit Service |
f629e6 |
{ "lint", optional_argument, NULL, 'L' },
|
|
Packit Service |
f629e6 |
{ "lint-old", no_argument, NULL, 't' },
|
|
Packit Service |
f629e6 |
{ "load", required_argument, NULL, 'l' },
|
|
Packit Service |
f629e6 |
#if defined(LOCALEDEBUG)
|
|
Packit Service |
f629e6 |
{ "locale", required_argument, NULL, 'Z' },
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
{ "non-decimal-data", no_argument, NULL, 'n' },
|
|
Packit Service |
f629e6 |
{ "no-optimize", no_argument, NULL, 's' },
|
|
Packit Service |
f629e6 |
{ "nostalgia", no_argument, & do_nostalgia, 1 },
|
|
Packit Service |
f629e6 |
{ "optimize", no_argument, NULL, 'O' },
|
|
Packit Service |
f629e6 |
#if defined(YYDEBUG) || defined(GAWKDEBUG)
|
|
Packit Service |
f629e6 |
{ "parsedebug", no_argument, NULL, 'Y' },
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
{ "posix", no_argument, NULL, 'P' },
|
|
Packit Service |
f629e6 |
{ "pretty-print", optional_argument, NULL, 'o' },
|
|
Packit Service |
f629e6 |
{ "profile", optional_argument, NULL, 'p' },
|
|
Packit Service |
f629e6 |
{ "re-interval", no_argument, NULL, 'r' },
|
|
Packit Service |
f629e6 |
{ "sandbox", no_argument, NULL, 'S' },
|
|
Packit Service |
f629e6 |
{ "source", required_argument, NULL, 'e' },
|
|
Packit Service |
f629e6 |
{ "traditional", no_argument, NULL, 'c' },
|
|
Packit Service |
f629e6 |
{ "use-lc-numeric", no_argument, & use_lc_numeric, 1 },
|
|
Packit Service |
f629e6 |
{ "version", no_argument, & do_version, 'V' },
|
|
Packit Service |
f629e6 |
{ NULL, 0, NULL, '\0' }
|
|
Packit Service |
f629e6 |
};
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* main --- process args, parse program, run it, clean up */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
int
|
|
Packit Service |
f629e6 |
main(int argc, char **argv)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
int i;
|
|
Packit Service |
f629e6 |
char *extra_stack;
|
|
Packit Service |
f629e6 |
int have_srcfile = 0;
|
|
Packit Service |
f629e6 |
SRCFILE *s;
|
|
Packit Service |
f629e6 |
char *cp;
|
|
Packit Service |
f629e6 |
#if defined(LOCALEDEBUG)
|
|
Packit Service |
f629e6 |
const char *initial_locale;
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* do these checks early */
|
|
Packit Service |
f629e6 |
if (getenv("TIDYMEM") != NULL)
|
|
Packit Service |
f629e6 |
do_flags |= DO_TIDY_MEM;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MCHECK_H
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MTRACE
|
|
Packit Service |
f629e6 |
if (do_tidy_mem)
|
|
Packit Service |
f629e6 |
mtrace();
|
|
Packit Service |
f629e6 |
#endif /* HAVE_MTRACE */
|
|
Packit Service |
f629e6 |
#endif /* HAVE_MCHECK_H */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
myname = gawk_name(argv[0]);
|
|
Packit Service |
f629e6 |
os_arg_fixup(&argc, &argv); /* emulate redirection, expand wildcards */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (argc < 2)
|
|
Packit Service |
f629e6 |
usage(EXIT_FAILURE, stderr);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if ((cp = getenv("GAWK_LOCALE_DIR")) != NULL)
|
|
Packit Service |
f629e6 |
locale_dir = cp;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if defined(F_GETFL) && defined(O_APPEND)
|
|
Packit Service |
f629e6 |
// 1/2018: This is needed on modern BSD systems so that the
|
|
Packit Service |
f629e6 |
// inplace tests pass. I think it's a bug in those kernels
|
|
Packit Service |
f629e6 |
// but let's just work around it anyway.
|
|
Packit Service |
f629e6 |
int flags = fcntl(fileno(stderr), F_GETFL, NULL);
|
|
Packit Service |
f629e6 |
if (flags >= 0 && (flags & O_APPEND) == 0) {
|
|
Packit Service |
f629e6 |
flags |= O_APPEND;
|
|
Packit Service |
f629e6 |
(void) fcntl(fileno(stderr), F_SETFL, flags);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if defined(LOCALEDEBUG)
|
|
Packit Service |
f629e6 |
initial_locale = locale;
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
set_locale_stuff();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
(void) signal(SIGFPE, catchsig);
|
|
Packit Service |
f629e6 |
#ifdef SIGBUS
|
|
Packit Service |
f629e6 |
(void) signal(SIGBUS, catchsig);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Ignore SIGPIPE so that writes to pipes that fail don't
|
|
Packit Service |
f629e6 |
* kill the process but instead return -1 and set errno.
|
|
Packit Service |
f629e6 |
* That lets us print a fatal message instead of dieing suddenly.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* Note that this requires ignoring EPIPE when writing and
|
|
Packit Service |
f629e6 |
* flushing stdout/stderr in other parts of the program. E.g.,
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* gawk 'BEGIN { print "hi" }' | exit
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* should not give us "broken pipe" messages --- mainly because
|
|
Packit Service |
f629e6 |
* it did not do so in the past and people would complain.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
ignore_sigpipe();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
(void) sigsegv_install_handler(catchsegv);
|
|
Packit Service |
f629e6 |
#define STACK_SIZE (16*1024)
|
|
Packit Service |
f629e6 |
emalloc(extra_stack, char *, STACK_SIZE, "main");
|
|
Packit Service |
f629e6 |
(void) stackoverflow_install_handler(catchstackoverflow, extra_stack, STACK_SIZE);
|
|
Packit Service |
f629e6 |
#undef STACK_SIZE
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* initialize the null string */
|
|
Packit Service |
f629e6 |
Nnull_string = make_string("", 0);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Robustness: check that file descriptors 0, 1, 2 are open */
|
|
Packit Service |
f629e6 |
init_fds();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* init array handling. */
|
|
Packit Service |
f629e6 |
array_init();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* init the symbol tables */
|
|
Packit Service |
f629e6 |
init_symbol_table();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
output_fp = stdout;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* initialize global (main) execution context */
|
|
Packit Service |
f629e6 |
push_context(new_context());
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
parse_args(argc, argv);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if defined(LOCALEDEBUG)
|
|
Packit Service |
f629e6 |
if (locale != initial_locale)
|
|
Packit Service |
f629e6 |
set_locale_stuff();
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* In glibc, MB_CUR_MAX is actually a function. This value is
|
|
Packit Service |
f629e6 |
* tested *a lot* in many speed-critical places in gawk. Caching
|
|
Packit Service |
f629e6 |
* this value once makes a speed difference.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
gawk_mb_cur_max = MB_CUR_MAX;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* init the cache for checking bytes if they're characters */
|
|
Packit Service |
f629e6 |
init_btowc_cache();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_nostalgia)
|
|
Packit Service |
f629e6 |
nostalgia();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* check for POSIXLY_CORRECT environment variable */
|
|
Packit Service |
f629e6 |
if (! do_posix && getenv("POSIXLY_CORRECT") != NULL) {
|
|
Packit Service |
f629e6 |
do_flags |= DO_POSIX;
|
|
Packit Service |
f629e6 |
if (do_lint)
|
|
Packit Service |
f629e6 |
lintwarn(
|
|
Packit Service |
f629e6 |
_("environment variable `POSIXLY_CORRECT' set: turning on `--posix'"));
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_posix) {
|
|
Packit Service |
f629e6 |
use_lc_numeric = true;
|
|
Packit Service |
f629e6 |
if (do_traditional) /* both on command line */
|
|
Packit Service |
f629e6 |
warning(_("`--posix' overrides `--traditional'"));
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
do_flags |= DO_TRADITIONAL;
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* POSIX compliance also implies
|
|
Packit Service |
f629e6 |
* no GNU extensions either.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_traditional && do_non_decimal_data) {
|
|
Packit Service |
f629e6 |
do_flags &= ~DO_NON_DEC_DATA;
|
|
Packit Service |
f629e6 |
warning(_("`--posix'/`--traditional' overrides `--non-decimal-data'"));
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_lint && os_is_setuid())
|
|
Packit Service |
f629e6 |
warning(_("running %s setuid root may be a security problem"), myname);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_binary) {
|
|
Packit Service |
f629e6 |
if (do_posix)
|
|
Packit Service |
f629e6 |
warning(_("`--posix' overrides `--characters-as-bytes'"));
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
gawk_mb_cur_max = 1; /* hands off my data! */
|
|
Packit Service |
f629e6 |
#if defined(LC_ALL)
|
|
Packit Service |
f629e6 |
setlocale(LC_ALL, "C");
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_debug) /* Need to register the debugger pre-exec hook before any other */
|
|
Packit Service |
f629e6 |
init_debug();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MPFR
|
|
Packit Service |
f629e6 |
/* Set up MPFR defaults, and register pre-exec hook to process arithmetic opcodes */
|
|
Packit Service |
f629e6 |
if (do_mpfr)
|
|
Packit Service |
f629e6 |
init_mpfr(DEFAULT_PREC, DEFAULT_ROUNDMODE);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* load group set */
|
|
Packit Service |
f629e6 |
init_groupset();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MPFR
|
|
Packit Service |
f629e6 |
if (do_mpfr) {
|
|
Packit Service |
f629e6 |
mpz_init(Nnull_string->mpg_i);
|
|
Packit Service |
f629e6 |
Nnull_string->flags = (MALLOC|STRCUR|STRING|MPZN|NUMCUR|NUMBER);
|
|
Packit Service |
f629e6 |
} else
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
Nnull_string->numbr = 0.0;
|
|
Packit Service |
f629e6 |
Nnull_string->flags = (MALLOC|STRCUR|STRING|NUMCUR|NUMBER);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Tell the regex routines how they should work.
|
|
Packit Service |
f629e6 |
* Do this before initializing variables, since
|
|
Packit Service |
f629e6 |
* they could want to do a regexp compile.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
resetup();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Set up the special variables */
|
|
Packit Service |
f629e6 |
init_vars();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Set up the field variables */
|
|
Packit Service |
f629e6 |
init_fields();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Now process the pre-assignments */
|
|
Packit Service |
f629e6 |
for (i = 0; i <= numassigns; i++) {
|
|
Packit Service |
f629e6 |
if (preassigns[i].type == PRE_ASSIGN)
|
|
Packit Service |
f629e6 |
(void) arg_assign(preassigns[i].val, true);
|
|
Packit Service |
f629e6 |
else /* PRE_ASSIGN_FS */
|
|
Packit Service |
f629e6 |
cmdline_fs(preassigns[i].val);
|
|
Packit Service |
f629e6 |
efree(preassigns[i].val);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (preassigns != NULL)
|
|
Packit Service |
f629e6 |
efree(preassigns);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if ((BINMODE & BINMODE_INPUT) != 0)
|
|
Packit Service |
f629e6 |
if (os_setbinmode(fileno(stdin), O_BINARY) == -1)
|
|
Packit Service |
f629e6 |
fatal(_("can't set binary mode on stdin (%s)"), strerror(errno));
|
|
Packit Service |
f629e6 |
if ((BINMODE & BINMODE_OUTPUT) != 0) {
|
|
Packit Service |
f629e6 |
if (os_setbinmode(fileno(stdout), O_BINARY) == -1)
|
|
Packit Service |
f629e6 |
fatal(_("can't set binary mode on stdout (%s)"), strerror(errno));
|
|
Packit Service |
f629e6 |
if (os_setbinmode(fileno(stderr), O_BINARY) == -1)
|
|
Packit Service |
f629e6 |
fatal(_("can't set binary mode on stderr (%s)"), strerror(errno));
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef GAWKDEBUG
|
|
Packit Service |
f629e6 |
setbuf(stdout, (char *) NULL); /* make debugging easier */
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
if (os_isatty(fileno(stdout)))
|
|
Packit Service |
f629e6 |
output_is_tty = true;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* initialize API before loading extension libraries */
|
|
Packit Service |
f629e6 |
init_ext_api();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* load extension libs */
|
|
Packit Service |
f629e6 |
for (s = srcfiles->next; s != srcfiles; s = s->next) {
|
|
Packit Service |
f629e6 |
if (s->stype == SRC_EXTLIB)
|
|
Packit Service |
f629e6 |
load_ext(s->fullpath);
|
|
Packit Service |
f629e6 |
else if (s->stype != SRC_INC)
|
|
Packit Service |
f629e6 |
have_srcfile++;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* do version check after extensions are loaded to get extension info */
|
|
Packit Service |
f629e6 |
if (do_version)
|
|
Packit Service |
f629e6 |
version();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* No -f or --source options, use next arg */
|
|
Packit Service |
f629e6 |
if (! have_srcfile) {
|
|
Packit Service |
f629e6 |
if (optind > argc - 1 || stopped_early) /* no args left or no program */
|
|
Packit Service |
f629e6 |
usage(EXIT_FAILURE, stderr);
|
|
Packit Service |
f629e6 |
(void) add_srcfile(SRC_CMDLINE, argv[optind], srcfiles, NULL, NULL);
|
|
Packit Service |
f629e6 |
optind++;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Select the interpreter routine */
|
|
Packit Service |
f629e6 |
init_interpret();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
init_args(optind, argc,
|
|
Packit Service |
f629e6 |
do_posix ? argv[0] : myname,
|
|
Packit Service |
f629e6 |
argv);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if defined(LC_NUMERIC)
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* FRAGILE! CAREFUL!
|
|
Packit Service |
f629e6 |
* Pre-initing the variables with arg_assign() can change the
|
|
Packit Service |
f629e6 |
* locale. Force it to C before parsing the program.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
setlocale(LC_NUMERIC, "C");
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
/* Read in the program */
|
|
Packit Service |
f629e6 |
if (parse_program(& code_block) != 0)
|
|
Packit Service |
f629e6 |
exit(EXIT_FAILURE);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_intl)
|
|
Packit Service |
f629e6 |
exit(EXIT_SUCCESS);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
install_builtins();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_lint)
|
|
Packit Service |
f629e6 |
shadow_funcs();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_lint && code_block->nexti->opcode == Op_atexit)
|
|
Packit Service |
f629e6 |
lintwarn(_("no program text at all!"));
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
load_symbols();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_profile)
|
|
Packit Service |
f629e6 |
init_profiling_signals();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if defined(LC_NUMERIC)
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* See comment above about using locale's decimal point.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* 10/2005:
|
|
Packit Service |
f629e6 |
* Bitter experience teaches us that most people the world over
|
|
Packit Service |
f629e6 |
* use period as the decimal point, not whatever their locale
|
|
Packit Service |
f629e6 |
* uses. Thus, only use the locale's decimal point if being
|
|
Packit Service |
f629e6 |
* posixly anal-retentive.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* 7/2007:
|
|
Packit Service |
f629e6 |
* Be a little bit kinder. Allow the --use-lc-numeric option
|
|
Packit Service |
f629e6 |
* to also use the local decimal point. This avoids the draconian
|
|
Packit Service |
f629e6 |
* strictness of POSIX mode if someone just wants to parse their
|
|
Packit Service |
f629e6 |
* data using the local decimal point.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
if (use_lc_numeric)
|
|
Packit Service |
f629e6 |
setlocale(LC_NUMERIC, locale);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
init_io();
|
|
Packit Service |
f629e6 |
output_fp = stdout;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_debug)
|
|
Packit Service |
f629e6 |
debug_prog(code_block);
|
|
Packit Service |
f629e6 |
else if (do_pretty_print && ! do_profile)
|
|
Packit Service |
f629e6 |
; /* run pretty printer only. */
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
interpret(code_block);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_pretty_print) {
|
|
Packit Service |
f629e6 |
dump_prog(code_block);
|
|
Packit Service |
f629e6 |
dump_funcs();
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_dump_vars)
|
|
Packit Service |
f629e6 |
dump_vars(varfile);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MPFR
|
|
Packit Service |
f629e6 |
if (do_mpfr)
|
|
Packit Service |
f629e6 |
cleanup_mpfr();
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_tidy_mem)
|
|
Packit Service |
f629e6 |
release_all_vars();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* keep valgrind happier */
|
|
Packit Service |
f629e6 |
if (extra_stack)
|
|
Packit Service |
f629e6 |
efree(extra_stack);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
final_exit(exit_val);
|
|
Packit Service |
f629e6 |
return exit_val; /* to suppress warnings */
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* add_preassign --- add one element to preassigns */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
add_preassign(enum assign_type type, char *val)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
static long alloc_assigns; /* for how many are allocated */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#define INIT_SRC 4
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
++numassigns;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (preassigns == NULL) {
|
|
Packit Service |
f629e6 |
emalloc(preassigns, struct pre_assign *,
|
|
Packit Service |
f629e6 |
INIT_SRC * sizeof(struct pre_assign), "add_preassign");
|
|
Packit Service |
f629e6 |
alloc_assigns = INIT_SRC;
|
|
Packit Service |
f629e6 |
} else if (numassigns >= alloc_assigns) {
|
|
Packit Service |
f629e6 |
alloc_assigns *= 2;
|
|
Packit Service |
f629e6 |
erealloc(preassigns, struct pre_assign *,
|
|
Packit Service |
f629e6 |
alloc_assigns * sizeof(struct pre_assign), "add_preassigns");
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
preassigns[numassigns].type = type;
|
|
Packit Service |
f629e6 |
preassigns[numassigns].val = estrdup(val, strlen(val));
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#undef INIT_SRC
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* usage --- print usage information and exit */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
usage(int exitval, FILE *fp)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
/* Not factoring out common stuff makes it easier to translate. */
|
|
Packit Service |
f629e6 |
fprintf(fp, _("Usage: %s [POSIX or GNU style options] -f progfile [--] file ...\n"),
|
|
Packit Service |
f629e6 |
myname);
|
|
Packit Service |
f629e6 |
fprintf(fp, _("Usage: %s [POSIX or GNU style options] [--] %cprogram%c file ...\n"),
|
|
Packit Service |
f629e6 |
myname, quote, quote);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* GNU long options info. This is too many options. */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
fputs(_("POSIX options:\t\tGNU long options: (standard)\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-f progfile\t\t--file=progfile\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-F fs\t\t\t--field-separator=fs\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-v var=val\t\t--assign=var=val\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("Short options:\t\tGNU long options: (extensions)\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-b\t\t\t--characters-as-bytes\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-c\t\t\t--traditional\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-C\t\t\t--copyright\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-d[file]\t\t--dump-variables[=file]\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-D[file]\t\t--debug[=file]\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-e 'program-text'\t--source='program-text'\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-E file\t\t\t--exec=file\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-g\t\t\t--gen-pot\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-h\t\t\t--help\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-i includefile\t\t--include=includefile\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-l library\t\t--load=library\n"), fp);
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* TRANSLATORS: the "fatal" and "invalid" here are literal
|
|
Packit Service |
f629e6 |
* values, they should not be translated. Thanks.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
fputs(_("\t-L[fatal|invalid]\t--lint[=fatal|invalid]\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-M\t\t\t--bignum\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-N\t\t\t--use-lc-numeric\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-n\t\t\t--non-decimal-data\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-o[file]\t\t--pretty-print[=file]\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-O\t\t\t--optimize\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-p[file]\t\t--profile[=file]\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-P\t\t\t--posix\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-r\t\t\t--re-interval\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-s\t\t\t--no-optimize\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-S\t\t\t--sandbox\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-t\t\t\t--lint-old\n"), fp);
|
|
Packit Service |
f629e6 |
fputs(_("\t-V\t\t\t--version\n"), fp);
|
|
Packit Service |
f629e6 |
#ifdef NOSTALGIA
|
|
Packit Service |
f629e6 |
fputs(_("\t-W nostalgia\t\t--nostalgia\n"), fp);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
#ifdef GAWKDEBUG
|
|
Packit Service |
f629e6 |
fputs(_("\t-Y\t\t--parsedebug\n"), fp);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* This is one string to make things easier on translators. */
|
|
Packit Service |
f629e6 |
/* TRANSLATORS: --help output 5 (end)
|
|
Packit Service |
f629e6 |
TRANSLATORS: the placeholder indicates the bug-reporting address
|
|
Packit Service |
f629e6 |
for this application. Please add _another line_ with the
|
|
Packit Service |
f629e6 |
address for translation bugs.
|
|
Packit Service |
f629e6 |
no-wrap */
|
|
Packit Service |
f629e6 |
fputs(_("\nTo report bugs, see node `Bugs' in `gawk.info'\n\
|
|
Packit Service |
f629e6 |
which is section `Reporting Problems and Bugs' in the\n\
|
|
Packit Service |
f629e6 |
printed version. This same information may be found at\n\
|
|
Packit Service |
f629e6 |
https://www.gnu.org/software/gawk/manual/html_node/Bugs.html.\n\
|
|
Packit Service |
f629e6 |
PLEASE do NOT try to report bugs by posting in comp.lang.awk.\n\n"), fp);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* ditto */
|
|
Packit Service |
f629e6 |
fputs(_("gawk is a pattern scanning and processing language.\n\
|
|
Packit Service |
f629e6 |
By default it reads standard input and writes standard output.\n\n"), fp);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* ditto */
|
|
Packit Service |
f629e6 |
fputs(_("Examples:\n\tgawk '{ sum += $1 }; END { print sum }' file\n\
|
|
Packit Service |
f629e6 |
\tgawk -F: '{ print $1 }' /etc/passwd\n"), fp);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
fflush(fp);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (ferror(fp)) {
|
|
Packit Service |
f629e6 |
#ifdef __MINGW32__
|
|
Packit Service |
f629e6 |
if (errno == 0 || errno == EINVAL)
|
|
Packit Service |
f629e6 |
w32_maybe_set_errno();
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
/* don't warn about stdout/stderr if EPIPE, but do error exit */
|
|
Packit Service |
f629e6 |
if (errno == EPIPE)
|
|
Packit Service |
f629e6 |
die_via_sigpipe();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (fp == stdout)
|
|
Packit Service |
f629e6 |
warning(_("error writing standard output (%s)"), strerror(errno));
|
|
Packit Service |
f629e6 |
else if (fp == stderr)
|
|
Packit Service |
f629e6 |
warning(_("error writing standard error (%s)"), strerror(errno));
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
// some other problem than SIGPIPE
|
|
Packit Service |
f629e6 |
exit(EXIT_FAILURE);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
exit(exitval);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* copyleft --- print out the short GNU copyright information */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
copyleft()
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
static const char blurb_part1[] =
|
|
Packit Service |
f629e6 |
N_("Copyright (C) 1989, 1991-%d Free Software Foundation.\n\
|
|
Packit Service |
f629e6 |
\n\
|
|
Packit Service |
f629e6 |
This program is free software; you can redistribute it and/or modify\n\
|
|
Packit Service |
f629e6 |
it under the terms of the GNU General Public License as published by\n\
|
|
Packit Service |
f629e6 |
the Free Software Foundation; either version 3 of the License, or\n\
|
|
Packit Service |
f629e6 |
(at your option) any later version.\n\
|
|
Packit Service |
f629e6 |
\n");
|
|
Packit Service |
f629e6 |
static const char blurb_part2[] =
|
|
Packit Service |
f629e6 |
N_("This program is distributed in the hope that it will be useful,\n\
|
|
Packit Service |
f629e6 |
but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
|
|
Packit Service |
f629e6 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
|
|
Packit Service |
f629e6 |
GNU General Public License for more details.\n\
|
|
Packit Service |
f629e6 |
\n");
|
|
Packit Service |
f629e6 |
static const char blurb_part3[] =
|
|
Packit Service |
f629e6 |
N_("You should have received a copy of the GNU General Public License\n\
|
|
Packit Service |
f629e6 |
along with this program. If not, see http://www.gnu.org/licenses/.\n");
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* multiple blurbs are needed for some brain dead compilers. */
|
|
Packit Service |
f629e6 |
printf(_(blurb_part1), UPDATE_YEAR); /* Last update year */
|
|
Packit Service |
f629e6 |
fputs(_(blurb_part2), stdout);
|
|
Packit Service |
f629e6 |
fputs(_(blurb_part3), stdout);
|
|
Packit Service |
f629e6 |
fflush(stdout);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (ferror(stdout)) {
|
|
Packit Service |
f629e6 |
#ifdef __MINGW32__
|
|
Packit Service |
f629e6 |
if (errno == 0 || errno == EINVAL)
|
|
Packit Service |
f629e6 |
w32_maybe_set_errno();
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
/* don't warn about stdout if EPIPE, but do error exit */
|
|
Packit Service |
f629e6 |
if (errno != EPIPE)
|
|
Packit Service |
f629e6 |
warning(_("error writing standard output (%s)"), strerror(errno));
|
|
Packit Service |
f629e6 |
exit(EXIT_FAILURE);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
exit(EXIT_SUCCESS);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* cmdline_fs --- set FS from the command line */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
cmdline_fs(char *str)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE **tmp;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
tmp = &FS_node->var_value;
|
|
Packit Service |
f629e6 |
unref(*tmp);
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Only if in full compatibility mode check for the stupid special
|
|
Packit Service |
f629e6 |
* case so -F\t works as documented in awk book even though the shell
|
|
Packit Service |
f629e6 |
* hands us -Ft. Bleah!
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* Thankfully, POSIX didn't propagate this "feature".
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
if (str[0] == 't' && str[1] == '\0') {
|
|
Packit Service |
f629e6 |
if (do_lint)
|
|
Packit Service |
f629e6 |
lintwarn(_("-Ft does not set FS to tab in POSIX awk"));
|
|
Packit Service |
f629e6 |
if (do_traditional && ! do_posix)
|
|
Packit Service |
f629e6 |
str[0] = '\t';
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
*tmp = make_str_node(str, strlen(str), SCAN); /* do process escapes */
|
|
Packit Service |
f629e6 |
set_FS();
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* init_args --- set up ARGV from stuff on the command line */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
init_args(int argc0, int argc, const char *argv0, char **argv)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
int i, j;
|
|
Packit Service |
f629e6 |
NODE **aptr;
|
|
Packit Service |
f629e6 |
NODE *tmp;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
ARGV_node = install_symbol(estrdup("ARGV", 4), Node_var_array);
|
|
Packit Service |
f629e6 |
tmp = make_number(0.0);
|
|
Packit Service |
f629e6 |
aptr = assoc_lookup(ARGV_node, tmp);
|
|
Packit Service |
f629e6 |
unref(tmp);
|
|
Packit Service |
f629e6 |
unref(*aptr);
|
|
Packit Service |
f629e6 |
*aptr = make_string(argv0, strlen(argv0));
|
|
Packit Service |
f629e6 |
(*aptr)->flags |= USER_INPUT;
|
|
Packit Service |
f629e6 |
for (i = argc0, j = 1; i < argc; i++, j++) {
|
|
Packit Service |
f629e6 |
tmp = make_number((AWKNUM) j);
|
|
Packit Service |
f629e6 |
aptr = assoc_lookup(ARGV_node, tmp);
|
|
Packit Service |
f629e6 |
unref(tmp);
|
|
Packit Service |
f629e6 |
unref(*aptr);
|
|
Packit Service |
f629e6 |
*aptr = make_string(argv[i], strlen(argv[i]));
|
|
Packit Service |
f629e6 |
(*aptr)->flags |= USER_INPUT;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
ARGC_node = install_symbol(estrdup("ARGC", 4), Node_var);
|
|
Packit Service |
f629e6 |
ARGC_node->var_value = make_number((AWKNUM) j);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Set all the special variables to their initial values.
|
|
Packit Service |
f629e6 |
* Note that some of the variables that have set_FOO routines should
|
|
Packit Service |
f629e6 |
* *N*O*T* have those routines called upon initialization, and thus
|
|
Packit Service |
f629e6 |
* they have NULL entries in that field. This is notably true of FS
|
|
Packit Service |
f629e6 |
* and IGNORECASE.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
struct varinit {
|
|
Packit Service |
f629e6 |
NODE **spec;
|
|
Packit Service |
f629e6 |
const char *name;
|
|
Packit Service |
f629e6 |
const char *strval;
|
|
Packit Service |
f629e6 |
AWKNUM numval;
|
|
Packit Service |
f629e6 |
Func_ptr update;
|
|
Packit Service |
f629e6 |
Func_ptr assign;
|
|
Packit Service |
f629e6 |
bool do_assign;
|
|
Packit Service |
f629e6 |
int flags;
|
|
Packit Service |
f629e6 |
#define NO_INSTALL 0x01
|
|
Packit Service |
f629e6 |
#define NON_STANDARD 0x02
|
|
Packit Service |
f629e6 |
#define NOT_OFF_LIMITS 0x04 /* may be accessed by extension function */
|
|
Packit Service |
f629e6 |
};
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static const struct varinit varinit[] = {
|
|
Packit Service |
f629e6 |
{NULL, "ARGC", NULL, 0, NULL, NULL, false, NO_INSTALL },
|
|
Packit Service |
f629e6 |
{&ARGIND_node, "ARGIND", NULL, 0, NULL, NULL, false, NON_STANDARD },
|
|
Packit Service |
f629e6 |
{NULL, "ARGV", NULL, 0, NULL, NULL, false, NO_INSTALL },
|
|
Packit Service |
f629e6 |
{&BINMODE_node, "BINMODE", NULL, 0, NULL, set_BINMODE, false, NON_STANDARD },
|
|
Packit Service |
f629e6 |
{&CONVFMT_node, "CONVFMT", "%.6g", 0, NULL, set_CONVFMT,true, 0 },
|
|
Packit Service |
f629e6 |
{NULL, "ENVIRON", NULL, 0, NULL, NULL, false, NO_INSTALL },
|
|
Packit Service |
f629e6 |
{&ERRNO_node, "ERRNO", "", 0, NULL, NULL, false, NON_STANDARD },
|
|
Packit Service |
f629e6 |
{&FIELDWIDTHS_node, "FIELDWIDTHS", "", 0, NULL, set_FIELDWIDTHS, false, NON_STANDARD },
|
|
Packit Service |
f629e6 |
{&FILENAME_node, "FILENAME", "", 0, NULL, NULL, false, 0 },
|
|
Packit Service |
f629e6 |
{&FNR_node, "FNR", NULL, 0, update_FNR, set_FNR, true, 0 },
|
|
Packit Service |
f629e6 |
{&FS_node, "FS", " ", 0, NULL, set_FS, false, 0 },
|
|
Packit Service |
f629e6 |
{&FPAT_node, "FPAT", "[^[:space:]]+", 0, NULL, set_FPAT, false, NON_STANDARD },
|
|
Packit Service |
f629e6 |
{&IGNORECASE_node, "IGNORECASE", NULL, 0, NULL, set_IGNORECASE, false, NON_STANDARD },
|
|
Packit Service |
f629e6 |
{&LINT_node, "LINT", NULL, 0, NULL, set_LINT, false, NON_STANDARD },
|
|
Packit Service |
f629e6 |
{&PREC_node, "PREC", NULL, DEFAULT_PREC, NULL, set_PREC, false, NON_STANDARD},
|
|
Packit Service |
f629e6 |
{&NF_node, "NF", NULL, -1, update_NF, set_NF, false, 0 },
|
|
Packit Service |
f629e6 |
{&NR_node, "NR", NULL, 0, update_NR, set_NR, true, 0 },
|
|
Packit Service |
f629e6 |
{&OFMT_node, "OFMT", "%.6g", 0, NULL, set_OFMT, true, 0 },
|
|
Packit Service |
f629e6 |
{&OFS_node, "OFS", " ", 0, NULL, set_OFS, true, 0 },
|
|
Packit Service |
f629e6 |
{&ORS_node, "ORS", "\n", 0, NULL, set_ORS, true, 0 },
|
|
Packit Service |
f629e6 |
{NULL, "PROCINFO", NULL, 0, NULL, NULL, false, NO_INSTALL | NON_STANDARD | NOT_OFF_LIMITS },
|
|
Packit Service |
f629e6 |
{&RLENGTH_node, "RLENGTH", NULL, 0, NULL, NULL, false, 0 },
|
|
Packit Service |
f629e6 |
{&ROUNDMODE_node, "ROUNDMODE", DEFAULT_ROUNDMODE, 0, NULL, set_ROUNDMODE, false, NON_STANDARD },
|
|
Packit Service |
f629e6 |
{&RS_node, "RS", "\n", 0, NULL, set_RS, true, 0 },
|
|
Packit Service |
f629e6 |
{&RSTART_node, "RSTART", NULL, 0, NULL, NULL, false, 0 },
|
|
Packit Service |
f629e6 |
{&RT_node, "RT", "", 0, NULL, NULL, false, NON_STANDARD },
|
|
Packit Service |
f629e6 |
{&SUBSEP_node, "SUBSEP", "\034", 0, NULL, set_SUBSEP, true, 0 },
|
|
Packit Service |
f629e6 |
{&TEXTDOMAIN_node, "TEXTDOMAIN", "messages", 0, NULL, set_TEXTDOMAIN, true, NON_STANDARD },
|
|
Packit Service |
f629e6 |
{0, NULL, NULL, 0, NULL, NULL, false, 0 },
|
|
Packit Service |
f629e6 |
};
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* init_vars --- actually initialize everything in the symbol table */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
init_vars()
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
const struct varinit *vp;
|
|
Packit Service |
f629e6 |
NODE *n;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
for (vp = varinit; vp->name != NULL; vp++) {
|
|
Packit Service |
f629e6 |
if ((vp->flags & NO_INSTALL) != 0)
|
|
Packit Service |
f629e6 |
continue;
|
|
Packit Service |
f629e6 |
n = *(vp->spec) = install_symbol(estrdup(vp->name, strlen(vp->name)), Node_var);
|
|
Packit Service |
f629e6 |
if (vp->strval != NULL)
|
|
Packit Service |
f629e6 |
n->var_value = make_string(vp->strval, strlen(vp->strval));
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
n->var_value = make_number(vp->numval);
|
|
Packit Service |
f629e6 |
n->var_assign = (Func_ptr) vp->assign;
|
|
Packit Service |
f629e6 |
n->var_update = (Func_ptr) vp->update;
|
|
Packit Service |
f629e6 |
if (vp->do_assign)
|
|
Packit Service |
f629e6 |
(*(vp->assign))();
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* Load PROCINFO and ENVIRON */
|
|
Packit Service |
f629e6 |
if (! do_traditional)
|
|
Packit Service |
f629e6 |
load_procinfo();
|
|
Packit Service |
f629e6 |
load_environ();
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* path_environ --- put path variable into environment if not already there */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
path_environ(const char *pname, const char *dflt)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
const char *val;
|
|
Packit Service |
f629e6 |
NODE **aptr;
|
|
Packit Service |
f629e6 |
NODE *tmp;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
tmp = make_string(pname, strlen(pname));
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* On VMS, environ[] only holds a subset of what getenv() can
|
|
Packit Service |
f629e6 |
* find, so look AWKPATH up before resorting to default path.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
val = getenv(pname);
|
|
Packit Service |
f629e6 |
if (val == NULL || *val == '\0')
|
|
Packit Service |
f629e6 |
val = dflt;
|
|
Packit Service |
f629e6 |
aptr = assoc_lookup(ENVIRON_node, tmp);
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* If original value was the empty string, set it to
|
|
Packit Service |
f629e6 |
* the default value.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
if ((*aptr)->stlen == 0) {
|
|
Packit Service |
f629e6 |
unref(*aptr);
|
|
Packit Service |
f629e6 |
*aptr = make_string(val, strlen(val));
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
unref(tmp);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* load_environ --- populate the ENVIRON array */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static NODE *
|
|
Packit Service |
f629e6 |
load_environ()
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
#if ! (defined(VMS) && defined(__DECC))
|
|
Packit Service |
f629e6 |
extern char **environ;
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
char *var, *val;
|
|
Packit Service |
f629e6 |
NODE **aptr;
|
|
Packit Service |
f629e6 |
int i;
|
|
Packit Service |
f629e6 |
NODE *tmp;
|
|
Packit Service |
f629e6 |
static bool been_here = false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (been_here)
|
|
Packit Service |
f629e6 |
return ENVIRON_node;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
been_here = true;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
ENVIRON_node = install_symbol(estrdup("ENVIRON", 7), Node_var_array);
|
|
Packit Service |
f629e6 |
for (i = 0; environ[i] != NULL; i++) {
|
|
Packit Service |
f629e6 |
static char nullstr[] = "";
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
var = environ[i];
|
|
Packit Service |
f629e6 |
val = strchr(var, '=');
|
|
Packit Service |
f629e6 |
if (val != NULL)
|
|
Packit Service |
f629e6 |
*val++ = '\0';
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
val = nullstr;
|
|
Packit Service |
f629e6 |
tmp = make_string(var, strlen(var));
|
|
Packit Service |
f629e6 |
aptr = assoc_lookup(ENVIRON_node, tmp);
|
|
Packit Service |
f629e6 |
unref(tmp);
|
|
Packit Service |
f629e6 |
unref(*aptr);
|
|
Packit Service |
f629e6 |
*aptr = make_string(val, strlen(val));
|
|
Packit Service |
f629e6 |
(*aptr)->flags |= USER_INPUT;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* restore '=' so that system() gets a valid environment */
|
|
Packit Service |
f629e6 |
if (val != nullstr)
|
|
Packit Service |
f629e6 |
*--val = '=';
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Put AWKPATH and AWKLIBPATH into ENVIRON if not already there.
|
|
Packit Service |
f629e6 |
* This allows querying it from within awk programs.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* October 2014:
|
|
Packit Service |
f629e6 |
* If their values are "", override with the default values;
|
|
Packit Service |
f629e6 |
* since 2.10 AWKPATH used default value if environment's
|
|
Packit Service |
f629e6 |
* value was "".
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
path_environ("AWKPATH", defpath);
|
|
Packit Service |
f629e6 |
path_environ("AWKLIBPATH", deflibpath);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* set up array functions */
|
|
Packit Service |
f629e6 |
init_env_array(ENVIRON_node);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return ENVIRON_node;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
load_procinfo_argv()
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
NODE *tmp;
|
|
Packit Service |
f629e6 |
NODE **aptr;
|
|
Packit Service |
f629e6 |
NODE *argv_array;
|
|
Packit Service |
f629e6 |
int i;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
tmp = make_string("argv", 4);
|
|
Packit Service |
f629e6 |
aptr = assoc_lookup(PROCINFO_node, tmp);
|
|
Packit Service |
f629e6 |
unref(tmp);
|
|
Packit Service |
f629e6 |
unref(*aptr);
|
|
Packit Service |
f629e6 |
getnode(argv_array);
|
|
Packit Service |
f629e6 |
memset(argv_array, '\0', sizeof(NODE)); /* valgrind wants this */
|
|
Packit Service |
f629e6 |
null_array(argv_array);
|
|
Packit Service |
f629e6 |
*aptr = argv_array;
|
|
Packit Service |
f629e6 |
argv_array->parent_array = PROCINFO_node;
|
|
Packit Service |
f629e6 |
argv_array->vname = estrdup("argv", 4);
|
|
Packit Service |
f629e6 |
for (i = 0; d_argv[i] != NULL; i++) {
|
|
Packit Service |
f629e6 |
tmp = make_number(i);
|
|
Packit Service |
f629e6 |
aptr = assoc_lookup(argv_array, tmp);
|
|
Packit Service |
f629e6 |
unref(tmp);
|
|
Packit Service |
f629e6 |
unref(*aptr);
|
|
Packit Service |
f629e6 |
*aptr = make_string(d_argv[i], strlen(d_argv[i]));
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* load_procinfo --- populate the PROCINFO array */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static NODE *
|
|
Packit Service |
f629e6 |
load_procinfo()
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
#if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
|
|
Packit Service |
f629e6 |
int i;
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
#if (defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0) || defined(HAVE_MPFR)
|
|
Packit Service |
f629e6 |
char name[100];
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
AWKNUM value;
|
|
Packit Service |
f629e6 |
static bool been_here = false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (been_here)
|
|
Packit Service |
f629e6 |
return PROCINFO_node;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
been_here = true;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
PROCINFO_node = install_symbol(estrdup("PROCINFO", 8), Node_var_array);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
update_PROCINFO_str("version", VERSION);
|
|
Packit Service |
f629e6 |
update_PROCINFO_str("strftime", def_strftime_format);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MPFR
|
|
Packit Service |
f629e6 |
sprintf(name, "GNU MPFR %s", mpfr_get_version());
|
|
Packit Service |
f629e6 |
update_PROCINFO_str("mpfr_version", name);
|
|
Packit Service |
f629e6 |
sprintf(name, "GNU MP %s", gmp_version);
|
|
Packit Service |
f629e6 |
update_PROCINFO_str("gmp_version", name);
|
|
Packit Service |
f629e6 |
update_PROCINFO_num("prec_max", MPFR_PREC_MAX);
|
|
Packit Service |
f629e6 |
update_PROCINFO_num("prec_min", MPFR_PREC_MIN);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef DYNAMIC
|
|
Packit Service |
f629e6 |
update_PROCINFO_num("api_major", GAWK_API_MAJOR_VERSION);
|
|
Packit Service |
f629e6 |
update_PROCINFO_num("api_minor", GAWK_API_MINOR_VERSION);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef GETPGRP_VOID
|
|
Packit Service |
f629e6 |
#define getpgrp_arg() /* nothing */
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
#define getpgrp_arg() getpid()
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
value = getpgrp(getpgrp_arg());
|
|
Packit Service |
f629e6 |
update_PROCINFO_num("pgrpid", value);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Could put a lot of this into a table, but then there's
|
|
Packit Service |
f629e6 |
* portability problems declaring all the functions. So just
|
|
Packit Service |
f629e6 |
* do it the slow and stupid way. Sigh.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
value = getpid();
|
|
Packit Service |
f629e6 |
update_PROCINFO_num("pid", value);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
value = getppid();
|
|
Packit Service |
f629e6 |
update_PROCINFO_num("ppid", value);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
value = getuid();
|
|
Packit Service |
f629e6 |
update_PROCINFO_num("uid", value);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
value = geteuid();
|
|
Packit Service |
f629e6 |
update_PROCINFO_num("euid", value);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
value = getgid();
|
|
Packit Service |
f629e6 |
update_PROCINFO_num("gid", value);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
value = getegid();
|
|
Packit Service |
f629e6 |
update_PROCINFO_num("egid", value);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
update_PROCINFO_str("FS", current_field_sep_str());
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
|
|
Packit Service |
f629e6 |
for (i = 0; i < ngroups; i++) {
|
|
Packit Service |
f629e6 |
sprintf(name, "group%d", i + 1);
|
|
Packit Service |
f629e6 |
value = groupset[i];
|
|
Packit Service |
f629e6 |
update_PROCINFO_num(name, value);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
if (groupset) {
|
|
Packit Service |
f629e6 |
efree(groupset);
|
|
Packit Service |
f629e6 |
groupset = NULL;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
load_procinfo_argv();
|
|
Packit Service |
f629e6 |
return PROCINFO_node;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* is_std_var --- return true if a variable is a standard variable */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
int
|
|
Packit Service |
f629e6 |
is_std_var(const char *var)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
const struct varinit *vp;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
for (vp = varinit; vp->name != NULL; vp++) {
|
|
Packit Service |
f629e6 |
if (strcmp(vp->name, var) == 0) {
|
|
Packit Service |
f629e6 |
if ((do_traditional || do_posix) && (vp->flags & NON_STANDARD) != 0)
|
|
Packit Service |
f629e6 |
return false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return true;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return false;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* is_off_limits_var --- return true if a variable is off limits
|
|
Packit Service |
f629e6 |
* to extension functions
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
int
|
|
Packit Service |
f629e6 |
is_off_limits_var(const char *var)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
const struct varinit *vp;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
for (vp = varinit; vp->name != NULL; vp++) {
|
|
Packit Service |
f629e6 |
if (strcmp(vp->name, var) == 0)
|
|
Packit Service |
f629e6 |
return ((vp->flags & NOT_OFF_LIMITS) == 0);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return false;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* get_spec_varname --- return the name of a special variable
|
|
Packit Service |
f629e6 |
with the given assign or update routine.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
const char *
|
|
Packit Service |
f629e6 |
get_spec_varname(Func_ptr fptr)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
const struct varinit *vp;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (! fptr)
|
|
Packit Service |
f629e6 |
return NULL;
|
|
Packit Service |
f629e6 |
for (vp = varinit; vp->name != NULL; vp++) {
|
|
Packit Service |
f629e6 |
if (vp->assign == fptr || vp->update == fptr)
|
|
Packit Service |
f629e6 |
return vp->name;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
return NULL;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* arg_assign --- process a command-line assignment */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
int
|
|
Packit Service |
f629e6 |
arg_assign(char *arg, bool initing)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
char *cp, *cp2;
|
|
Packit Service |
f629e6 |
bool badvar;
|
|
Packit Service |
f629e6 |
NODE *var;
|
|
Packit Service |
f629e6 |
NODE *it;
|
|
Packit Service |
f629e6 |
NODE **lhs;
|
|
Packit Service |
f629e6 |
long save_FNR;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (! initing && disallow_var_assigns)
|
|
Packit Service |
f629e6 |
return false; /* --exec */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
cp = strchr(arg, '=');
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (cp == NULL) {
|
|
Packit Service |
f629e6 |
if (! initing)
|
|
Packit Service |
f629e6 |
return false; /* This is file name, not assignment. */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
fprintf(stderr,
|
|
Packit Service |
f629e6 |
_("%s: `%s' argument to `-v' not in `var=value' form\n\n"),
|
|
Packit Service |
f629e6 |
myname, arg);
|
|
Packit Service |
f629e6 |
usage(EXIT_FAILURE, stderr);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
*cp++ = '\0';
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* avoid false source indications in a fatal message */
|
|
Packit Service |
f629e6 |
source = NULL;
|
|
Packit Service |
f629e6 |
sourceline = 0;
|
|
Packit Service |
f629e6 |
save_FNR = FNR;
|
|
Packit Service |
f629e6 |
FNR = 0;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* first check that the variable name has valid syntax */
|
|
Packit Service |
f629e6 |
badvar = false;
|
|
Packit Service |
f629e6 |
if (! is_letter((unsigned char) arg[0]))
|
|
Packit Service |
f629e6 |
badvar = true;
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
for (cp2 = arg+1; *cp2; cp2++)
|
|
Packit Service |
f629e6 |
if (! is_identchar((unsigned char) *cp2)) {
|
|
Packit Service |
f629e6 |
badvar = true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (badvar) {
|
|
Packit Service |
f629e6 |
if (initing)
|
|
Packit Service |
f629e6 |
fatal(_("`%s' is not a legal variable name"), arg);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (do_lint)
|
|
Packit Service |
f629e6 |
lintwarn(_("`%s' is not a variable name, looking for file `%s=%s'"),
|
|
Packit Service |
f629e6 |
arg, arg, cp);
|
|
Packit Service |
f629e6 |
} else {
|
|
Packit Service |
f629e6 |
if (check_special(arg) >= 0)
|
|
Packit Service |
f629e6 |
fatal(_("cannot use gawk builtin `%s' as variable name"), arg);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (! initing) {
|
|
Packit Service |
f629e6 |
var = lookup(arg);
|
|
Packit Service |
f629e6 |
if (var != NULL && var->type == Node_func)
|
|
Packit Service |
f629e6 |
fatal(_("cannot use function `%s' as variable name"), arg);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* BWK awk expands escapes inside assignments.
|
|
Packit Service |
f629e6 |
* This makes sense, so we do it too.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
it = make_str_node(cp, strlen(cp), SCAN);
|
|
Packit Service |
f629e6 |
it->flags |= USER_INPUT;
|
|
Packit Service |
f629e6 |
#ifdef LC_NUMERIC
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* See comment above about locale decimal point.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
if (do_posix)
|
|
Packit Service |
f629e6 |
setlocale(LC_NUMERIC, "C");
|
|
Packit Service |
f629e6 |
#endif /* LC_NUMERIC */
|
|
Packit Service |
f629e6 |
(void) force_number(it);
|
|
Packit Service |
f629e6 |
#ifdef LC_NUMERIC
|
|
Packit Service |
f629e6 |
if (do_posix)
|
|
Packit Service |
f629e6 |
setlocale(LC_NUMERIC, locale);
|
|
Packit Service |
f629e6 |
#endif /* LC_NUMERIC */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* since we are restoring the original text of ARGV later,
|
|
Packit Service |
f629e6 |
* need to copy the variable name part if we don't want
|
|
Packit Service |
f629e6 |
* name like v=abc instead of just v in var->vname
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
cp2 = estrdup(arg, cp - arg); /* var name */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
var = variable(0, cp2, Node_var);
|
|
Packit Service |
f629e6 |
if (var == NULL) /* error */
|
|
Packit Service |
f629e6 |
final_exit(EXIT_FATAL);
|
|
Packit Service |
f629e6 |
if (var->type == Node_var && var->var_update)
|
|
Packit Service |
f629e6 |
var->var_update();
|
|
Packit Service |
f629e6 |
lhs = get_lhs(var, false);
|
|
Packit Service |
f629e6 |
unref(*lhs);
|
|
Packit Service |
f629e6 |
*lhs = it;
|
|
Packit Service |
f629e6 |
/* check for set_FOO() routine */
|
|
Packit Service |
f629e6 |
if (var->type == Node_var && var->var_assign)
|
|
Packit Service |
f629e6 |
var->var_assign();
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
if (! initing)
|
|
Packit Service |
f629e6 |
*--cp = '='; /* restore original text of ARGV */
|
|
Packit Service |
f629e6 |
FNR = save_FNR;
|
|
Packit Service |
f629e6 |
return ! badvar;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* catchsig --- catch signals */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
catchsig(int sig)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
if (sig == SIGFPE) {
|
|
Packit Service |
f629e6 |
fatal(_("floating point exception"));
|
|
Packit Service |
f629e6 |
} else if (sig == SIGSEGV
|
|
Packit Service |
f629e6 |
#ifdef SIGBUS
|
|
Packit Service |
f629e6 |
|| sig == SIGBUS
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
) {
|
|
Packit Service |
f629e6 |
set_loc(__FILE__, __LINE__);
|
|
Packit Service |
f629e6 |
msg(_("fatal error: internal error"));
|
|
Packit Service |
f629e6 |
/* fatal won't abort() if not compiled for debugging */
|
|
Packit Service |
f629e6 |
// GLIBC 2.27 doesn't necessarily flush on abort. Sigh.
|
|
Packit Service |
f629e6 |
fflush(NULL);
|
|
Packit Service |
f629e6 |
abort();
|
|
Packit Service |
f629e6 |
} else
|
|
Packit Service |
f629e6 |
cant_happen();
|
|
Packit Service |
f629e6 |
/* NOTREACHED */
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifdef HAVE_LIBSIGSEGV
|
|
Packit Service |
f629e6 |
/* catchsegv --- for use with libsigsegv */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static int
|
|
Packit Service |
f629e6 |
catchsegv(void *fault_address, int serious)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
set_loc(__FILE__, __LINE__);
|
|
Packit Service |
f629e6 |
msg(_("fatal error: internal error: segfault"));
|
|
Packit Service |
f629e6 |
fflush(NULL);
|
|
Packit Service |
f629e6 |
abort();
|
|
Packit Service |
f629e6 |
/*NOTREACHED*/
|
|
Packit Service |
f629e6 |
return 0;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* catchstackoverflow --- for use with libsigsegv */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
catchstackoverflow(int emergency, stackoverflow_context_t scp)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
set_loc(__FILE__, __LINE__);
|
|
Packit Service |
f629e6 |
msg(_("fatal error: internal error: stack overflow"));
|
|
Packit Service |
f629e6 |
fflush(NULL);
|
|
Packit Service |
f629e6 |
abort();
|
|
Packit Service |
f629e6 |
/*NOTREACHED*/
|
|
Packit Service |
f629e6 |
return;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
#endif /* HAVE_LIBSIGSEGV */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* nostalgia --- print the famous error message and die */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
nostalgia()
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* N.B.: This string is not gettextized, on purpose.
|
|
Packit Service |
f629e6 |
* So there.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
fprintf(stderr, "awk: bailing out near line 1\n");
|
|
Packit Service |
f629e6 |
fflush(stderr);
|
|
Packit Service |
f629e6 |
abort();
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* version --- print version message */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
version()
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
printf("%s", version_string);
|
|
Packit Service |
f629e6 |
#ifdef DYNAMIC
|
|
Packit Service |
f629e6 |
printf(", API: %d.%d", GAWK_API_MAJOR_VERSION, GAWK_API_MINOR_VERSION);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MPFR
|
|
Packit Service |
f629e6 |
printf(" (GNU MPFR %s, GNU MP %s)", mpfr_get_version(), gmp_version);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
printf("\n");
|
|
Packit Service |
f629e6 |
print_ext_versions();
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Per GNU coding standards, print copyright info,
|
|
Packit Service |
f629e6 |
* then exit successfully, do nothing else.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
copyleft();
|
|
Packit Service |
f629e6 |
exit(EXIT_SUCCESS);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* init_fds --- check for 0, 1, 2, open on /dev/null if possible */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
init_fds()
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
struct stat sbuf;
|
|
Packit Service |
f629e6 |
int fd;
|
|
Packit Service |
f629e6 |
int newfd;
|
|
Packit Service |
f629e6 |
char const *const opposite_mode[] = {"w", "r", "r"};
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* maybe no stderr, don't bother with error mesg */
|
|
Packit Service |
f629e6 |
for (fd = 0; fd <= 2; fd++) {
|
|
Packit Service |
f629e6 |
if (fstat(fd, &sbuf) < 0) {
|
|
Packit Service |
f629e6 |
#if MAKE_A_HEROIC_EFFORT
|
|
Packit Service |
f629e6 |
if (do_lint)
|
|
Packit Service |
f629e6 |
lintwarn(_("no pre-opened fd %d"), fd);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
newfd = devopen("/dev/null", opposite_mode[fd]);
|
|
Packit Service |
f629e6 |
/* turn off some compiler warnings "set but not used" */
|
|
Packit Service |
f629e6 |
newfd += 0;
|
|
Packit Service |
f629e6 |
#ifdef MAKE_A_HEROIC_EFFORT
|
|
Packit Service |
f629e6 |
if (do_lint && newfd < 0)
|
|
Packit Service |
f629e6 |
lintwarn(_("could not pre-open /dev/null for fd %d"), fd);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* init_groupset --- initialize groupset */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
init_groupset()
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
#if defined(HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
|
|
Packit Service |
f629e6 |
#ifdef GETGROUPS_NOT_STANDARD
|
|
Packit Service |
f629e6 |
/* For systems that aren't standards conformant, use old way. */
|
|
Packit Service |
f629e6 |
ngroups = NGROUPS_MAX;
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* If called with 0 for both args, return value is
|
|
Packit Service |
f629e6 |
* total number of groups.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
ngroups = getgroups(0, NULL);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
/* If an error or no groups, just give up and get on with life. */
|
|
Packit Service |
f629e6 |
if (ngroups <= 0)
|
|
Packit Service |
f629e6 |
return;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* fill in groups */
|
|
Packit Service |
f629e6 |
emalloc(groupset, GETGROUPS_T *, ngroups * sizeof(GETGROUPS_T), "init_groupset");
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
ngroups = getgroups(ngroups, groupset);
|
|
Packit Service |
f629e6 |
/* same thing here, give up but keep going */
|
|
Packit Service |
f629e6 |
if (ngroups == -1) {
|
|
Packit Service |
f629e6 |
efree(groupset);
|
|
Packit Service |
f629e6 |
ngroups = 0;
|
|
Packit Service |
f629e6 |
groupset = NULL;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* estrdup --- duplicate a string */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
char *
|
|
Packit Service |
f629e6 |
estrdup(const char *str, size_t len)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
char *s;
|
|
Packit Service |
f629e6 |
emalloc(s, char *, len + 1, "estrdup");
|
|
Packit Service |
f629e6 |
memcpy(s, str, len);
|
|
Packit Service |
f629e6 |
s[len] = '\0';
|
|
Packit Service |
f629e6 |
return s;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#if defined(HAVE_LOCALE_H)
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* init_locale --- initialize locale info. */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* On some operating systems, the pointers in the struct returned
|
|
Packit Service |
f629e6 |
* by localeconv() can become dangling pointers after a call to
|
|
Packit Service |
f629e6 |
* setlocale(). So we do a deep copy.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* Thanks to KIMURA Koichi <kimura.koichi@canon.co.jp>.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
init_locale(struct lconv *l)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
struct lconv *t;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
t = localeconv();
|
|
Packit Service |
f629e6 |
*l = *t;
|
|
Packit Service |
f629e6 |
l->thousands_sep = estrdup(t->thousands_sep, strlen(t->thousands_sep));
|
|
Packit Service |
f629e6 |
l->decimal_point = estrdup(t->decimal_point, strlen(t->decimal_point));
|
|
Packit Service |
f629e6 |
l->grouping = estrdup(t->grouping, strlen(t->grouping));
|
|
Packit Service |
f629e6 |
l->int_curr_symbol = estrdup(t->int_curr_symbol, strlen(t->int_curr_symbol));
|
|
Packit Service |
f629e6 |
l->currency_symbol = estrdup(t->currency_symbol, strlen(t->currency_symbol));
|
|
Packit Service |
f629e6 |
l->mon_decimal_point = estrdup(t->mon_decimal_point, strlen(t->mon_decimal_point));
|
|
Packit Service |
f629e6 |
l->mon_thousands_sep = estrdup(t->mon_thousands_sep, strlen(t->mon_thousands_sep));
|
|
Packit Service |
f629e6 |
l->mon_grouping = estrdup(t->mon_grouping, strlen(t->mon_grouping));
|
|
Packit Service |
f629e6 |
l->positive_sign = estrdup(t->positive_sign, strlen(t->positive_sign));
|
|
Packit Service |
f629e6 |
l->negative_sign = estrdup(t->negative_sign, strlen(t->negative_sign));
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
#endif /* LOCALE_H */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* save_argv --- save argv array */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
save_argv(int argc, char **argv)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
int i;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
emalloc(d_argv, char **, (argc + 1) * sizeof(char *), "save_argv");
|
|
Packit Service |
f629e6 |
for (i = 0; i < argc; i++)
|
|
Packit Service |
f629e6 |
d_argv[i] = estrdup(argv[i], strlen(argv[i]));
|
|
Packit Service |
f629e6 |
d_argv[argc] = NULL;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* update_global_values --- make sure the symbol table has correct values.
|
|
Packit Service |
f629e6 |
* Called from the grammar before dumping values.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* Also called when accessing through SYMTAB, and from api_sym_lookup().
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
void
|
|
Packit Service |
f629e6 |
update_global_values()
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
const struct varinit *vp;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
for (vp = varinit; vp->name; vp++) {
|
|
Packit Service |
f629e6 |
if (vp->update != NULL)
|
|
Packit Service |
f629e6 |
vp->update();
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* getenv_long --- read a long value (>= 0) from an environment var. */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
long
|
|
Packit Service |
f629e6 |
getenv_long(const char *name)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
const char *val;
|
|
Packit Service |
f629e6 |
long newval;
|
|
Packit Service |
f629e6 |
if ((val = getenv(name)) != NULL && isdigit((unsigned char) *val)) {
|
|
Packit Service |
f629e6 |
for (newval = 0; *val && isdigit((unsigned char) *val); val++)
|
|
Packit Service |
f629e6 |
newval = (newval * 10) + *val - '0';
|
|
Packit Service |
f629e6 |
return newval;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
return -1;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* parse_args --- do the getopt_long thing */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
parse_args(int argc, char **argv)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* The + on the front tells GNU getopt not to rearrange argv.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
const char *optlist = "+F:f:v:W;bcCd::D::e:E:ghi:l:L::nNo::Op::MPrSstVYZ:";
|
|
Packit Service |
f629e6 |
int old_optind;
|
|
Packit Service |
f629e6 |
int c;
|
|
Packit Service |
f629e6 |
char *scan;
|
|
Packit Service |
f629e6 |
char *src;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* we do error messages ourselves on invalid options */
|
|
Packit Service |
f629e6 |
opterr = false;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* copy argv before getopt gets to it; used to restart the debugger */
|
|
Packit Service |
f629e6 |
save_argv(argc, argv);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* option processing. ready, set, go! */
|
|
Packit Service |
f629e6 |
for (optopt = 0, old_optind = 1;
|
|
Packit Service |
f629e6 |
(c = getopt_long(argc, argv, optlist, optab, NULL)) != EOF;
|
|
Packit Service |
f629e6 |
optopt = 0, old_optind = optind) {
|
|
Packit Service |
f629e6 |
if (do_posix)
|
|
Packit Service |
f629e6 |
opterr = true;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
switch (c) {
|
|
Packit Service |
f629e6 |
case 'F':
|
|
Packit Service |
f629e6 |
add_preassign(PRE_ASSIGN_FS, optarg);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'E':
|
|
Packit Service |
f629e6 |
disallow_var_assigns = true;
|
|
Packit Service |
f629e6 |
/* fall through */
|
|
Packit Service |
f629e6 |
case 'f':
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Allow multiple -f options.
|
|
Packit Service |
f629e6 |
* This makes function libraries real easy.
|
|
Packit Service |
f629e6 |
* Most of the magic is in the scanner.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* The following is to allow for whitespace at the end
|
|
Packit Service |
f629e6 |
* of a #! /bin/gawk line in an executable file
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
scan = optarg;
|
|
Packit Service |
f629e6 |
if (argv[optind-1] != optarg)
|
|
Packit Service |
f629e6 |
while (isspace((unsigned char) *scan))
|
|
Packit Service |
f629e6 |
scan++;
|
|
Packit Service |
f629e6 |
src = (*scan == '\0' ? argv[optind++] : optarg);
|
|
Packit Service |
f629e6 |
(void) add_srcfile((src && src[0] == '-' && src[1] == '\0') ?
|
|
Packit Service |
f629e6 |
SRC_STDIN : SRC_FILE,
|
|
Packit Service |
f629e6 |
src, srcfiles, NULL, NULL);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'v':
|
|
Packit Service |
f629e6 |
add_preassign(PRE_ASSIGN, optarg);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'b':
|
|
Packit Service |
f629e6 |
do_binary = true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'c':
|
|
Packit Service |
f629e6 |
do_flags |= DO_TRADITIONAL;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'C':
|
|
Packit Service |
f629e6 |
copyleft();
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'd':
|
|
Packit Service |
f629e6 |
do_flags |= DO_DUMP_VARS;
|
|
Packit Service |
f629e6 |
if (optarg != NULL && optarg[0] != '\0')
|
|
Packit Service |
f629e6 |
varfile = optarg;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'D':
|
|
Packit Service |
f629e6 |
do_flags |= DO_DEBUG;
|
|
Packit Service |
f629e6 |
if (optarg != NULL && optarg[0] != '\0')
|
|
Packit Service |
f629e6 |
command_file = optarg;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'e':
|
|
Packit Service |
f629e6 |
if (optarg[0] == '\0')
|
|
Packit Service |
f629e6 |
warning(_("empty argument to `-e/--source' ignored"));
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
(void) add_srcfile(SRC_CMDLINE, optarg, srcfiles, NULL, NULL);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'g':
|
|
Packit Service |
f629e6 |
do_flags |= DO_INTL;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'h':
|
|
Packit Service |
f629e6 |
/* write usage to stdout, per GNU coding stds */
|
|
Packit Service |
f629e6 |
usage(EXIT_SUCCESS, stdout);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'i':
|
|
Packit Service |
f629e6 |
(void) add_srcfile(SRC_INC, optarg, srcfiles, NULL, NULL);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'l':
|
|
Packit Service |
f629e6 |
(void) add_srcfile(SRC_EXTLIB, optarg, srcfiles, NULL, NULL);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
#ifndef NO_LINT
|
|
Packit Service |
f629e6 |
case 'L':
|
|
Packit Service |
f629e6 |
do_flags |= DO_LINT_ALL;
|
|
Packit Service |
f629e6 |
if (optarg != NULL) {
|
|
Packit Service |
f629e6 |
if (strcmp(optarg, "fatal") == 0)
|
|
Packit Service |
f629e6 |
lintfunc = r_fatal;
|
|
Packit Service |
f629e6 |
else if (strcmp(optarg, "invalid") == 0) {
|
|
Packit Service |
f629e6 |
do_flags &= ~DO_LINT_ALL;
|
|
Packit Service |
f629e6 |
do_flags |= DO_LINT_INVALID;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 't':
|
|
Packit Service |
f629e6 |
do_flags |= DO_LINT_OLD;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
case 'L':
|
|
Packit Service |
f629e6 |
case 't':
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'n':
|
|
Packit Service |
f629e6 |
do_flags |= DO_NON_DEC_DATA;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'N':
|
|
Packit Service |
f629e6 |
use_lc_numeric = true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'O':
|
|
Packit Service |
f629e6 |
do_optimize = true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'p':
|
|
Packit Service |
f629e6 |
do_flags |= DO_PROFILE;
|
|
Packit Service |
f629e6 |
/* fall through */
|
|
Packit Service |
f629e6 |
case 'o':
|
|
Packit Service |
f629e6 |
do_flags |= DO_PRETTY_PRINT;
|
|
Packit Service |
f629e6 |
if (optarg != NULL)
|
|
Packit Service |
f629e6 |
set_prof_file(optarg);
|
|
Packit Service |
f629e6 |
else
|
|
Packit Service |
f629e6 |
set_prof_file(DEFAULT_PROFILE);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'M':
|
|
Packit Service |
f629e6 |
#ifdef HAVE_MPFR
|
|
Packit Service |
f629e6 |
do_flags |= DO_MPFR;
|
|
Packit Service |
f629e6 |
#else
|
|
Packit Service |
f629e6 |
warning(_("-M ignored: MPFR/GMP support not compiled in"));
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'P':
|
|
Packit Service |
f629e6 |
do_flags |= DO_POSIX;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'r':
|
|
Packit Service |
f629e6 |
do_flags |= DO_INTERVALS;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 's':
|
|
Packit Service |
f629e6 |
do_optimize = false;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'S':
|
|
Packit Service |
f629e6 |
do_flags |= DO_SANDBOX;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'V':
|
|
Packit Service |
f629e6 |
do_version = true;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'W': /* gawk specific options - now in getopt_long */
|
|
Packit Service |
f629e6 |
fprintf(stderr, _("%s: option `-W %s' unrecognized, ignored\n"),
|
|
Packit Service |
f629e6 |
argv[0], optarg);
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 0:
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* getopt_long found an option that sets a variable
|
|
Packit Service |
f629e6 |
* instead of returning a letter. Do nothing, just
|
|
Packit Service |
f629e6 |
* cycle around for the next one.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
case 'Y':
|
|
Packit Service |
f629e6 |
case 'Z':
|
|
Packit Service |
f629e6 |
#if defined(YYDEBUG) || defined(GAWKDEBUG)
|
|
Packit Service |
f629e6 |
if (c == 'Y') {
|
|
Packit Service |
f629e6 |
yydebug = 2;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
#if defined(LOCALEDEBUG)
|
|
Packit Service |
f629e6 |
if (c == 'Z') {
|
|
Packit Service |
f629e6 |
locale = optarg;
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
/* if not debugging, fall through */
|
|
Packit Service |
f629e6 |
case '?':
|
|
Packit Service |
f629e6 |
default:
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* If not posix, an unrecognized option stops argument
|
|
Packit Service |
f629e6 |
* processing so that it can go into ARGV for the awk
|
|
Packit Service |
f629e6 |
* program to see. This makes use of ``#! /bin/gawk -f''
|
|
Packit Service |
f629e6 |
* easier.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* However, it's never simple. If optopt is set,
|
|
Packit Service |
f629e6 |
* an option that requires an argument didn't get the
|
|
Packit Service |
f629e6 |
* argument. We care because if opterr is 0, then
|
|
Packit Service |
f629e6 |
* getopt_long won't print the error message for us.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
if (! do_posix
|
|
Packit Service |
f629e6 |
&& (optopt == '\0' || strchr(optlist, optopt) == NULL)) {
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* can't just do optind--. In case of an
|
|
Packit Service |
f629e6 |
* option with >= 2 letters, getopt_long
|
|
Packit Service |
f629e6 |
* won't have incremented optind.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
optind = old_optind;
|
|
Packit Service |
f629e6 |
stopped_early = true;
|
|
Packit Service |
f629e6 |
goto out;
|
|
Packit Service |
f629e6 |
} else if (optopt != '\0') {
|
|
Packit Service |
f629e6 |
/* Use POSIX required message format */
|
|
Packit Service |
f629e6 |
fprintf(stderr,
|
|
Packit Service |
f629e6 |
_("%s: option requires an argument -- %c\n"),
|
|
Packit Service |
f629e6 |
myname, optopt);
|
|
Packit Service |
f629e6 |
usage(EXIT_FAILURE, stderr);
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
/* else
|
|
Packit Service |
f629e6 |
let getopt print error message for us */
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
if (c == 'E') /* --exec ends option processing */
|
|
Packit Service |
f629e6 |
break;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
out:
|
|
Packit Service |
f629e6 |
do_optimize = (do_optimize && ! do_pretty_print);
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
return;
|
|
Packit Service |
f629e6 |
}
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* set_locale_stuff --- setup the locale stuff */
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
static void
|
|
Packit Service |
f629e6 |
set_locale_stuff(void)
|
|
Packit Service |
f629e6 |
{
|
|
Packit Service |
f629e6 |
#if defined(LC_CTYPE)
|
|
Packit Service |
f629e6 |
setlocale(LC_CTYPE, locale);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
#if defined(LC_COLLATE)
|
|
Packit Service |
f629e6 |
setlocale(LC_COLLATE, locale);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
#if defined(LC_MESSAGES)
|
|
Packit Service |
f629e6 |
setlocale(LC_MESSAGES, locale);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
#if defined(LC_NUMERIC) && defined(HAVE_LOCALE_H)
|
|
Packit Service |
f629e6 |
/*
|
|
Packit Service |
f629e6 |
* Force the issue here. According to POSIX 2001, decimal
|
|
Packit Service |
f629e6 |
* point is used for parsing source code and for command-line
|
|
Packit Service |
f629e6 |
* assignments and the locale value for processing input,
|
|
Packit Service |
f629e6 |
* number to string conversion, and printing output.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* 10/2005 --- see below also; we now only use the locale's
|
|
Packit Service |
f629e6 |
* decimal point if do_posix in effect.
|
|
Packit Service |
f629e6 |
*
|
|
Packit Service |
f629e6 |
* 9/2007:
|
|
Packit Service |
f629e6 |
* This is a mess. We need to get the locale's numeric info for
|
|
Packit Service |
f629e6 |
* the thousands separator for the %'d flag.
|
|
Packit Service |
f629e6 |
*/
|
|
Packit Service |
f629e6 |
setlocale(LC_NUMERIC, locale);
|
|
Packit Service |
f629e6 |
init_locale(& loc);
|
|
Packit Service |
f629e6 |
setlocale(LC_NUMERIC, "C");
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
#if defined(LC_TIME)
|
|
Packit Service |
f629e6 |
setlocale(LC_TIME, locale);
|
|
Packit Service |
f629e6 |
#endif
|
|
Packit Service |
f629e6 |
|
|
Packit Service |
f629e6 |
/* These must be done after calling setlocale */
|
|
Packit Service |
f629e6 |
(void) bindtextdomain(PACKAGE, locale_dir);
|
|
Packit Service |
f629e6 |
(void) textdomain(PACKAGE);
|
|
Packit Service |
f629e6 |
}
|