Main Page | Class List | Directories | File List | Class Members | File Members

main.c File Reference

#include "awk.h"
#include "getopt.h"
#include "patchlev.h"

Go to the source code of this file.

Classes

struct  varinit

Defines

#define DEFAULT_PROFILE   "awkprof.out"
#define DEFAULT_VARFILE   "awkvars.out"
#define srcfiles_add(stype, val)   add_src(&srcfiles, &numfiles, &allocfiles, stype, val)
#define preassigns_add(stype, val)   add_src(&preassigns, &numassigns, &allocassigns, stype, val)
#define INIT_SRC   4
#define getpgrp_arg()   getpid()

Functions

static void usage P ((int exitval, FILE *fp))
int main (int argc, char **argv)
static void add_src (struct src **data, long *num, long *alloc, enum srctype stype, char *val)
static void usage (int exitval, FILE *fp)
static void copyleft ()
static void cmdline_fs (char *str)
static void init_args (int argc0, int argc, char *argv0, char **argv)
static void init_vars ()
NODEload_environ ()
NODEload_procinfo ()
int arg_assign (char *arg, int initing)
static RETSIGTYPE catchsig (int sig)
static void nostalgia ()
static void version ()
static void init_fds ()
static void init_groupset ()

Variables

static const char * varfile = DEFAULT_VARFILE
static const struct varinit varinit []


Define Documentation

#define DEFAULT_PROFILE   "awkprof.out"
 

Definition at line 42 of file main.c.

Referenced by main().

#define DEFAULT_VARFILE   "awkvars.out"
 

Definition at line 43 of file main.c.

 
#define getpgrp_arg  )     getpid()
 

#define INIT_SRC   4
 

Referenced by add_src().

#define preassigns_add stype,
val   )     add_src(&preassigns, &numassigns, &allocassigns, stype, val)
 

Referenced by main().

#define srcfiles_add stype,
val   )     add_src(&srcfiles, &numfiles, &allocfiles, stype, val)
 

Referenced by main().


Function Documentation

static void add_src struct src **  data,
long *  num,
long *  alloc,
enum srctype  stype,
char *  val
[static]
 

Definition at line 593 of file main.c.

References emalloc, erealloc, INIT_SRC, and NULL.

00594 {
00595 #define INIT_SRC 4
00596 
00597         ++*num;
00598 
00599         if (*data == NULL) {
00600                 emalloc(*data, struct src *, INIT_SRC * sizeof(struct src), "add_src");
00601                 *alloc = INIT_SRC;
00602         } else if (*num >= *alloc) {
00603                 (*alloc) *= 2;
00604                 erealloc(*data, struct src *, (*alloc) * sizeof(struct src), "add_src");
00605         }
00606 
00607         (*data)[*num].stype = stype;
00608         (*data)[*num].val = val;
00609 
00610 #undef INIT_SRC
00611 }

int arg_assign char *  arg,
int  initing
 

Definition at line 940 of file main.c.

References _, do_lint, FALSE, fatal, exp_node::flags, force_number, get_lhs, ISALNUM, ISALPHA, lintwarn, make_str_node(), MAYBE_NUM, myname, Node_var, NULL, SCAN, setlocale, strchr(), TRUE, unref(), usage(), and variable().

Referenced by main(), and nextfile().

00941 {
00942         char *cp, *cp2;
00943         int badvar;
00944         Func_ptr after_assign = NULL;
00945         NODE *var;
00946         NODE *it;
00947         NODE **lhs;
00948 
00949         cp = strchr(arg, '=');
00950 
00951         if (cp == NULL) {
00952                 if (! initing)
00953                         return FALSE;   /* This is file name, not assignment. */
00954 
00955                 fprintf(stderr,
00956                         _("%s: `%s' argument to `-v' not in `var=value' form\n\n"),
00957                         myname, arg);
00958                 usage(1, stderr);
00959         }
00960 
00961         *cp++ = '\0';
00962 
00963         /* first check that the variable name has valid syntax */
00964         badvar = FALSE;
00965         if (! ISALPHA(arg[0]) && arg[0] != '_')
00966                 badvar = TRUE;
00967         else
00968                 for (cp2 = arg+1; *cp2; cp2++)
00969                         if (! ISALNUM(*cp2) && *cp2 != '_') {
00970                                 badvar = TRUE;
00971                                 break;
00972                         }
00973 
00974         if (badvar) {
00975                 if (initing)
00976                         fatal(_("`%s' is not a legal variable name"), arg);
00977 
00978                 if (do_lint)
00979                         lintwarn(_("`%s' is not a variable name, looking for file `%s=%s'"),
00980                                 arg, arg, cp);
00981         } else {
00982                 /*
00983                  * Recent versions of nawk expand escapes inside assignments.
00984                  * This makes sense, so we do it too.
00985                  */
00986                 it = make_str_node(cp, strlen(cp), SCAN);
00987                 it->flags |= MAYBE_NUM;
00988 #ifdef LC_NUMERIC
00989                 setlocale(LC_NUMERIC, "C");
00990                 (void) force_number(it);
00991                 setlocale(LC_NUMERIC, "");
00992 #endif /* LC_NUMERIC */
00993                 var = variable(arg, FALSE, Node_var);
00994                 lhs = get_lhs(var, &after_assign, FALSE);
00995                 unref(*lhs);
00996                 *lhs = it;
00997                 if (after_assign != NULL)
00998                         (*after_assign)();
00999         }
01000 
01001         *--cp = '=';    /* restore original text of ARGV */
01002 
01003         return ! badvar;
01004 }

