option.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1984-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Glenn Fowler
* AT&T Research
*
* make options support
*
* option name mappings are here
* option flag mappings are in options.h
*/
#include "make.h"
#include "options.h"
#define OPT_OFFSET 10
#define OPT_NON '-'
#define OPT_SEP ';'
static const char usage1[] =
"+"
"[-?%s\n]"
"[+NAME?nmake - configure, manage and update file hierarchies]"
"[+DESCRIPTION?\bnmake\b reads input \amakefiles\a and triggers shell"
" actions to build target files that are out of date with prerequisite"
" files. Most information used to build targets is contained in"
" the global \abase rules\a that are augmented by user \amakefiles\a."
" Each operand may be an option, script, or target. An option operand"
" is preceded by \b-\b or \b+\b. A script operand contains at least"
" one of \bspace\b, \btab\b, \bnewline\b, \b:\b, \b=\b, \b\"\b, or"
" \b\\\b and is parsed as a separate, complete makefile. Otherwise"
" the operand is a \atarget\a that is generated according to the"
" \amakefile\a and \aglobal\a rules. \atarget\a operands are made"
" in order from left to right and override the default targets.]"
"[+?Command line options, scripts and targets may appear in any order,"
" with the exception that no option operand may appear after a"
" \b--\b operand.]"
"[+?Options are qualified by the base name of the makefile that defined"
" them. Unqualified options are defined by \bnmake\b itself.]"
;
{
"Accept filesystem timestamps of existing targets." },
"Enable directory aliasing." },
"Compile base or global rules." },
"Believe the state file time of files lower than view level"
" \alevel-1\a. The file system time will be checked for files with"
" no state or files in views equal to or higher than \alevel\a."
" \alevel=0\a causes the file system time to be checked for"
" files on all view levels. The top view is level 0.", "level:=0" },
"Disable compatibility messages." },
"Compile the input makefile and exit." },
"\aaction\a determines the action to take for corrupt or invalid"
" top view state files. The top view default is \berror\b and the"
" lower view default is \baccept\b. \aaction\a may be one of:",
"[action:!accept]"
"{"
" [+accept?print a warning and set \b--accept\b]"
" [+error?print a diagnostic and exit]"
" [+ignore?print a warning and set \b--noreadstate\b]"
"}" },
"Don't run generated executables." },
{ "debug", OPT_debug, 0, 0,
"Set the debug trace level to \alevel\a. Higher levels produce"
" more output.", "level" },
"Add \aid\a to the error message command identifier.", "id:=make" },
"Enable shell action execution. \b--noexec\b"
" disables all but \b.ALWAYS\b shell actions and also disables"
" make object and state file generation/updates." },
"Expand \a3d\a filesystem paths." },
"Explain each action." },
"Read the makefile \afile\a. If \b--file\b is not specified then"
" the makefile names specified by \b$(MAKEFILES)\b are attempted in"
" order from left to right. The file \b-\b is equivalent"
"Force all targets to be out of date." },
"Read the global makefile \afile\a. The \b--file\b search is not"
" affected.", "file" },
"Ignore shell action errors." },
"Ignore state file locks." },
{ "include", OPT_include, 0, 0,
"Add \adirectory\a to the makefile search list.", "directory" },
"Force intermediate target generation." },
"Set the shell action concurrency level to \alevel\a."
" Level \b1\b allows dependency checking while an action is"
" executing; level \b0\b stops all activity while an action"
"Continue after error with sibling prerequisites." },
"List the current rules and variables on the standard output in"
" makefile form." },
"Write \amake abstract machine\a output to \afile\a if specified or"
" to the standard output otherwise. See \bmam\b(5) for details on"
" the \amake abstract machine\a language. If \aparent\a !=0 then it is"
" the process id of a parent \amam\a process. \adirectory\a is"
" the working directory of the current \amam\a process relative"
" to the root \amam\a process, \b.\b if not specified. \atype\a"
" must be one of:",
"[type[,subtype]][::file[::parent[::directory]]]]]]]"
"{"
"[+dynamic?\amam\a trace of an actual build]"
"[+regress?\amam\a for regression testing; labels, path"
" names and time stamps are canonicalized for easy comparison]"
"[+static?\amam\a representation of the makefile assertions;"
" used for makefile conversion]"
"[+----?0 or more comma separated subtypes ----]"
"[+port?used by the base rules to generate portable"
" makefiles; some paths are parameterized; on by default]"
"[+----?mam options ----]"
"[+[no]]hold?\bhold\b \amam\a output until nested \bnohold\b]"
"}" },
"Don't execute any shell actions. \b--noexec\b executes \b.ALWAYS\b"
" shell actions." },
{ "option", OPT_option, 0, 0,
"Define a new option. The definition is a delimiter separated field"
" list. Any non-alpha-numeric delimiter other than \b-\b may be used."
" \b;\b is used in this description. Makefile \bset option\b"
" definitions must be '...' quoted. Two adjacent delimiters specifies"
" the literal delimiter character and a \b-\b field value specifies an"
" empty field. \achar\a is the single character option name, \aname\a"
" is the long option name, \aset\a is an optional \b.FUNCTION\b that"
" is called when the option value is changed by \bset\b, \avalues\a is"
" an \boptget\b(3) value list, and \aflags\a are a combination of:",
"['char;name;flags;set;description;values']"
"{"
" [+a?multiple values appended]"
" [+b?boolean value]"
" [+i?internal value inverted]"
" [+n?numeric value]"
" [+o?\a-char\a means \b--no\b\aname\a]"
" [+p?.mo probe prerequisite]"
" [+s?string value]"
" [+v?optional option argument]"
" [+x?not expanded in \b$(-)\b]"
"}" },
"Implicit rules or metarules override explicit rules." },
"Enable questionable features defined by \amask\a. Questionable"
" features are artifacts of previous implementations (\bnmake\b has"
" been around since 1984-11-01) that will eventually be dropped."
" The questionable \amask\a registry is in the \bmain.c\b \bnmake\b"
" source file.", "mask" },
"Current assignments and assertions will be marked \breadonly\b." },
"Ignore state files lower than view level \alevel\a. \alevel=0\a"
" ignores state files on all view levels. The top view is level 0.",
"level:=0" },
"Massage output for regression testing. \aaction\a may be one of:",
"[action:!message]"
"{"
" [+message?alter messages only]"
" [+sync?sync 1-second clocks if necessary and alter messages]"
"}" },
"Ignore any previously generated \b.mo\b files and re-read all"
" input makefiles." },
"Dump rule information in tabular form on the standard"
" error when \bnmake\b exits." },
"Serialize concurrent output by caching job stdout and stderr"
" output until job completion." },
"Do not trace shell actions as they are executed." },
"Set \bVPATH\b \b.SOURCE\b rule interpretation to follow strict"
" \a3d\a filesystem semantics, where directories in the top views"
" take precedence. On by default when running in \a2d\a with"
" \bVPATH\b defined, off by default otherwise." },
"Expand and execute shell actions in the target directory context."
" This allows a single makefile to control a directory tree while"
" generating target files at the source file directory level. By"
" default target files are generated in the current directory." },
"Allow metarules to match \aseparator\a in the target to \b/\b"
" in the source. Used to disambiguate source file base name clashes"
" when target files are generated in the current directory."
" \aseparator\a must not contain metarule or shell pattern characters.",
"separator" },
"Enable test code defined by \amask\a. Test code is implementation"
" specific. The test \amask\a registry is in the \bmain.c\b \bnmake\b"
" source file.", "mask" },
"Set the time comparison tolerance to \aseconds\a. Times within"
" the tolerance range compare equal. Useful on systems that can't"
" quite get the file system and local clocks in sync. A tolerance"
" of more that 5 seconds soon becomes intolerable.", "seconds" },
"Touch the time stamps of out of date targets rather than execute"
" the shell action." },
"Dump variable information in tabular form on the standard"
" error when \bnmake\b exits." },
"Enable verbose warning messages." },
"Generate a \b.mo\b make object file in \afile\a that can be read"
" instead of the input makefiles on the next \bnmake\b invocation."
" On by default. \b--nowriteobject\b prevents the generation."
" The default name is used if \afile\a is omitted or \b-\b."
" If \afile\a is a directory then the default is placed in that"
" directory.",
"file:=$(MAKEFILE::B::S=.mo)" },
"Generate a \b.ms\b make state file in \afile\a when \bnmake\b exits."
"The state contains the time stamps of all prerequisites and targets"
" that have been accessed since the state file was first generated."
" On by default. \b--nowritestate\b prevents the generation."
" The default name is used if \afile\a is omitted or \b-\b."
" If \afile\a is a directory then the default is placed in that"
" directory.",
"file:=$(MAKEFILE::B::S=.ms)" },
{ "byname", OPT_byname, 0, 0,
"(obsolete) Set options by name.", "name[=value]]" },
{ "define", OPT_define, 0, 0,
"(obsolete) Pass macro definition to the makefile preprocessor.",
"name[=value]]" },
{ "preprocess", OPT_preprocess, 0, 0,
"(obsolete) Preprocess all makefiles." },
{ "undef", OPT_undef, 0, 0,
"(obsolete) Pass macro deletion to the makefile preprocessor.",
"name" },
};
static const char usage2[] =
"\n"
"[ script ... ] [ target ... ]\n"
"\n"
"[+DIAGNOSTICS?Diagnostic messages are printed on the standard error and are"
" classified by levels. The level determines if the diagnostic"
" is printed, if it causes \bnmake\b to exit, and if it affects"
" the \bnmake\b exit status. The levels are:]{"
" [+<0?Debug message, enabled when the absolute value of"
" \alevel\a is greater than or equal to the"
" \b--debug\b level. Debug diagnostics are prefixed"
" by \bdebug\b-\alevel\a\b:\b.]"
" [+1?Warning message, disabled by \b--silent\b. Warning"
" diagnostics are prefixed by \bwarning\a\b:\b]"
" [+2?Non-fatal error message. Processing continues after"
" the diagnostic, but the eventual \bnmake\b exit"
" status will be non-zero.]"
" [+>2?Fatal error message. \bnmake\b exits after the"
" diagnostic (and internal cleanup) with exit"
" status \alevel\a-2.]"
"}"
"[+SEE ALSO?\b3d\b(1), \bar\b(1), \bcc\b(1), \bcoshell\b(1), \bcpp\b(1),"
" \bprobe\b(1), \bsh\b(1)]"
;
struct Oplist_s /* linked option list */
{
char* option; /* option value for set() */
};
typedef struct Optstate_s /* option state */
{
int usageindex; /* next user index */
} Optstate_t;
static Optstate_t opt;
static Option_t*
{
register int c;
{
while (c = *name++)
if (c != '-' && c != '_')
}
return op;
}
static void
{
register char* s;
register int c;
char buf[16];
{
while (c = *s++)
if (c != '-' && c != '_')
}
else
{
buf[0] = '-';
buf[2] = 0;
}
{
}
}
/*
* initialize the option hash table
*/
void
optinit(void)
{
register int i;
for (i = 0; i < elementsof(options); i++)
{
{
break;
}
else
}
}
/*
* return option table entry given OPT_[a-z]+ flag
* type==0 panics if not in table
*/
{
char buf[8];
else
{
buf[0] = '-';
buf[2] = 0;
}
return op;
}
/*
* call op->set with new value
*/
static void
{
Rule_t* r;
char* oset;
int oreadonly;
char buf[16];
{
{
case Ob:
break;
case On:
break;
case Os:
break;
}
}
}
/*
* copy a declare() string entry s to sp
*/
static void
{
register int c;
if (s && *s)
while (c = *s++)
{
if (c == OPT_SEP)
}
else
}
/*
* generate external option declaration
*/
static void
{
}
/*
* generate optget() usage for op
*/
static void
{
long pos;
if (op)
{
{
}
{
else
}
}
if (last)
else
}
/*
* mam output discipline to parameterize local paths
*/
static ssize_t
{
char* s;
size_t z;
static char* tmp;
static int siz;
z = n;
{
if (n >= siz)
{
}
tmp[n-1] = 0;
{
z = strlen(s);
if (z >= siz)
{
}
tmp[z++] = '\n';
}
}
}
/*
* make sure the current time is > the start time
* to differentiate strtime() "recent" vs. "current"
* if the clock or filesystem doesn't support subsecond
* granularity then we sleep until the next integral
* second ticks off
*
* the filesystem checks assume that file time stamp
* subseconds==0 rarely happens by chance -- the penalty
* for a wrong guess is slightly slower but still correct
* regression tests
*
* this also assumes that regression tests run faster than
* the disk inode flush frequency on systems where the
* cache time resolution is higher than the disk
*/
static void
regressinit(const char* type)
{
Time_t t;
int i;
error_info.version = 0;
if (*type == 's')
{
t = CURTIME;
tmsleep(0L, 100000000L);
if (!i)
}
}
/*
* return option name and details
*/
static char*
{
}
/*
* return next option definition field
*/
static char*
{
register char* s;
register char* t;
char* v;
register int c;
if (!(c = *(s = *p)) || c == app)
return 0;
if (c == sep)
{
*p = s + 1;
return 0;
}
v = t = s;
for (;;)
{
if (!(c = *t++ = *s++))
{
s--;
t--;
break;
}
else if (c == sep)
{
if (lenient || !*s)
{
t--;
s--;
break;
}
{
t--;
s++;
break;
}
if (*s != c)
{
t--;
s--;
break;
}
s++;
}
}
if (*s)
s++;
*p = s;
if (*t)
*t = 0;
return 0;
return v;
}
/*
* set an option given its pointer
*/
static void
{
char* t;
Rule_t* r;
int readonly;
{
return;
if (readonly)
{
Oplist_t* x;
/*
* save for listops(*,'@')
*/
if (!s)
else if (!strchr(s, '\''))
else
if (opt.lasthidden)
else
return;
}
}
if (type != ':')
{
}
{
}
{
n = -n;
else
n = !n;
}
n = n != 0;
if (!n)
s = 0;
{
case OPT(OPT_believe):
else
return;
case OPT(OPT_byname):
if (s)
return;
case OPT(OPT_corrupt):
if (!s)
s = "-";
;
;
else
{
}
return;
case OPT(OPT_global):
if (!s)
{
if (n)
{
}
{
}
return;
}
break;
case OPT(OPT_include):
break;
/*FALLTHROUGH*/
case OPT(OPT_define):
if (s)
{
}
return;
case OPT(OPT_preprocess):
if (!state.preprocess)
{
if (!state.compatibility)
}
return;
case OPT(OPT_errorid):
if (s && *s)
{
}
else
{
}
return;
if (n >= MAXJOBS)
n = MAXJOBS - 1;
if (n < 1)
n = 0;
return;
if (t = s)
{
if (t[0] == 'n' && t[1] == 'o')
t += 2;
if (streq(t, "hold"))
{
if (t == s)
else
return;
}
}
{
}
{
}
{
}
{
}
state.mam.dontcare = state.mam.dynamic = state.mam.regress = state.mam.statix = state.mam.parent = 0;
if (s)
{
char* o;
char* u;
if (t = strchr(s, ':'))
*t++ = 0;
if (o = strchr(s, ','))
*o++ = 0;
{
}
else
while (s = o)
{
if (o = strchr(s, ','))
*o++ = 0;
if (*s == 'n' && *(s + 1) == 'o')
{
s += 2;
n = 0;
}
else
n = 1;
else
}
if (t)
{
s = t;
if (t = strchr(s, ':'))
{
*t++ = 0;
if (isdigit(*t))
{
while (isdigit(*t))
{
}
}
if (*t)
{
if (*t != ':')
t++;
}
if (!*t)
t = 0;
}
}
else s = null;
{
}
if (*s != '/')
if (t)
{
}
}
return;
case OPT(OPT_option):
s = strdup(s);
while (*s)
{
char* name;
char* func;
char* desc;
char* args;
int app;
int sep;
char buf[16];
sep = *s;
{
sep = *++s;
}
else
{
sep = *++s;
}
s++;
{
if (n & Of)
else
break;
}
{
for (;;)
{
switch (*t++)
{
case 0:
break;
case 'a':
n |= Oa;
continue;
case 'b':
n |= Ob;
continue;
case 'n':
n |= On;
continue;
case 'o':
n |= Oo;
continue;
case 'p':
n |= Op;
continue;
case 's':
n |= Os;
continue;
case 'v':
n |= Ov;
continue;
case 'x':
n |= Ox;
continue;
/* no complaints here for future extensions */
}
break;
}
}
if (!(n & Of))
{
break;
{
return;
}
buf[0] = '-';
buf[2] = 0;
}
else
nop = 0;
if (nop)
{
if (n & On)
else if (n & Os)
if (!desc)
desc = "option.";
if (*desc != '(')
{
if ((t = parsefile()) && *t)
else
}
{
}
readonly = 1;
}
{
else
goto set_insert;
}
else
{
{
{
if (n & Os)
}
}
error(1, "--%s: option is %s", nop->name, (nop->flags & Ob) ? "boolean" : (nop->flags & On) ? "numeric" : "string valued");
}
/*
* skip the remaining fields for future extensions
* and consume the append char if specified
*/
if (*s == app)
s++;
}
optcheck(0);
return;
return;
case OPT(OPT_regress):
if (n)
{
if (!s)
s = "-";
;
;
else
{
}
}
else
return;
case OPT(OPT_reread):
return;
case OPT(OPT_silent):
{
if (!error_info.trace)
}
else
if (error_info.trace > 0)
error_info.trace = 0;
return;
case OPT(OPT_targetprefix):
if (!n)
s = 0;
else if (s)
s = strdup(s);
if (state.targetprefix = s)
for (;;)
{
switch (*s++)
{
case 0:
break;
case '%':
case '*':
case '?':
case '&':
case '"':
case '\'':
case '\\':
error(3, "--%s: %s: value must not contain metarule or shell pattern characters", op->name, state.targetprefix);
break;
default:
continue;
}
break;
}
return;
case OPT(OPT_tolerance):
return;
case OPT(OPT_writeobject):
if (!n)
s = 0;
{
return;
}
else if (!s)
s = "-";
else
s = strdup(s);
state.writeobject = s;
return;
case OPT(OPT_writestate):
if (!n)
s = 0;
else if (!s)
s = "-";
else
s = strdup(s);
state.writestate = s;
{
}
return;
}
{
{
switch (type)
{
case '^':
break;
default:
break;
}
}
{
switch (type)
{
case '+':
break;
case '-':
break;
case '|':
break;
case '&':
break;
case '^':
break;
default:
break;
}
}
{
{
if (s)
{
/*
* s is a ':' list
*/
for (;;)
{
if (t = strchr(s, ':'))
*t = 0;
if (!t)
break;
*t++ = ':';
s = t;
}
}
else
{
}
}
else
}
}
{
{
}
{
if (!n)
else if (n != 1)
else
}
}
}
/*
* generate a single option setting in sp given the option pointer
* setting:
* 0 only the value is generated, "" if option not set
* '+' only the value is generated, "" if Os option not set, 0 for Ob|Oi not set
* '-' option name and value suitable for set()
* '?' 1 if OPT_SET, "" otherwise
* '#' table attributes with the current value
* flag!=0 if relative to option flag rather than option name
*/
static void
{
register long n;
char* v;
List_t* p;
switch (setting)
{
case '?':
return;
case '#':
break;
case 0:
break;
default:
break;
}
{
case Ob:
else
n = 0;
n = !n;
n = !n;
switch (setting)
{
case 0:
if (!n)
return;
/*FALLTHROUGH*/
case '+':
case '#':
break;
default:
else if (n)
{
return;
}
else
{
return;
}
break;
}
break;
case On:
else
n = 0;
n = -n;
n = !n;
switch (setting)
{
case 0:
if (!n)
return;
/*FALLTHROUGH*/
case '+':
case '#':
break;
default:
else if (n)
else
{
return;
}
break;
}
break;
case Os:
{
switch (setting)
{
case 0:
if (!p)
return;
/*FALLTHROUGH*/
case '+':
case '#':
break;
default:
else if (p)
else
{
return;
}
break;
}
if (p)
for (;;)
{
if (!(p = p->next))
break;
}
}
else
{
else
v = 0;
switch (setting)
{
case 0:
case '#':
if (!v)
return;
setting = 0;
break;
case '+':
break;
default:
else if (v)
else
{
return;
}
break;
}
if (v)
{
if (setting)
else
}
}
break;
#if DEBUG
default:
error(PANIC, "%s: option has%s%s%s", op->name, (op->flags & Ob) ? " Ob" : null, (op->flags & On) ? " On" : null, (op->flags & Os) ? " Os" : null);
break;
#endif
}
}
/*
* check and set delayed options
* this gives base, global and local makefiles a chance to
* define the options via --option=definition
*/
void
{
Oplist_t* x;
int errors;
if (must)
{
{
if (*x->option)
free(x);
}
finish(2);
}
else
*x->option = 0;
}
/*
* generate option setting list in sp suitable for set()
* setting:
* 0 non-Ox OPT_SET options
* '+' non-Om non-Ox OPT_SET options
* '-' all
* '?' non-Ox OPT_DEFAULT
* '#' table attributes with the current value
* '@' internal object file dump
*/
void
{
register Oplist_t* x;
int sc;
int sep;
long mask;
long test;
long clear;
sep = 0;
sc = ' ';
clear = 0;
switch (setting)
{
case '-':
mask = 0;
test = 0;
break;
case '+':
setting = '-';
break;
case '?':
setting = '-';
test = OPT_DEFAULT;
break;
case '#':
sc = '\n';
mask = 0;
test = 0;
break;
case '@':
setting = '-';
test = OPT_COMPILE;
clear = ~OPT_COMPILE;
{
if (sep)
else
{
sep = 1;
}
}
{
if (sep)
else
sep = 1;
free(x);
}
break;
default:
setting = '-';
break;
}
{
if (sep)
else
sep = 1;
if (clear)
}
}
/*
* generate a single option setting in sp given the option name
* setting passed to genop()
* end of s is returned
*/
void
{
int flag;
if ((op = getoption(name)) && !(flag = 0) || name[0] == 'n' && name[1] == 'o' && (op = getoption(&name[2])) && (flag = Oi) || name[0] && !name[1] && (op = optflag(name[0])) && (flag = Of))
}
/*
* set an option by its optget()/optstr() index
*/
static void
{
register char* s;
int n;
Oplist_t* x;
char buf[16];
if (i > 0)
{
{
{
while (*v && *v != '=')
if (*v)
{
if (!strchr(v, '\"'))
else
}
}
else
n = strlen(v);
if (opt.lastdelayed)
else
}
else
error((i == '?' && opt_info.option[0] == '-' && opt_info.option[1] != '?') ? (ERROR_USAGE|(state.interpreter ? 2 : 4)) : 2, "%s", opt_info.arg);
}
else
{
else
{
}
n = (op->flags & On) ? (opt_info.arg ? opt_info.num : 0) : (op->flags & Ob) ? (opt_info.num != 0) : (opt_info.num != 0) == !(op->flags & Oi);
n = !n;
s = 0;
if (scope)
}
}
/*
* set options by name
*/
int
{
register int i;
int r;
int oreadonly;
r = 0;
{
if (i > 0 && !must)
{
r = -1;
break;
}
if (!must)
{
}
if (!must)
}
return r;
}
/*
* set command line options with optget(3)
* options may appear in any position before --
* read command line assignments
* mark the command line scripts and targets
* index of the first command line script or target is returned
*/
int
{
register int i;
register char* s;
register int c;
int args;
int done;
char* e;
/*
* generate the optget() usage string from options[]
*/
for (i = 0; i < elementsof(options); i++)
opt.usageindex = i;
args = 0;
done = 0;
done = 1;
{
s = argv[i];
while (isspace(*s))
s++;
{
goto again;
}
if (*s)
{
for (e = s; c = *s; s++)
if (c == ',')
{
s = null;
break;
}
{
while (isspace(*s))
s++;
if (*s == '=' || *(s + 1) == '=')
{
argf[i] |= ARG_ASSIGN;
}
else
{
argf[i] |= ARG_SCRIPT;
if (!args)
args = i;
}
break;
}
if (!*s)
{
argf[i] |= ARG_TARGET;
if (!args)
args = i;
}
}
}
}
/*
* please reboot your program to finish setup ...
*
* old!=0 execs external.old for backwards compatibility
* otherwise re-exec forcing input files to be read
*/
void
{
register char* s;
register char** av;
int i;
List_t* p;
Oplist_t* x;
if (old)
{
/*
* this chunk must track external.old options
*/
/*
* options with same flag and meaning
*/
/*
* options with different flag but same meaning
*/
/*
* options with different flag and meaning
* the external.old meaning prevails
*/
if (s[1])
/*
* mam arguments -- assume oldmake knows mam
*/
{
}
/*
* delayed (unknown) options
*/
/*
* makefile arguments
*/
{
}
else for (; p; p = p->next)
{
}
/*
* variable assignment arguments
*/
{
/*
* echo the exec action external.old style
*/
#endif
while (*av)
}
}
else
{
/*
* copy the original argv adding OPT_reread
* and possibly OPT_preprocess
*/
if (state.preprocess)
}
/*
* tidy up
*/
/*
* start fresh
*/
}
/*
* return 1 if name is an option
*/
int
{
}