optget.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
7abd0c58a5ce51db13f93de82407b2188d55d298Christian Maeder/***********************************************************************
7abd0c58a5ce51db13f93de82407b2188d55d298Christian Maeder* This software is part of the ast package *
75a6279dbae159d018ef812185416cf6df386c10Till Mossakowski* Copyright (c) 1985-2012 AT&T Intellectual Property *
c00adad2e9459b422dee09e3a2bddba66b433bb7Christian Maeder* and is licensed under the *
7abd0c58a5ce51db13f93de82407b2188d55d298Christian Maeder* Eclipse Public License, Version 1.0 *
7abd0c58a5ce51db13f93de82407b2188d55d298Christian Maeder* by AT&T Intellectual Property *
7abd0c58a5ce51db13f93de82407b2188d55d298Christian Maeder* A copy of the License is available at *
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maeder* http://www.eclipse.org/org/documents/epl-v10.html *
c00adad2e9459b422dee09e3a2bddba66b433bb7Christian Maeder* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
e8ffec0fa3d3061061bdc16e44247b9cf96b050fChristian Maeder* Information and Software Systems Research *
c00adad2e9459b422dee09e3a2bddba66b433bb7Christian Maeder* AT&T Research *
e8ffec0fa3d3061061bdc16e44247b9cf96b050fChristian Maeder* Florham Park NJ *
e8ffec0fa3d3061061bdc16e44247b9cf96b050fChristian Maeder* Glenn Fowler <gsf@research.att.com> *
8197d0be8b81692f311ad5ca34e125e2cf9eecb8Christian Maeder* David Korn <dgk@research.att.com> *
f71a8dcf94fd9eb3c9800e16dcdc5e5ff74e5c22Christian Maeder* Phong Vo <kpv@research.att.com> *
8197d0be8b81692f311ad5ca34e125e2cf9eecb8Christian Maeder***********************************************************************/
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maeder * Glenn Fowler
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maeder * AT&T Research
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maeder * command line option parser and usage formatter
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maeder * its a monster but its all in one place
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder * widen your window while you're at it
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder#define OMIT "*@(\\[[-+]*\\?*\\]|\\@\\(#\\)|Copyright \\(c\\)|\\$\\I\\d\\: )*"
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder#define OPT_WIDTH 80 /* default help text width */
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder#define OPT_MARGIN 10 /* default help text margin */
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder#define OPT_USAGE 7 /* usage continuation indent */
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder#define OPT_flag 0x001 /* flag ( 0 or 1 ) */
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder#define OPT_hidden 0x002 /* remaining are hidden */
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder#define OPT_ignorecase 0x004 /* arg match ignores case */
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder#define OPT_invert 0x008 /* flag inverts long sense */
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder#define OPT_listof 0x010 /* arg is ' ' or ',' list */
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder#define OPT_number 0x020 /* arg is strtonll() number */
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder#define OPT_oneof 0x040 /* arg may be set once */
e289294500ad68fa0706b09521af340bbb356a69Christian Maeder#define OPT_optional 0x080 /* arg is optional */
e289294500ad68fa0706b09521af340bbb356a69Christian Maeder#define OPT_string 0x100 /* arg is string */
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder#define OPT_preformat 0001 /* output preformat string */
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder#define OPT_proprietary 0002 /* proprietary docs */
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder#define OPT_TYPE (OPT_flag|OPT_number|OPT_string)
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder#define STYLE_posix 0 /* posix getopt usage */
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder#define STYLE_short 1 /* [default] short usage */
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder#define STYLE_match 3 /* long description of matches */
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder#define STYLE_options 4 /* short and long descriptions */
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder#define STYLE_keys 9 /* translation key strings */
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder#define STYLE_usage 10 /* escaped usage string */
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder const char* match; /* builtin help match name */
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder const char* text; /* default message text */
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder 0,2, 4,10, 12,18, 20,26, 28,34, 36,42, 44,50, 0,0
9b3bf7c6cf82dc11478bbac3414fe657b9bca327Christian Maederstatic const char* end[] =
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maederstatic const char term_off[] = {CC_esc,'[','0','m',0};
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maederstatic const char term_B_on[] = {CC_esc,'[','1','m',0};
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maederstatic const char term_I_on[] = {CC_esc,'[','1',';','4','m',0};
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder "</B>", "<B>", "\\fP", "\\fB", &term_off[0], &term_B_on[0],
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder "</I>", "<I>", "\\fP", "\\fI", &term_off[0], &term_I_on[0],
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder#define D(s) (state.msgdict && dtmatch(state.msgdict, (s)))
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder#define T(i,c,m) (X(c)?translate(i,c,C(m)):(m))
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder#define X(c) (ERROR_translating()&&(c)!=native)
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder#define Z(x) C(x),sizeof(x)-1
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder * translate with C_LC_MESSAGES_libast[] check
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maedertranslate(const char* cmd, const char* cat, const char* msg)
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder return (char*)msg;
3a9dafc31d54a6bdac1acda72bb15aceffb0240fChristian Maeder#define C(s) s
3a9dafc31d54a6bdac1acda72bb15aceffb0240fChristian Maeder#define D(s) (state.msgdict && dtmatch(state.msgdict, (s)))
3a9dafc31d54a6bdac1acda72bb15aceffb0240fChristian Maeder#define T(i,c,m) m
3a9dafc31d54a6bdac1acda72bb15aceffb0240fChristian Maeder#define X(c) 0
3a9dafc31d54a6bdac1acda72bb15aceffb0240fChristian Maeder#define Z(x) C(x),sizeof(x)-1
3a9dafc31d54a6bdac1acda72bb15aceffb0240fChristian Maeder C("options available to all \bast\b commands"),
3a9dafc31d54a6bdac1acda72bb15aceffb0240fChristian Maeder C("\b-?\b and \b--?\b* options are the same \
3a9dafc31d54a6bdac1acda72bb15aceffb0240fChristian Maederfor all \bast\b commands. For any \aitem\a below, if \b--\b\aitem\a is not \
3a9dafc31d54a6bdac1acda72bb15aceffb0240fChristian Maedersupported by a given command then it is equivalent to \b--\?\?\b\aitem\a. The \
3a9dafc31d54a6bdac1acda72bb15aceffb0240fChristian Maeder\b--\?\?\b form should be used for portability. All output is written to the \
3a9dafc31d54a6bdac1acda72bb15aceffb0240fChristian Maederstandard error."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder Z("List all implementation info."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder Z("List detailed info in program readable form."),
3a9dafc31d54a6bdac1acda72bb15aceffb0240fChristian Maeder Z("List detailed help option info."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder Z("List detailed info in html."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder Z("List the usage translation key strings with C style escapes."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder Z("List long option usage."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder Z("List detailed info in displayed man page form."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder Z("List detailed info in nroff."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder Z("List short and long option details."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder Z("List posix getopt usage."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder Z("List short option usage."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder Z("List the usage string with C style escapes."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder C("List implementation info matching \alabel\a*."),
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maeder C("Equivalent to \b--help=\b\aname\a."),
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maeder C("Equivalent to \b--\?\?options\b."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder C("Equivalent to \b--\?\?man\b."),
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder C("Equivalent to \b--\?\?help\b."),
0f67ca7b0c738a28f6688ba6e96d44d7c14af611Christian Maeder C("If the next argument is \b--\b\aoption\a then list \
0f67ca7b0c738a28f6688ba6e96d44d7c14af611Christian Maederthe \aoption\a output in the \aitem\a style. Otherwise print \
0f67ca7b0c738a28f6688ba6e96d44d7c14af611Christian Maeder\bversion=\b\an\a where \an\a>0 if \b--\?\?\b\aitem\a is supported, \b0\b \
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder C("Emit escape codes even if output is not a terminal."),
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder C("List the \bman\b(1) section title for \asection\a [the \
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maedercurrent command]]."),
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maeder C("List the \bman\b(1) section number for the current command."),
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maeder C("Massage the output for regression testing."),
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maederstatic const char unknown[] = C("unknown option or attribute");
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maederstatic const char* heading[] =
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder C("USER COMMANDS"),
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder C("SYSTEM LIBRARY"),
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder C("USER LIBRARY"),
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder C("FILE FORMATS"),
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder C("MISCELLANEOUS"),
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder C("GAMES and DEMOS"),
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder C("SPECIAL FILES"),
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder C("ADMINISTRATIVE COMMANDS"),
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder * list of common man page strings
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder * NOTE: add but do not delete from this table
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("APPLICATION USAGE") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("ASYNCHRONOUS EVENTS") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("BUGS") },
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder { C("CAVEATS") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("CONSEQUENCES OF ERRORS") },
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder { C("DESCRIPTION") },
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder { C("ENVIRONMENT VARIABLES") },
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder { C("EXAMPLES") },
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder { C("EXIT STATUS") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("EXTENDED DESCRIPTION") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("INPUT FILES") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("LIBRARY") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("NAME") },
dc4bfcb8a5092af158e8a5691c8de8d6bc8b8724Christian Maeder { C("OPERANDS") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("OPTIONS") },
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maeder { C("OUTPUT FILES") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("PLUGIN") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("SEE ALSO") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("STDERR") },
0f67ca7b0c738a28f6688ba6e96d44d7c14af611Christian Maeder { C("STDIN") },
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder { C("STDOUT") },
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder { C("SYNOPSIS") },
b49276c9f50038e0bd499ad49f7bd6444566a834Christian Maeder { C("author") },
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maeder { C("copyright") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("license") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("name") },
c1124c6303c288db3fcb40518d38169cd7baaa4cChristian Maeder { C("path") },
0f67ca7b0c738a28f6688ba6e96d44d7c14af611Christian Maeder { C("version") },
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder * 2007-03-19 move opt_info from _opt_info_ to (*_opt_data_)
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder * to allow future Opt_t growth
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder * by 2009 _opt_info_ can be static
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder#define extern extern __EXPORT__
d17834302eaa101395b4b806cd73670fd864445fChristian MaederOpt_t _opt_info_ = { 0,0,0,0,0,0,0,{0},{0},0,0,0,{0},{0},&state };
show(register char* s)
t = buf;
goto done;
done:
return buf;
typedef struct Section_s
const char* name;
} Section_t;
t = strcopy(t, s);
if (section[0] == sections[i].section[0] && (section[1] == sections[i].section[1] || !sections[i].section[1]))
s = section;
strcopy(t, s);
static Push_t*
skip(register char* s, register int t1, register int t2, register int t3, register int n, register int b, int past, int version)
register int on = n;
register int ob = b;
message((-22, "optget: skip t1=%c t2=%c t3=%c n=%d b=%d `%s'", t1 ? t1 : '@', t2 ? t2 : '@', t3 ? t3 : '@', n, b, show(s - 1)));
else if (c == GO)
else if (c == OG)
if (n == 0 && b-- == ob)
nest(register char* s)
char* xw;
char* ww;
if (catalog)
xw = x;
w = ww = s;
if (isupper(*x))
xw = x;
if (isupper(*w))
ww = w;
else if (SEP(*x))
xw = ++x;
else if (SEP(*w) && w != s)
ww = ++w;
if (x != xw)
if (SEP(*x))
xw = x;
while (w > ww && *w != *x)
const char* ep;
Save_t* p;
Dtdisc_t* d;
if (!dict)
return (char*)ap;
return (char*)ap;
b = buf;
if (bp)
if (cp)
return (char*)ap;
return p->text;
if (!(b = id))
else if (!opt_info.disc || !opt_info.disc->infof || (*opt_info.disc->infof)(&opt_info, ip, b, opt_info.disc) < 0)
initdict(void)
#if !_PACKAGE_astsa
for (n = 0, t = OPT_FLAGS; *t; t++)
map[*t] = ++n;
#if _BLD_DEBUG
p->oopts = s;
p->version = 0;
p->flags = 0;
p->catalog = 0;
s = next(s, 0);
s = next(s, 0);
if (!isdigit(*s))
while (isdigit(*s))
p->release = s;
if (isspace(*s++))
p->release = s;
else if (!isdigit(*s))
while (isdigit(*s))
p->prefix = n;
p->prefix = 0;
if (isupper(*s))
p->section[n++] = *s++;
if (isupper(*s))
p->section[n++] = *s++;
p->section[n] = 0;
while (isspace(*s))
if (strneq(s - 1, "+NAME?", 6) && (s += 5) || strneq(s - 1, "+LIBRARY?", 9) && (s += 8) && (l = 1) || strneq(s - 1, "+PLUGIN?", 8) && (s += 7) && (l = 1))
else if ((a = strlen(p->id)) <= (n = t - s) || strncmp(p->id + a - n, s, n) || *(p->id + a - n - 1) != ':')
if (s = p->catalog)
p->catalog = ((t = strchr(s, ']')) && (!p->id || (t - s) != strlen(p->id) || !strneq(s, p->id, t - s))) ? save(s, t - s, 0, 0, 0, 0) : (char*)0;
if (!p->catalog)
s = p->oopts;
s = next(s, 0);
if (!p->version && (t = strchr(s, '(')) && strchr(t, ')') && (state.cp || (state.cp = sfstropen())))
for (t = p->oopts; t < s; t++)
n = t - p->oopts;
p->opts = s;
message((-2, "version=%d prefix=%d section=%s flags=%04x id=%s catalog=%s oopts=%p", p->version, p->prefix, p->section, p->flags, p->id, p->catalog, p->oopts));
switch (style)
case STYLE_html:
case STYLE_nroff:
case STYLE_short:
case STYLE_long:
case STYLE_posix:
case STYLE_api:
static Push_t*
n = strlen(b);
return tsp;
static Push_t*
localize(Push_t* psp, char* s, char* e, int term, int n, Sfio_t* ip, int version, char* id, char* catalog)
if (term && *s == c)
n = strlen(u);
return tsp;
label(register Sfio_t* sp, int sep, register char* s, int about, int z, int level, int style, int f, Sfio_t* ip, int version, char* id, char* catalog)
int ostyle;
int va;
style = 0;
e = s + strlen(s);
if (sep > 0)
va = 0;
if (about)
va = 0;
if (f == FONT_ITALIC || f < 0)
if (f == FONT_BOLD || f < 0)
if (f == FONT_LITERAL || f < 0)
goto restore;
else if (sep)
goto restore;
goto restore;
goto restore;
a = FONT_ITALIC;
if (++t < e && isdigit(*t))
while (++t < e && isupper(*t));
a = FONT_BOLD;
goto setfont;
for (i = 0; i < level; i++)
a = FONT_LITERAL;
goto setfont;
if (about)
if (psp)
args(register Sfio_t* sp, register char* p, register int n, int flags, int style, Sfio_t* ip, int version, char* id, char* catalog)
int sep;
if (!(a = id))
sfprintf(sp, "\t%s%s%s%s[%s%s%s%s%s]", font(FONT_BOLD, style, 1), a, font(FONT_BOLD, style, 0), b, b, font(FONT_ITALIC, style, 1), o, font(FONT_ITALIC, style, 0), b);
sfprintf(sp, "%*.*s%s%s%s[%s%s%s]", OPT_USAGE - 1, OPT_USAGE - 1, T(NiL, ID, "Or:"), b, a, b, b, o, b);
if (X(catalog))
item(Sfio_t* sp, char* s, int about, int level, int style, Sfio_t* ip, int version, char* id, char* catalog, int* hflags)
int par;
par = 0;
for (n = 0; n < level; n++)
par = 0;
if (level)
for (n = 0; n < level; n++)
if (!level)
if (s[-1] == '-' && s[0] == 'l' && s[1] == 'i' && s[2] == 'c' && s[3] == 'e' && s[4] == 'n' && s[5] == 's' && s[6] == 'e' && s[7] == '?')
if (t[0] == 'p' && (!strncmp(t, "proprietary", 11) || !strncmp(t, "private", 7)) || t[0] == 'n' && !strncmp(t, "noncommercial", 13))
if (!level)
if (!level)
for (n = 0; n < level; n++)
return par;
#if _BLD_DEBUG
trace_textout(Sfio_t* sp, register char* p, char* conform, int conformlen, int style, int level, int bump, Sfio_t* ip, int version, char* id, char* catalog, int* hflags, int line)
static int depth = 0;
message((-21, "opthelp: txt#%d +++ %2d \"%s\" style=%d level=%d bump=%d", line, ++depth, show(p), style, level, bump));
textout(Sfio_t* sp, register char* s, char* conform, int conformlen, int style, int level, int bump, Sfio_t* ip, int version, char* id, char* catalog, int* hflags)
#if _BLD_DEBUG
#define textout(sp,s,conform,conformlen,style,level,bump,ip,version,id,catalog,hflags) trace_textout(sp,s,conform,conformlen,style,level,bump,ip,version,id,catalog,hflags,__LINE__)
int par;
int about;
about = 0;
if ((c = *s) == GO)
if (*s == GO)
level++;
level++;
else if (*s != OG)
if (level <= 1 || *s != '[' || *(s + 1) != '-' || style == STYLE_man && *(s + 2) == '?' || isalpha(*(s + 2)))
level++;
level++;
else if (*s == GO)
goto again;
else if (*s == OG)
while (isdigit(*t))
par = 0;
for (n = 0; n < level; n++)
par = 0;
if ((c == ']' || c == '?' && *(s + 1) == ']' && *(s + 2) != ']' && s++) && (c = *(s = next(s + 1, version))) == GO)
s = textout(sp, s, conform, conformlen, style, level + bump + par + 1, 0, ip, version, id, catalog, hflags);
goto again;
if (conform)
conform = 0;
int ol;
int vl;
a |= OPT_optional;
if (a & OPT_optional)
t = o + ol;
t = v + vl;
goto again;
goto again;
else if (*s != OG)
a = FONT_ITALIC;
if (isdigit(*++t))
while (isupper(*++t));
a = FONT_BOLD;
goto setfont;
a = FONT_LITERAL;
goto setfont;
goto again;
char* cb;
char* dt;
char* ov;
char* pp;
char* rb;
char* re;
int cl;
int sl;
int vl;
int ol;
int wl;
int xl;
int rm;
int ts;
int co;
int style;
int head;
int margin;
int mode;
int mutex;
int prefix;
int version;
long tp;
char* id;
char* catalog;
Optpass_t* o;
Optpass_t* q;
Optpass_t* e;
int flags = 0;
int bflags = 0;
int dflags = 0;
int hflags = 0;
int matched = 0;
int paragraph = 0;
goto nospace;
if (!what)
else if (!*what)
else if ((hp = (Help_t*)search(styles, elementsof(styles), sizeof(styles[0]), (char*)what + 1)) && hp->style >= 0)
goto nospace;
goto nospace;
if (opts)
o = &one;
goto nospace;
goto nospace;
goto nospace;
switch (style)
case STYLE_api:
case STYLE_html:
case STYLE_nroff:
case STYLE_usage:
case STYLE_keys:
case STYLE_posix:
xl = 0;
p = q->opts;
switch (style)
case STYLE_usage:
if (xl)
psp = 0;
goto style_usage;
case STYLE_keys:
psp = 0;
vl = 0;
if (c == GO)
vl++;
else if (c == OG)
vl--;
xl = 0;
xl = 0;
if (xl)
case CC_esc:
if (xl)
head = 0;
mode = 0;
mutex = 0;
if (sp_body)
sp_body = 0;
goto nospace;
psp = 0;
xl = p - x;
if (*p == OG)
sl = 0;
vl = 0;
cb = 0;
goto nospace;
if (*(p + 1) == '?' || *(s = skip(p + 1, ':', '?', 0, 1, 0, 0, version)) == '?' && isspace(*(s + 1)))
w = (char*)what;
if (!sp_head)
goto nospace;
if (paragraph)
paragraph = 0;
mutex++;
a |= OPT_invert;
rb = p;
sl = p - s;
a |= OPT_invert;
if (sl || (p - s) == 1 || *(s + 1) == '=' || *(s + 1) == '!' && (a |= OPT_invert) || *(s + 1) == '|')
re = p;
if (!(wl = p - w))
wl = 0;
wl = 0;
if ((!wl || *w == ':' || *w == '?') && (what[1] || sl && !memchr(s, what[0], sl) || !sl && what[0] != f))
if (*p == GO)
if (mutex)
mutex--;
mutex--;
ov = 0;
a |= OPT_optional;
a |= OPT_flag;
if (!sl)
for (c = 0; c < sl; c++)
if (!head)
item(sp_body, (flags & OPT_functions) ? C("FUNCTIONS") : C("OPTIONS"), 0, 0, style, sp_info, version, id, ID, &bflags);
mutex++;
if (sp_body)
goto nospace;
if (mutex)
mutex++;
if (sl)
m = a & OPT_TYPE;
if (m = (a & ~m) | mode)
if (!sl)
if (prefix > 0)
if (a & OPT_optional)
if (a & OPT_optional)
cb = 0;
if ((a & OPT_invert) && w && (d || u))
sfprintf(sp_info, " %s; -\b%c\b %s --\bno%-.*s\b.", T(NiL, ID, "On by default"), f, T(NiL, ID, "means"), u - w, w);
sfprintf(sp_info, " %s %s\bno%-.*s\b %s.", T(NiL, ID, "On by default; use"), "--"+2-prefix, u - w, w, T(NiL, ID, "to turn off"));
goto nospace;
if (*p == GO)
p = u ? skip(p + 1, 0, 0, 0, 0, 1, 1, version) : textout(sp_body, p, 0, 0, style, 4, 0, sp_info, version, id, catalog, &bflags);
if (a & OPT_optional)
if (ov)
while (ov < t)
ov++;
goto nospace;
t = v + vl;
goto nospace;
else if (!mutex)
if (*p == GO)
else if (*p == GO)
if (sp_misc)
goto nospace;
if (sp_info)
goto nospace;
s = o->id;
t = ud;
if (islower(c))
c = toupper(c);
t = rd;
if (s = o->release)
, ud
, section
, rd
if (!matched)
goto nospace;
goto nospace;
goto again;
s = (char*)unknown;
goto nope;
else if (matched < 0)
if (sp_plus)
goto nospace;
if (sp_head)
goto nospace;
sp_head = 0;
xl = t - x;
u = id;
if (sp_body)
goto nospace;
sp_body = 0;
if (sp_info)
sp_info = 0;
if (sp_misc)
sp_misc = 0;
goto nospace;
m = strlen((style <= STYLE_long && error_info.id && !strchr(error_info.id, '/')) ? error_info.id : id) + 1;
ts = 0;
s = id;
t = ud;
if (islower(c))
c = toupper(c);
sfprintf(mp, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n<HTML>\n<HEAD>\n<META name=\"generator\" content=\"optget (AT&T Research) 2011-11-11\">\n%s<TITLE>%s man document</TITLE>\n<STYLE type=\"text/css\">\ndiv.SH { padding-left:2em; text-indent:0em; }\ndiv.SY { padding-left:4em; text-indent:-2em; }\ndt { float:left; clear:both; }\ndd { margin-left:3em; }\n</STYLE>\n</HEAD>\n<BODY bgcolor=white>\n", (state.flags & OPT_proprietary) ? "<!--INTERNAL-->\n" : "", id);
sfprintf(mp, "<H4><TABLE width=100%%><TR><TH align=left>%s ( %s ) <TH align=center><A href=\".\" title=\"Index\">%s</A><TH align=right>%s ( %s )</TR></TABLE></H4>\n<HR>\n", ud, section, T(NiL, ID, secname(section)), ud, section);
co = 0;
tp = 0;
tp = 0;
co = 0;
pt++;
pt--;
dt = p;
dt = 0;
if (dt)
switch (*dt++)
ip++;
co = 0;
co++;
tp = 0;
pp = p;
tp = 0;
tp = 0;
pp = p;
if (*y++ == 't' && *y++ == 't' && *y++ == 'p' && (*y == ':' || *y++ == 's' && *y == ':') && *y++ == ':' && *y++ == '/' && *y++ == '/')
while (isalnum(*y) || *y == '_' || *y == '/' || *y == '-' || *y == '.' || *y == '?' || *y == '=' || *y == '%' || *y == '&' || *y == ';' || *y == '#')
if (*y++ == 'o' && *y++ == 'p' && *y++ == 'y' && *y++ == 'r' && *y++ == 'i' && *y++ == 'g' && *y++ == 'h' && *y++ == 't' && *y++ == ' ' && *y++ == '(' && (*y++ == 'c' || *(y - 1) == 'C') && *y++ == ')')
if (c == CC_esc)
if (tp)
tp = 0;
p = pp;
for (d = sfstrbase(mp), t = sfstrseek(mp, 0, SEEK_CUR); t > d && ((c = *(t - 1)) == '\n' || c == '\r' || c == ' ' || c == '\t'); t--);
pt--;
goto nospace;
if (sp)
nope:
if (psp)
if (sp_help)
if (sp_text)
if (sp_plus)
if (sp_info)
if (sp_head)
if (sp_body)
if (sp_misc)
static intmax_t
optnumber(const char* s, char** t, int* e)
intmax_t n;
int oerrno;
errno = 0;
*e = errno;
goto nospace;
if (!X(catalog))
goto nospace;
if (opt_info.option[0] != '?' && opt_info.option[0] != '-' || opt_info.option[1] != '?' && opt_info.option[1] != '-')
if (err)
char* numopt;
char* opts;
char* id;
char* catalog;
int err;
int no;
int nov;
int num;
int numchr;
int prefix;
int version;
if (!_error_infop_)
if (!_opt_infop_)
if (!oopts)
if (!argv)
cache = 0;
if (cache)
if (pcache)
if (!argv)
if (!argv)
catalog = 0;
else /* if (!error_info.catalog) */
psp = 0;
if (!prefix)
else if ((c = *s++) != '-' && (c != '+' || !(pass->flags & OPT_plus) && (!(pass->flags & OPT_numeric) || !isdigit(*s))))
if ((*s == 'n' || *s == 'N') && (*(s + 1) == 'o' || *(s + 1) == 'O') && *(s + 2) && *(s + 2) != '=')
no = 0;
if (w < &opt_info.name[elementsof(opt_info.name) - 1] && *s != ':' && *s != '|' && *s != '[' && *s != ']')
initdict();
goto help;
initdict();
numopt = 0;
s = opts;
if (cache)
if (!(k & OPT_cache_numeric))
if ((k & OPT_cache_optional) && (*opt_info.arg == '-' || (pass->flags & OPT_plus) && *opt_info.arg == '+') && *(opt_info.arg + 1))
if (k & OPT_cache_string)
if (!err)
if (k & OPT_cache_optional)
else if (k & OPT_cache_optional)
cache = 0;
cache = 0;
if (cache)
cache = 0;
s = opts;
if (!x && catalog)
catalog = 0;
s = opts;
s = nest(f = s);
if (!conformance(f, s - f))
goto disable;
else if (w && !cache)
if (catalog)
goto nospace;
else if (!SEP(*s))
if (SEP(*w))
if (!SEP(*q))
nov = 0;
if (n = no)
else if (!SEP(*s))
if (SEP(*w))
if (!SEP(*q))
num = 0;
for (x = k; *(f + 1) == '|' && (j = *(f + 2)) && j != '!' && j != '=' && j != ':' && j != '?' && j != ']'; f += 2);
x = -strtol(a, &b, 0);
if (*s == GO)
if (cache)
m = OPT_cache_flag;
m |= OPT_cache_numeric;
m |= OPT_cache_string;
m |= OPT_cache_optional;
if (*v != GO)
m |= OPT_cache_invert;
num = 0;
c = -strtol(++f, &b, 0);
numchr = k;
if (cache)
m = OPT_cache_flag;
m |= OPT_cache_numeric;
m |= OPT_cache_optional;
m |= OPT_cache_string;
m |= OPT_cache_optional;
if (*s == GO)
if (v && (a == 0 || *a == 0 || *(a + 1) != ':' && *(a + 1) != '#') && (*v == '0' || *v == '1') && !*(v + 1))
if (!num && v)
goto help;
goto help;
s = numopt;
if (nov)
goto optarg;
if (*(s + 1) == '?' && (*opt_info.arg == '-' || (pass->flags & OPT_plus) && *opt_info.arg == '+') && *(opt_info.arg + 1))
if (err || *e)
if (*s == ':' && *(s = skip(s, 0, 0, 0, 1, 0, 1, version)) == GO && *(s = next(s + 1, version)) == '[' && isalnum(*(s + 1)))
if (catalog)
goto nospace;
else if (!SEP(*s))
if (SEP(*w))
if (!SEP(*q))
nov = 0;
num = 0;
for (x = k; *(f + 1) == '|' && (j = *(f + 2)) && j != '!' && j != '=' && j != ':' && j != '?' && j != ']'; f += 2);
x = -strtol(a, &b, 0);
help:
goto again;
register char* s = (char*)str;
register int ql;
register int qr;
register int qc;
if (isdigit(*s) && (v = (int)strtol(s, &e, 10)) > 1 && isspace(*e) && --v <= strlen(s) && (s[v] == 0 || s[v] == '\n'))
while (isspace(*++e));
while (*s && *s != ',' && *s != ' ' && *s != '\t' && *s != '\n' && *s != '\r' && *s != '=' && *s != ':')
goto nospace;
else if (c == qr)
if (--qc <= 0)
else if (c == ql)
qc++;
else if (qr)
if (c == GO)
ql = c;
ql = c;
goto nospace;
if (opts)
goto again;