static RETSIGTYPE catchsig int  sig  )  [static]
 

Definition at line 1009 of file main.c.

References _, cant_happen, fatal, msg(), and set_loc().

Referenced by main().

01010 {
01011         if (sig == SIGFPE) {
01012                 fatal(_("floating point exception"));
01013         } else if (sig == SIGSEGV
01014 #ifdef SIGBUS
01015                 || sig == SIGBUS
01016 #endif
01017         ) {
01018                 set_loc(__FILE__, __LINE__);
01019                 msg(_("fatal error: internal error"));
01020                 /* fatal won't abort() if not compiled for debugging */
01021                 abort();
01022         } else
01023                 cant_happen();
01024         /* NOTREACHED */
01025 }

static void cmdline_fs char *  str  )  [static]
 

Definition at line 715 of file main.c.

References _, do_lint, do_posix, do_traditional, FALSE, FS_node, get_lhs, lintwarn, make_str_node(), SCAN, set_FS(), and unref().

Referenced by main().

00716 {
00717         register NODE **tmp;
00718 
00719         tmp = get_lhs(FS_node, (Func_ptr *) 0, FALSE);
00720         unref(*tmp);
00721         /*
00722          * Only if in full compatibility mode check for the stupid special
00723          * case so -F\t works as documented in awk book even though the shell
00724          * hands us -Ft.  Bleah!
00725          *
00726          * Thankfully, Posix didn't propagate this "feature".
00727          */
00728         if (str[0] == 't' && str[1] == '\0') {
00729                 if (do_lint)
00730                         lintwarn(_("-Ft does not set FS to tab in POSIX awk"));
00731                 if (do_traditional && ! do_posix)
00732                         str[0] = '\t';
00733         }
00734         *tmp = make_str_node(str, strlen(str), SCAN); /* do process escapes */
00735         set_FS();
00736 }

static void copyleft  )  [static]
 

Definition at line 679 of file main.c.

References _, exit, and N_.

Referenced by main(), and version().

00680 {
00681         static const char blurb_part1[] =
00682           N_("Copyright (C) 1989, 1991-%d Free Software Foundation.\n\
00683 \n\
00684 This program is free software; you can redistribute it and/or modify\n\
00685 it under the terms of the GNU General Public License as published by\n\
00686 the Free Software Foundation; either version 2 of the License, or\n\
00687 (at your option) any later version.\n\
00688 \n");
00689         static const char blurb_part2[] =
00690           N_("This program is distributed in the hope that it will be useful,\n\
00691 but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
00692 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n\
00693 GNU General Public License for more details.\n\
00694 \n");
00695         static const char blurb_part3[] =
00696           N_("You should have received a copy of the GNU General Public License\n\
00697 along with this program; if not, write to the Free Software\n\
00698 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n");
00699  
00700         /* multiple blurbs are needed for some brain dead compilers. */
00701         printf(_(blurb_part1), 2003);   /* Last update year */
00702         fputs(_(blurb_part2), stdout);
00703         fputs(_(blurb_part3), stdout);
00704         fflush(stdout);
00705 
00706         if (ferror(stdout))
00707                 exit(1);
00708 
00709         exit(0);
00710 }

static void init_args int  argc0,
int  argc,
char *  argv0,
char **  argv
[static]
 

Definition at line 741 of file main.c.

References ARGC_node, ARGV_node, assoc_lookup(), AWKNUM, FALSE, i, install(), make_number, make_string, MAYBE_NUM, node(), Node_var, Node_var_array, NULL, and tmp_number.

Referenced by main().

00742 {
00743         int i, j;
00744         NODE **aptr;
00745 
00746         ARGV_node = install("ARGV", node((NODE *) NULL, Node_var_array, (NODE *) NULL));
00747         aptr = assoc_lookup(ARGV_node, tmp_number(0.0), FALSE);
00748         *aptr = make_string(argv0, strlen(argv0));
00749         (*aptr)->flags |= MAYBE_NUM;
00750         for (i = argc0, j = 1; i < argc; i++) {
00751                 aptr = assoc_lookup(ARGV_node, tmp_number((AWKNUM) j), FALSE);
00752                 *aptr = make_string(argv[i], strlen(argv[i]));
00753                 (*aptr)->flags |= MAYBE_NUM;
00754                 j++;
00755         }
00756         ARGC_node = install("ARGC",
00757                         node(make_number((AWKNUM) j), Node_var, (NODE *) NULL));
00758 }

static void init_fds  )  [static]
 

Definition at line 1058 of file main.c.

References _, devopen(), do_lint, and lintwarn.

Referenced by main().

01059 {
01060         struct stat sbuf;
01061         int fd;
01062         int newfd;
01063 
01064         /* maybe no stderr, don't bother with error mesg */
01065         for (fd = 0; fd <= 2; fd++) {
01066                 if (fstat(fd, &sbuf) < 0) {
01067 #if MAKE_A_HEROIC_EFFORT
01068                         if (do_lint)
01069                                 lintwarn(_("no pre-opened fd %d"), fd);
01070 #endif
01071                         newfd = devopen("/dev/null", "r+");
01072 #ifdef MAKE_A_HEROIC_EFFORT
01073                         if (do_lint && newfd < 0)
01074                                 lintwarn(_("could not pre-open /dev/null for fd %d"), fd);
01075 #endif
01076                 }
01077         }
01078 }

static void init_groupset  )  [static]
 

Definition at line 1083 of file main.c.

References _, emalloc, errno, fatal, GETGROUPS_T, NULL, and strerror.

Referenced by main().

01084 {
01085 #if defined(HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
01086 #ifdef GETGROUPS_NOT_STANDARD
01087         /* For systems that aren't standards conformant, use old way. */
01088         ngroups = NGROUPS_MAX;
01089 #else
01090         /*
01091          * If called with 0 for both args, return value is
01092          * total number of groups.
01093          */
01094         ngroups = getgroups(0, NULL);
01095 #endif
01096         if (ngroups == -1)
01097                 fatal(_("could not find groups: %s"), strerror(errno));
01098         else if (ngroups == 0)
01099                 return;
01100 
01101         /* fill in groups */
01102         emalloc(groupset, GETGROUPS_T *, ngroups * sizeof(GETGROUPS_T), "init_groupset");
01103 
01104         ngroups = getgroups(ngroups, groupset);
01105         if (ngroups == -1)
01106                 fatal(_("could not find groups: %s"), strerror(errno));
01107 #endif
01108 }

static void init_vars  )  [static]
 

Definition at line 803 of file main.c.

References varinit::assign, install(), make_number, make_string, varinit::name, node(), NULL, varinit::numval, varinit::spec, varinit::strval, and varinit::type.

Referenced by main().

00804 {
00805         register const struct varinit *vp;
00806 
00807         for (vp = varinit; vp->name; vp++) {
00808                 *(vp->spec) = install((char *) vp->name,
00809                   node(vp->strval == NULL ? make_number(vp->numval)
00810                                 : make_string((char *) vp->strval,
00811                                         strlen(vp->strval)),
00812                        vp->type, (NODE *) NULL));
00813                 if (vp->assign)
00814                         (*(vp->assign))();
00815         }
00816 }

NODE* load_environ  ) 
 

Definition at line 821 of file main.c.

References assoc_lookup(), defpath, environ, FALSE, getenv, i, install(), make_string, MAYBE_NUM, node(), Node_var_array, NULL, strchr(), and tmp_string().

Referenced by variable().

00822 {
00823 #if ! defined(TANDEM)
00824 #if ! (defined(MSDOS) && !defined(DJGPP)) && ! defined(OS2) && ! (defined(VMS) && defined(__DECC))
00825         extern char **environ;
00826 #endif
00827         register char *var, *val;
00828         NODE **aptr;
00829         register int i;
00830 #endif /* TANDEM */
00831 
00832         ENVIRON_node = install("ENVIRON", 
00833                         node((NODE *) NULL, Node_var_array, (NODE *) NULL));
00834 #if ! defined(TANDEM)
00835         for (i = 0; environ[i] != NULL; i++) {
00836                 static char nullstr[] = "";
00837 
00838                 var = environ[i];
00839                 val = strchr(var, '=');
00840                 if (val != NULL)
00841                         *val++ = '\0';
00842                 else
00843                         val = nullstr;
00844                 aptr = assoc_lookup(ENVIRON_node, tmp_string(var, strlen(var)),
00845                                     FALSE);
00846                 *aptr = make_string(val, strlen(val));
00847                 (*aptr)->flags |= MAYBE_NUM;
00848 
00849                 /* restore '=' so that system() gets a valid environment */
00850                 if (val != nullstr)
00851                         *--val = '=';
00852         }
00853         /*
00854          * Put AWKPATH into ENVIRON if it's not there.
00855          * This allows querying it from within awk programs.
00856          */
00857         if (getenv("AWKPATH") == NULL) {
00858                 aptr = assoc_lookup(ENVIRON_node, tmp_string("AWKPATH", 7), FALSE);
00859                 *aptr = make_string(defpath, strlen(defpath));
00860         }
00861 #endif /* TANDEM */
00862         return ENVIRON_node;
00863 }

NODE* load_procinfo  ) 
 

Definition at line 868 of file main.c.

References assoc_lookup(), AWKNUM, FALSE, free(), getegid, geteuid, getgid, getpgrp(), getpgrp_arg, getpid(), getppid(), getuid, i, install(), make_number, make_string, name, node(), Node_var_array, NULL, PROCINFO_node, tmp_string(), and using_fieldwidths().

Referenced by variable().

00869 {
00870         int i;
00871         NODE **aptr;
00872         char name[100];
00873         AWKNUM value;
00874 
00875         PROCINFO_node = install("PROCINFO",
00876                         node((NODE *) NULL, Node_var_array, (NODE *) NULL));
00877 
00878 #ifdef GETPGRP_VOID
00879 #define getpgrp_arg() /* nothing */
00880 #else
00881 #define getpgrp_arg() getpid()
00882 #endif
00883 
00884         value = getpgrp(getpgrp_arg());
00885         aptr = assoc_lookup(PROCINFO_node, tmp_string("pgrpid", 6), FALSE);
00886         *aptr = make_number(value);
00887 
00888         /*
00889          * could put a lot of this into a table, but then there's
00890          * portability problems declaring all the functions. so just
00891          * do it the slow and stupid way. sigh.
00892          */
00893 
00894         value = getpid();
00895         aptr = assoc_lookup(PROCINFO_node, tmp_string("pid", 3), FALSE);
00896         *aptr = make_number(value);
00897 
00898         value = getppid();
00899         aptr = assoc_lookup(PROCINFO_node, tmp_string("ppid", 4), FALSE);
00900         *aptr = make_number(value);
00901 
00902         value = getuid();
00903         aptr = assoc_lookup(PROCINFO_node, tmp_string("uid", 3), FALSE);
00904         *aptr = make_number(value);
00905 
00906         value = geteuid();
00907         aptr = assoc_lookup(PROCINFO_node, tmp_string("euid", 4), FALSE);
00908         *aptr = make_number(value);
00909 
00910         value = getgid();
00911         aptr = assoc_lookup(PROCINFO_node, tmp_string("gid", 3), FALSE);
00912         *aptr = make_number(value);
00913 
00914         value = getegid();
00915         aptr = assoc_lookup(PROCINFO_node, tmp_string("egid", 4), FALSE);
00916         *aptr = make_number(value);
00917 
00918         aptr = assoc_lookup(PROCINFO_node, tmp_string("FS", 2), FALSE);
00919         *aptr = (using_fieldwidths() ? make_string("FIELDWIDTHS", 11) :
00920                                 make_string("FS", 2) );
00921 
00922 #if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
00923         for (i = 0; i < ngroups; i++) {
00924                 sprintf(name, "group%d", i + 1);
00925                 value = groupset[i];
00926                 aptr = assoc_lookup(PROCINFO_node, tmp_string(name, strlen(name)), FALSE);
00927                 *aptr = make_number(value);
00928         }
00929         if (groupset) {
00930                 free(groupset);
00931                 groupset = NULL;
00932         }
00933 #endif
00934         return PROCINFO_node;
00935 }

int main int  argc,
char **  argv
 

Definition at line 199 of file main.c.

References _, arg_assign(), array_init(), begin_block, bindtextdomain, BINMODE, catchsig(), close_io(), cmdline_fs(), copyleft(), DEFAULT_PROFILE, do_dump_vars, do_input(), do_intl, do_lint, do_non_decimal_data, do_posix, do_tidy_mem, do_traditional, dump_funcs(), dump_prog(), dump_vars(), end_block, errcount, errno, exit, exit_val, exiting, expression_value, FALSE, fatal, exp_node::flags, free(), gawk_name(), getenv, getopt_long(), i, in_begin_rule, in_end_rule, init_args(), init_fds(), init_fields(), init_groupset(), init_profiling(), init_profiling_signals(), init_vars(), interpret(), isatty(), ISDIGIT, ISSPACE, LINT_ALL, LINT_INVALID, lintfunc, lintwarn, LOCALEDIR, make_string, MRL, myname, Nnull_string, Node_val, nostalgia(), NULL, NUMBER, NUMCUR, numfiles, O_BINARY, optarg, opterr, optind, optopt, os_arg_fixup(), os_is_setuid(), os_setbinmode(), output_is_tty, PACKAGE, PERM, preassigns_add, r_fatal(), release_all_vars(), resetup(), set_prof_file(), setlocale, shadow_funcs(), srcfiles, srcfiles_add, strchr(), STRCUR, strerror, STRING, textdomain, tokexpand(), TRUE, exp_node::type, usage(), flagtab::val, varfile, version(), version_string, warning(), whiny_users, yydebug, and yyparse.

00200 {
00201         int c;
00202         char *scan;
00203         /* the + on the front tells GNU getopt not to rearrange argv */
00204         const char *optlist = "+F:f:v:W;m:D";
00205         int stopped_early = FALSE;
00206         int old_optind;
00207         extern int optind;
00208         extern int opterr;
00209         extern char *optarg;
00210         int i;
00211 
00212         /* do these checks early */
00213         if (getenv("TIDYMEM") != NULL)
00214                 do_tidy_mem = TRUE;
00215 
00216         if (getenv("WHINY_USERS") != NULL)
00217                 whiny_users = TRUE;
00218 
00219 #ifdef HAVE_MCHECK_H
00220         if (do_tidy_mem)
00221                 mtrace();
00222 #endif /* HAVE_MCHECK_H */
00223         
00224 #if defined(LC_CTYPE)
00225         setlocale(LC_CTYPE, "");
00226 #endif
00227 #if defined(LC_COLLATE)
00228         setlocale(LC_COLLATE, "");
00229 #endif
00230 #if HAVE_LC_MESSAGES && defined(LC_MESSAGES)
00231         setlocale(LC_MESSAGES, "");
00232 #endif
00233 #if defined(LC_NUMERIC)
00234         /*
00235          * Force the issue here.  According to POSIX 2001, decimal
00236          * point is used for parsing source code and for command-line
00237          * assignments and the locale value for processing input,
00238          * number to string conversion, and printing output.
00239          */
00240         setlocale(LC_NUMERIC, "C");
00241 #endif
00242 #if defined(LC_TIME)
00243         setlocale(LC_TIME, "");
00244 #endif
00245 
00246 #ifdef MBS_SUPPORT
00247         /*
00248          * In glibc, MB_CUR_MAX is actually a function.  This value is
00249          * tested *a lot* in many speed-critical places in gawk. Caching
00250          * this value once makes a speed difference.
00251          */
00252         gawk_mb_cur_max = MB_CUR_MAX;
00253 #endif
00254 
00255         bindtextdomain(PACKAGE, LOCALEDIR);
00256         textdomain(PACKAGE);
00257 
00258         (void) signal(SIGFPE, catchsig);
00259         (void) signal(SIGSEGV, catchsig);
00260 #ifdef SIGBUS
00261         (void) signal(SIGBUS, catchsig);
00262 #endif
00263 
00264         myname = gawk_name(argv[0]);
00265         argv[0] = (char *) myname;
00266         os_arg_fixup(&argc, &argv); /* emulate redirection, expand wildcards */
00267 
00268         /* remove sccs gunk */
00269         if (strncmp(version_string, "@(#)", 4) == 0)
00270                 version_string += 4;
00271 
00272         if (argc < 2)
00273                 usage(1, stderr);
00274 
00275         /* Robustness: check that file descriptors 0, 1, 2 are open */
00276         init_fds();
00277 
00278         /* init array handling. */
00279         array_init();
00280 
00281         /* we do error messages ourselves on invalid options */
00282         opterr = FALSE;
00283 
00284         /* option processing. ready, set, go! */
00285         for (optopt = 0, old_optind = 1;
00286              (c = getopt_long(argc, argv, optlist, optab, NULL)) != EOF;
00287              optopt = 0, old_optind = optind) {
00288                 if (do_posix)
00289                         opterr = TRUE;
00290 
00291                 switch (c) {
00292                 case 'F':
00293                         preassigns_add(PRE_ASSIGN_FS, optarg);
00294                         break;
00295 
00296                 case 'f':
00297                         /*
00298                          * a la MKS awk, allow multiple -f options.
00299                          * this makes function libraries real easy.
00300                          * most of the magic is in the scanner.
00301                          *
00302                          * The following is to allow for whitespace at the end
00303                          * of a #! /bin/gawk line in an executable file
00304                          */
00305                         scan = optarg;
00306                         if (argv[optind-1] != optarg)
00307                                 while (ISSPACE(*scan))
00308                                         scan++;
00309                         srcfiles_add(SOURCEFILE,
00310                                 (*scan == '\0' ? argv[optind++] : optarg));
00311                         break;
00312 
00313                 case 'v':
00314                         preassigns_add(PRE_ASSIGN, optarg);
00315                         break;
00316 
00317                 case 'm':
00318                         /*
00319                          * Research awk extension.
00320                          *      -mf nnn         set # fields, gawk ignores
00321                          *      -mr nnn         set record length, ditto
00322                          */
00323                         if (do_lint)
00324                                 lintwarn(_("`-m[fr]' option irrelevant in gawk"));
00325                         if (optarg[0] != 'r' && optarg[0] != 'f')
00326                                 warning(_("-m option usage: `-m[fr] nnn'"));
00327                         /*
00328                          * Set fixed length records for Tandem,
00329                          * ignored on other platforms (see io.c:get_a_record).
00330                          */
00331                         if (optarg[0] == 'r') {
00332                                 if (ISDIGIT(optarg[1]))
00333                                         MRL = atoi(optarg+1);
00334                                 else {
00335                                         MRL = atoi(argv[optind]);
00336                                         optind++;
00337                                 }
00338                         } else if (optarg[1] == '\0')
00339                                 optind++;
00340                         break;
00341 
00342                 case 'W':       /* gawk specific options - now in getopt_long */
00343                         fprintf(stderr, _("%s: option `-W %s' unrecognized, ignored\n"),
00344                                 argv[0], optarg);
00345                         break;
00346 
00347                 /* These can only come from long form options */
00348                 case 'C':
00349                         copyleft();
00350                         break;
00351 
00352                 case 'd':
00353                         do_dump_vars = TRUE;
00354                         if (optarg != NULL && optarg[0] != '\0')
00355                                 varfile = optarg;
00356                         break;
00357 
00358                 case 'l':
00359 #ifndef NO_LINT
00360                         do_lint = LINT_ALL;
00361                         if (optarg != NULL) {
00362                                 if (strcmp(optarg, "fatal") == 0)
00363                                         lintfunc = r_fatal;
00364                                 else if (strcmp(optarg, "invalid") == 0)
00365                                         do_lint = LINT_INVALID;
00366                         }
00367 #endif
00368                         break;
00369 
00370                 case 'p':
00371                         do_profiling = TRUE;
00372                         if (optarg != NULL)
00373                                 set_prof_file(optarg);
00374                         else
00375                                 set_prof_file(DEFAULT_PROFILE);
00376                         break;
00377 
00378                 case 's':
00379                         if (optarg[0] == '\0')
00380                                 warning(_("empty argument to `--source' ignored"));
00381                         else
00382                                 srcfiles_add(CMDLINE, optarg);
00383                         break;
00384 
00385                 case 'u':
00386                         usage(0, stdout);       /* per coding stds */
00387                         break;
00388 
00389                 case 'V':
00390                         version();
00391                         break;
00392 
00393                 case 0:
00394                         /*
00395                          * getopt_long found an option that sets a variable
00396                          * instead of returning a letter. Do nothing, just
00397                          * cycle around for the next one.
00398                          */
00399                         break;
00400 
00401                 case 'D':
00402 #ifdef GAWKDEBUG
00403                         yydebug = 2;
00404                         break;
00405 #endif
00406                         /* if not debugging, fall through */
00407 
00408                 case '?':
00409                 default:
00410                         /*
00411                          * New behavior.  If not posix, an unrecognized
00412                          * option stops argument processing so that it can
00413                          * go into ARGV for the awk program to see. This
00414                          * makes use of ``#! /bin/gawk -f'' easier.
00415                          *
00416                          * However, it's never simple. If optopt is set,
00417                          * an option that requires an argument didn't get the
00418                          * argument. We care because if opterr is 0, then
00419                          * getopt_long won't print the error message for us.
00420                          */
00421                         if (! do_posix
00422                             && (optopt == '\0' || strchr(optlist, optopt) == NULL)) {
00423                                 /*
00424                                  * can't just do optind--. In case of an
00425                                  * option with >= 2 letters, getopt_long
00426                                  * won't have incremented optind.
00427                                  */
00428                                 optind = old_optind;
00429                                 stopped_early = TRUE;
00430                                 goto out;
00431                         } else if (optopt != '\0')
00432                                 /* Use 1003.2 required message format */
00433                                 fprintf(stderr,
00434                                         _("%s: option requires an argument -- %c\n"),
00435                                         myname, optopt);
00436                         /* else
00437                                 let getopt print error message for us */
00438                         break;
00439                 }
00440         }
00441 out:
00442 
00443         if (do_nostalgia)
00444                 nostalgia();
00445 
00446         /* check for POSIXLY_CORRECT environment variable */
00447         if (! do_posix && getenv("POSIXLY_CORRECT") != NULL) {
00448                 do_posix = TRUE;
00449                 if (do_lint)
00450                         lintwarn(
00451         _("environment variable `POSIXLY_CORRECT' set: turning on `--posix'"));
00452         }
00453 
00454         if (do_posix) {
00455                 if (do_traditional)     /* both on command line */
00456                         warning(_("`--posix' overrides `--traditional'"));
00457                 else
00458                         do_traditional = TRUE;
00459                         /*
00460                          * POSIX compliance also implies
00461                          * no GNU extensions either.
00462                          */
00463         }
00464 
00465         if (do_traditional && do_non_decimal_data) {
00466                 do_non_decimal_data = FALSE;
00467                 warning(_("`--posix'/`--traditional' overrides `--non-decimal-data'"));
00468         }
00469 
00470         if (do_lint && os_is_setuid())
00471                 warning(_("running %s setuid root may be a security problem"), myname);
00472 
00473         /*
00474          * Force profiling if this is pgawk.
00475          * Don't bother if the command line already set profiling up.
00476          */
00477         if (! do_profiling)
00478                 init_profiling(& do_profiling, DEFAULT_PROFILE);
00479 
00480         /* load group set */
00481         init_groupset();
00482 
00483         /* initialize the null string */
00484         Nnull_string = make_string("", 0);
00485         Nnull_string->numbr = 0.0;
00486         Nnull_string->type = Node_val;
00487         Nnull_string->flags = (PERM|STRCUR|STRING|NUMCUR|NUMBER);
00488 
00489         /*
00490          * Tell the regex routines how they should work.
00491          * Do this before initializing variables, since
00492          * they could want to do a regexp compile.
00493          */
00494         resetup();
00495 
00496         /* Set up the special variables */
00497         init_vars();
00498 
00499         /* Set up the field variables */
00500         init_fields();
00501 
00502         /* Now process the pre-assignments */
00503         for (i = 0; i <= numassigns; i++)
00504                 if (preassigns[i].stype == PRE_ASSIGN)
00505                         (void) arg_assign(preassigns[i].val, TRUE);
00506                 else    /* PRE_ASSIGN_FS */
00507                         cmdline_fs(preassigns[i].val);
00508         free(preassigns);
00509 
00510         if ((BINMODE & 1) != 0)
00511                 if (os_setbinmode(fileno(stdin), O_BINARY) == -1)
00512                         fatal(_("can't set binary mode on stdin (%s)"), strerror(errno));
00513         if ((BINMODE & 2) != 0) {
00514                 if (os_setbinmode(fileno(stdout), O_BINARY) == -1)
00515                         fatal(_("can't set binary mode on stdout (%s)"), strerror(errno));
00516                 if (os_setbinmode(fileno(stderr), O_BINARY) == -1)
00517                         fatal(_("can't set binary mode on stderr (%s)"), strerror(errno));
00518         }
00519 
00520 #ifdef GAWKDEBUG
00521         setbuf(stdout, (char *) NULL);  /* make debugging easier */
00522 #endif
00523         if (isatty(fileno(stdout)))
00524                 output_is_tty = TRUE;
00525         /* No -f or --source options, use next arg */
00526         if (numfiles == -1) {
00527                 if (optind > argc - 1 || stopped_early) /* no args left or no program */
00528                         usage(1, stderr);
00529                 srcfiles_add(CMDLINE, argv[optind]);
00530                 optind++;
00531         }
00532 
00533         init_args(optind, argc, (char *) myname, argv);
00534         (void) tokexpand();
00535 
00536         /* Read in the program */
00537         if (yyparse() != 0 || errcount != 0)
00538                 exit(1);
00539 
00540         free(srcfiles);
00541 
00542         if (do_intl)
00543                 exit(0);
00544 
00545         if (do_lint && begin_block == NULL && expression_value == NULL
00546              && end_block == NULL)
00547                 lintwarn(_("no program text at all!"));
00548 
00549         if (do_lint)
00550                 shadow_funcs();
00551 
00552         init_profiling_signals();
00553 
00554 #if defined(LC_NUMERIC)
00555         /* See comment above. */
00556         setlocale(LC_NUMERIC, "");
00557 #endif
00558 
00559         /* Whew. Finally, run the program. */
00560         if (begin_block != NULL) {
00561                 in_begin_rule = TRUE;
00562                 (void) interpret(begin_block);
00563         }
00564         in_begin_rule = FALSE;
00565         if (! exiting && (expression_value != NULL || end_block != NULL))
00566                 do_input();
00567         if (end_block != NULL) {
00568                 in_end_rule = TRUE;
00569                 (void) interpret(end_block);
00570         }
00571         in_end_rule = FALSE;
00572         if (close_io() != 0 && exit_val == 0)
00573                 exit_val = 1;
00574 
00575         if (do_profiling) {
00576                 dump_prog(begin_block, expression_value, end_block);
00577                 dump_funcs();
00578         }
00579 
00580         if (do_dump_vars)
00581                 dump_vars(varfile);
00582 
00583         if (do_tidy_mem)
00584                 release_all_vars();
00585 
00586         exit(exit_val);         /* more portable */
00587         return exit_val;        /* to suppress warnings */
00588 }

static void nostalgia  )  [static]
 

Definition at line 1030 of file main.c.

Referenced by main().

01031 {
01032         /*
01033          * N.B.: This string is not gettextized, on purpose.
01034          * So there.
01035          */
01036         fprintf(stderr, "awk: bailing out near line 1\n");
01037         fflush(stderr);
01038         abort();
01039 }

static void usage P (int exitval, FILE *fp)   )  [static]
 

Definition at line 47 of file main.c.

References do_intervals, do_intl, do_lint_old, do_non_decimal_data, do_posix, do_traditional, no_argument, optional_argument, and required_argument.

00080                                                   : gets NULL CONVFMT
00081  * Fun, fun, fun, fun.
00082  */
00083 char *CONVFMT = "%.6g";
00084 
00085 
00086 int errcount = 0;               /* error counter, used by yyerror() */
00087 
00088 NODE *Nnull_string;             /* The global null string */
00089 
00090 /* The name the program was invoked under, for error messages */
00091 const char *myname;
00092 
00093 /* A block of AWK code to be run before running the program */
00094 NODE *begin_block = NULL;
00095 
00096 /* A block of AWK code to be run after the last input file */
00097 NODE *end_block = NULL;
00098 
00099 int exiting = FALSE;            /* Was an "exit" statement executed? */
00100 int exit_val = 0;               /* optional exit value */
00101 
00102 #if defined(YYDEBUG) || defined(GAWKDEBUG)
00103 extern int yydebug;
00104 #endif
00105 
00106 struct src *srcfiles = NULL;    /* source file name(s) */
00107 long numfiles = -1;             /* how many source files */
00108 static long allocfiles;         /* for how many is *srcfiles allocated */
00109 
00110 #define srcfiles_add(stype, val) \
00111         add_src(&srcfiles, &numfiles, &allocfiles, stype, val)
00112 
00113 static struct src *preassigns = NULL;   /* requested via -v or -F */
00114 static long numassigns = -1;            /* how many of them */
00115 static long allocassigns;               /* for how many is allocated */
00116 
00117 #define preassigns_add(stype, val) \
00118         add_src(&preassigns, &numassigns, &allocassigns, stype, val)
00119 
00120 #undef do_lint
00121 #undef do_lint_old
00122 
00123 int do_traditional =