diff options
Diffstat (limited to 'contrib/com_err')
-rw-r--r-- | contrib/com_err/com_err.3 | 96 | ||||
-rw-r--r-- | contrib/com_err/com_err.c | 40 | ||||
-rw-r--r-- | contrib/com_err/com_err.h | 31 | ||||
-rw-r--r-- | contrib/com_err/com_right.h | 27 | ||||
-rw-r--r-- | contrib/com_err/compile_et.1 | 75 | ||||
-rw-r--r-- | contrib/com_err/compile_et.c | 43 | ||||
-rw-r--r-- | contrib/com_err/compile_et.h | 12 | ||||
-rw-r--r-- | contrib/com_err/getarg.c | 379 | ||||
-rw-r--r-- | contrib/com_err/getarg.h | 76 | ||||
-rw-r--r-- | contrib/com_err/lex.l | 25 | ||||
-rw-r--r-- | contrib/com_err/parse.y | 20 |
11 files changed, 721 insertions, 103 deletions
diff --git a/contrib/com_err/com_err.3 b/contrib/com_err/com_err.3 new file mode 100644 index 0000000..e6eeea1 --- /dev/null +++ b/contrib/com_err/com_err.3 @@ -0,0 +1,96 @@ +.\" Copyright (c) 1988 Massachusetts Institute of Technology, +.\" Student Information Processing Board. All rights reserved. +.\" +.\" $FreeBSD$ +.\" +.TH COM_ERR 3 "22 Nov 1988" SIPB +.SH NAME +com_err \- common error display routine +.SH SYNOPSIS +.nf + #include <com_err.h> +.PP +void com_err (whoami, code, format, ...); + const char *whoami; + long code; + const char *format; +.PP +proc = set_com_err_hook (proc); +.fi +void (* +.I proc +) (const char *, long, const char *, va_list); +.nf +.PP +proc = reset_com_err_hook (); +.PP +void initialize_XXXX_error_table (); +.fi +.SH DESCRIPTION +.I Com_err +displays an error message on the standard error stream +.I stderr +(see +.IR stdio (3S)) +composed of the +.I whoami +string, which should specify the program name or some subportion of +a program, followed by an error message generated from the +.I code +value (derived from +.IR compile_et (1)), +and a string produced using the +.I format +string and any following arguments, in the same style as +.IR fprintf (3). + +The behavior of +.I com_err +can be modified using +.I set_com_err_hook; +this defines a procedure which is called with the arguments passed to +.I com_err, +instead of the default internal procedure which sends the formatted +text to error output. Thus the error messages from a program can all +easily be diverted to another form of diagnostic logging, such as +.IR syslog (3). +.I Reset_com_err_hook +may be used to restore the behavior of +.I com_err +to its default form. Both procedures return the previous ``hook'' +value. These ``hook'' procedures must have the declaration given for +.I proc +above in the synopsis. + +The +.I initialize_XXXX_error_table +routine is generated mechanically by +.IR compile_et (1) +from a source file containing names and associated strings. Each +table has a name of up to four characters, which is used in place of +the +.B XXXX +in the name of the routine. These routines should be called before +any of the corresponding error codes are used, so that the +.I com_err +library will recognize error codes from these tables when they are +used. + +The +.B com_err.h +header file should be included in any source file that uses routines +from the +.I com_err +library; executable files must be linked using +.I ``-lcom_err'' +in order to cause the +.I com_err +library to be included. + +.\" .IR for manual entries +.\" .PP for paragraph breaks + +.SH "SEE ALSO" +compile_et (1), syslog (3). + +Ken Raeburn, "A Common Error Description Library for UNIX". diff --git a/contrib/com_err/com_err.c b/contrib/com_err/com_err.c index ea0ac7c..fc15e9a 100644 --- a/contrib/com_err/com_err.c +++ b/contrib/com_err/com_err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan + * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -14,7 +14,12 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of the Institute nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -33,15 +38,14 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: com_err.c,v 1.18 2002/03/10 23:07:01 assar Exp $"); +RCSID("$Id: com_err.c,v 1.13 1999/03/12 15:17:08 bg Exp $"); #endif #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <roken.h> #include "com_err.h" -struct et_list *_et_list = NULL; +struct et_list *_et_list; const char * @@ -49,12 +53,8 @@ error_message (long code) { static char msg[128]; const char *p = com_right(_et_list, code); - if (p == NULL) { - if (code < 0) - sprintf(msg, "Unknown error %ld", code); - else - p = strerror(code); - } + if (p == NULL) + p = strerror(code); if (p != NULL && *p != '\0') { strncpy(msg, p, sizeof(msg) - 1); msg[sizeof(msg) - 1] = 0; @@ -72,10 +72,6 @@ init_error_table(const char **msgs, long base, int count) static void default_proc (const char *whoami, long code, const char *fmt, va_list args) - __attribute__((__format__(__printf__, 3, 0))); - -static void -default_proc (const char *whoami, long code, const char *fmt, va_list args) { if (whoami) fprintf(stderr, "%s: ", whoami); @@ -157,17 +153,3 @@ error_table_name(int num) *p = '\0'; return(buf); } - -void -add_to_error_table(struct et_list *new_table) -{ - struct et_list *et; - - for (et = _et_list; et; et = et->next) { - if (et->table->base == new_table->table->base) - return; - } - - new_table->next = _et_list; - _et_list = new_table; -} diff --git a/contrib/com_err/com_err.h b/contrib/com_err/com_err.h index a76214b..19cf034 100644 --- a/contrib/com_err/com_err.h +++ b/contrib/com_err/com_err.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -14,7 +14,12 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of the Institute nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -31,35 +36,33 @@ * SUCH DAMAGE. */ -/* $Id: com_err.h,v 1.9 2001/05/11 20:03:36 assar Exp $ */ +/* $Id: com_err.h,v 1.3 1998/05/02 20:13:28 assar Exp $ */ +/* $FreeBSD$ */ /* MIT compatible com_err library */ #ifndef __COM_ERR_H__ #define __COM_ERR_H__ -#include <com_right.h> +#include <sys/cdefs.h> -#if !defined(__GNUC__) && !defined(__attribute__) -#define __attribute__(X) +#ifdef __STDC__ +#include <stdarg.h> #endif +#include <com_right.h> + typedef void (*errf) __P((const char *, long, const char *, va_list)); const char * error_message __P((long)); int init_error_table __P((const char**, long, int)); -void com_err_va __P((const char *, long, const char *, va_list)) - __attribute__((format(printf, 3, 0))); - -void com_err __P((const char *, long, const char *, ...)) - __attribute__((format(printf, 3, 4))); +void com_err_va __P((const char *, long, const char *, va_list)); +void com_err __P((const char *, long, const char *, ...)); errf set_com_err_hook __P((errf)); errf reset_com_err_hook __P((void)); -const char *error_table_name __P((int num)); - -void add_to_error_table __P((struct et_list *new_table)); +const char *error_table_name __P((int num)); #endif /* __COM_ERR_H__ */ diff --git a/contrib/com_err/com_right.h b/contrib/com_err/com_right.h index c87bb0d..c329bce 100644 --- a/contrib/com_err/com_right.h +++ b/contrib/com_err/com_right.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -14,7 +14,12 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of the Institute nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -31,22 +36,13 @@ * SUCH DAMAGE. */ -/* $Id: com_right.h,v 1.11 2000/07/31 01:11:08 assar Exp $ */ +/* $Id: com_right.h,v 1.8 1998/02/17 21:19:43 bg Exp $ */ +/* $FreeBSD$ */ #ifndef __COM_RIGHT_H__ #define __COM_RIGHT_H__ -#ifdef __STDC__ -#include <stdarg.h> -#endif - -#ifndef __P -#ifdef __STDC__ -#define __P(X) X -#else -#define __P(X) () -#endif -#endif +#include <sys/cdefs.h> struct error_table { char const * const * msgs; @@ -60,7 +56,8 @@ struct et_list { extern struct et_list *_et_list; const char *com_right __P((struct et_list *list, long code)); -void initialize_error_table_r __P((struct et_list **, const char **, int, long)); +void initialize_error_table_r __P((struct et_list **, const char **, int, + long)); void free_error_table __P((struct et_list *)); #endif /* __COM_RIGHT_H__ */ diff --git a/contrib/com_err/compile_et.1 b/contrib/com_err/compile_et.1 new file mode 100644 index 0000000..f432655 --- /dev/null +++ b/contrib/com_err/compile_et.1 @@ -0,0 +1,75 @@ +.\" Copyright (c) 1988 Massachusetts Institute of Technology, +.\" Student Information Processing Board. All rights reserved. +.\" +.\" $FreeBSD$ +.\" +.Dd November 22, 1988 +.Os +.Dt COMPILE_ET 1 +.Sh NAME +.Nm compile_et +.Nd error table compiler +.Sh SYNOPSIS +.Nm compile_et +.Ar file +.Sh DESCRIPTION +.Nm Compile_et +converts a table listing error-code names and associated messages into +a C source file suitable for use with the +.Xr com_err 3 +library. +.Pp +The source file name must end with a suffix of ``.et''; the file +consists of a declaration supplying the name (up to four characters +long) of the error-code table: +.Pp +.Em error_table name +.Pp +followed by up to 256 entries of the form: +.Pp +.Em error_code name , +.No \(dq Ns Em string Ns \(dq +.Pp +and a final +.Pp +.Em end +.Pp +to indicate the end of the table. +.Pp +The name of the table is used to construct the name of a subroutine +.Em initialize_XXXX_error_table +which must be called in order for the +.Xr com_err 3 +library to recognize the error table. +.Pp +The various error codes defined are assigned sequentially increasing +numbers (starting with a large number computed as a hash function of +the name of the table); thus for compatibility it is suggested that +new codes be added only to the end of an existing table, and that no +codes be removed from tables. +.Pp +The names defined in the table are placed into a C header file with +preprocessor directives defining them as integer constants of up to +32 bits in magnitude. +.Pp +A C source file is also generated which should be compiled and linked +with the object files which reference these error codes; it contains +the text of the messages and the initialization subroutine. Both C +files have names derived from that of the original source file, with +the ``.et'' suffix replaced by ``.c'' and ``.h''. +.Pp +A ``#'' in the source file is treated as a comment character, and all +remaining text to the end of the source line will be ignored. +.Sh BUGS +Since +.Nm compile_et +uses a very simple parser based on +.Xr yacc 1 , +its error recovery leaves much to be desired. +.Sh SEE ALSO +.Xr yacc 1 , +.Xr com_err 3 +.Rs +.%A Ken Raeburn +.%T "A Common Error Description Library for UNIX" +.Re diff --git a/contrib/com_err/compile_et.c b/contrib/com_err/compile_et.c index b19b218..345a39f 100644 --- a/contrib/com_err/compile_et.c +++ b/contrib/com_err/compile_et.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2002 Kungliga Tekniska Högskolan + * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -14,7 +14,12 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of the Institute nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -35,9 +40,10 @@ #include "compile_et.h" #include <getarg.h> -RCSID("$Id: compile_et.c,v 1.16 2002/08/20 12:44:51 joda Exp $"); +#if 0 +RCSID("$Id: compile_et.c,v 1.12 1999/04/01 09:13:52 joda Exp $"); +#endif -#include <roken.h> #include <err.h> #include "parse.h" @@ -83,7 +89,7 @@ generate_c(void) fprintf(c_file, "#include \"%s\"\n", hfn); fprintf(c_file, "\n"); - fprintf(c_file, "static const char *%s_error_strings[] = {\n", name); + fprintf(c_file, "static const char *text[] = {\n"); for(ec = codes, n = 0; ec; ec = ec->next, n++) { while(n < ec->number) { @@ -98,22 +104,20 @@ generate_c(void) fprintf(c_file, "\tNULL\n"); fprintf(c_file, "};\n"); fprintf(c_file, "\n"); - fprintf(c_file, "#define num_errors %d\n", number); - fprintf(c_file, "\n"); fprintf(c_file, "void initialize_%s_error_table_r(struct et_list **list)\n", name); fprintf(c_file, "{\n"); fprintf(c_file, - " initialize_error_table_r(list, %s_error_strings, " - "num_errors, ERROR_TABLE_BASE_%s);\n", name, name); + " initialize_error_table_r(list, text, " + "%s_num_errors, ERROR_TABLE_BASE_%s);\n", name, name); fprintf(c_file, "}\n"); fprintf(c_file, "\n"); fprintf(c_file, "void initialize_%s_error_table(void)\n", name); fprintf(c_file, "{\n"); fprintf(c_file, - " init_error_table(%s_error_strings, ERROR_TABLE_BASE_%s, " - "num_errors);\n", name, name); + " init_error_table(text, ERROR_TABLE_BASE_%s, " + "%s_num_errors);\n", name, name); fprintf(c_file, "}\n"); fclose(c_file); @@ -143,7 +147,7 @@ generate_h(void) fprintf(h_file, "#ifndef %s\n", fn); fprintf(h_file, "#define %s\n", fn); fprintf(h_file, "\n"); - fprintf(h_file, "struct et_list;\n"); + fprintf(h_file, "#include <com_right.h>\n"); fprintf(h_file, "\n"); fprintf(h_file, "void initialize_%s_error_table_r(struct et_list **);\n", @@ -154,16 +158,16 @@ generate_h(void) name, name); fprintf(h_file, "\n"); fprintf(h_file, "typedef enum %s_error_number{\n", name); + fprintf(h_file, "\tERROR_TABLE_BASE_%s = %ld,\n", name, base); + fprintf(h_file, "\t%s_err_base = %ld,\n", name, base); for(ec = codes; ec; ec = ec->next) { - fprintf(h_file, "\t%s = %ld%s\n", ec->name, base + ec->number, - (ec->next != NULL) ? "," : ""); + fprintf(h_file, "\t%s = %ld,\n", ec->name, base + ec->number); } + fprintf(h_file, "\t%s_num_errors = %d\n", name, number); fprintf(h_file, "} %s_error_number;\n", name); fprintf(h_file, "\n"); - fprintf(h_file, "#define ERROR_TABLE_BASE_%s %ld\n", name, base); - fprintf(h_file, "\n"); fprintf(h_file, "#endif /* %s */\n", fn); @@ -177,10 +181,8 @@ generate(void) return generate_c() || generate_h(); } -int version_flag; int help_flag; struct getargs args[] = { - { "version", 0, arg_flag, &version_flag }, { "help", 0, arg_flag, &help_flag } }; int num_args = sizeof(args) / sizeof(args[0]); @@ -198,15 +200,10 @@ main(int argc, char **argv) char *p; int optind = 0; - setprogname(argv[0]); if(getarg(args, num_args, argc, argv, &optind)) usage(1); if(help_flag) usage(0); - if(version_flag) { - print_version(NULL); - exit(0); - } if(optind == argc) usage(1); diff --git a/contrib/com_err/compile_et.h b/contrib/com_err/compile_et.h index 86dd113..fc6b3e5 100644 --- a/contrib/com_err/compile_et.h +++ b/contrib/com_err/compile_et.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -14,7 +14,12 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of the Institute nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -31,7 +36,7 @@ * SUCH DAMAGE. */ -/* $Id: compile_et.h,v 1.6 2000/07/01 20:21:48 assar Exp $ */ +/* $Id: compile_et.h,v 1.3 1998/11/22 09:39:46 assar Exp $ */ #ifndef __COMPILE_ET_H__ #define __COMPILE_ET_H__ @@ -45,7 +50,6 @@ #include <stdlib.h> #include <stdarg.h> #include <ctype.h> -#include <roken.h> extern long base; extern int number; diff --git a/contrib/com_err/getarg.c b/contrib/com_err/getarg.c new file mode 100644 index 0000000..80f76ab --- /dev/null +++ b/contrib/com_err/getarg.c @@ -0,0 +1,379 @@ +/* + * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#if 0 +RCSID("$Id: getarg.c,v 1.25 1998/11/22 09:45:05 assar Exp $"); +#endif + +#include <sys/ttycom.h> +#include <time.h> +#include <stdio.h> +#include <stdlib.h> +#include "getarg.h" + +#define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag) + +static size_t +print_arg (char *string, size_t len, int mdoc, int longp, struct getargs *arg) +{ + const char *s; + + *string = '\0'; + + if (ISFLAG(*arg)) + return 0; + + if(mdoc){ + if(longp) + strncat(string, "= Ns", len); + strncat(string, " Ar ", len); + }else + if (longp) + strncat (string, "=", len); + else + strncat (string, " ", len); + + if (arg->arg_help) + s = arg->arg_help; + else if (arg->type == arg_integer) + s = "number"; + else if (arg->type == arg_string) + s = "string"; + else + s = "<undefined>"; + + strncat(string, s, len); + return 1 + strlen(s); +} + +static int +check_column(FILE *f, int col, int len, int columns) +{ + if(col + len > columns) { + fprintf(f, "\n"); + col = fprintf(f, " "); + } + return col; +} + +void +arg_printusage (struct getargs *args, + size_t num_args, + const char *progname, + const char *extra_string) +{ + int i; + size_t max_len = 0; + char buf[128]; + int col = 0, columns; + struct winsize ws; + + columns = 80; + col = 0; + col += fprintf (stderr, "Usage: %s", progname); + for (i = 0; i < num_args; ++i) { + size_t len = 0; + + if (args[i].long_name) { + buf[0] = '\0'; + strncat(buf, "[--", sizeof(buf)); + len += 2; + if(args[i].type == arg_negative_flag) { + strncat(buf, "no-", sizeof(buf)); + len += 3; + } + strncat(buf, args[i].long_name, sizeof(buf)); + len += strlen(args[i].long_name); + len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), + 0, 1, &args[i]); + strncat(buf, "]", sizeof(buf)); + if(args[i].type == arg_strings) + strncat(buf, "...", sizeof(buf)); + col = check_column(stderr, col, strlen(buf) + 1, columns); + col += fprintf(stderr, " %s", buf); + } + if (args[i].short_name) { + snprintf(buf, sizeof(buf), "[-%c", args[i].short_name); + len += 2; + len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), + 0, 0, &args[i]); + strncat(buf, "]", sizeof(buf)); + if(args[i].type == arg_strings) + strncat(buf, "...", sizeof(buf)); + col = check_column(stderr, col, strlen(buf) + 1, columns); + col += fprintf(stderr, " %s", buf); + } + if (args[i].long_name && args[i].short_name) + len += 2; /* ", " */ + max_len = max(max_len, len); + } + if (extra_string) { + col = check_column(stderr, col, strlen(extra_string) + 1, columns); + fprintf (stderr, " %s\n", extra_string); + } else + fprintf (stderr, "\n"); + for (i = 0; i < num_args; ++i) { + if (args[i].help) { + size_t count = 0; + + if (args[i].short_name) { + count += fprintf (stderr, "-%c", args[i].short_name); + print_arg (buf, sizeof(buf), 0, 0, &args[i]); + count += fprintf(stderr, "%s", buf); + } + if (args[i].short_name && args[i].long_name) + count += fprintf (stderr, ", "); + if (args[i].long_name) { + count += fprintf (stderr, "--"); + if (args[i].type == arg_negative_flag) + count += fprintf (stderr, "no-"); + count += fprintf (stderr, "%s", args[i].long_name); + print_arg (buf, sizeof(buf), 0, 1, &args[i]); + count += fprintf(stderr, "%s", buf); + } + while(count++ <= max_len) + putc (' ', stderr); + fprintf (stderr, "%s\n", args[i].help); + } + } +} + +static void +add_string(getarg_strings *s, char *value) +{ + s->strings = realloc(s->strings, (s->num_strings + 1) * sizeof(*s->strings)); + s->strings[s->num_strings] = value; + s->num_strings++; +} + +static int +arg_match_long(struct getargs *args, size_t num_args, + char *argv) +{ + int i; + char *optarg = NULL; + int negate = 0; + int partial_match = 0; + struct getargs *partial = NULL; + struct getargs *current = NULL; + int argv_len; + char *p; + + argv_len = strlen(argv); + p = strchr (argv, '='); + if (p != NULL) + argv_len = p - argv; + + for (i = 0; i < num_args; ++i) { + if(args[i].long_name) { + int len = strlen(args[i].long_name); + char *p = argv; + int p_len = argv_len; + negate = 0; + + for (;;) { + if (strncmp (args[i].long_name, p, p_len) == 0) { + if(p_len == len) + current = &args[i]; + else { + ++partial_match; + partial = &args[i]; + } + optarg = p + p_len; + } else if (ISFLAG(args[i]) && strncmp (p, "no-", 3) == 0) { + negate = !negate; + p += 3; + p_len -= 3; + continue; + } + break; + } + if (current) + break; + } + } + if (current == NULL) { + if (partial_match == 1) + current = partial; + else + return ARG_ERR_NO_MATCH; + } + + if(*optarg == '\0' && !ISFLAG(*current)) + return ARG_ERR_NO_MATCH; + switch(current->type){ + case arg_integer: + { + int tmp; + if(sscanf(optarg + 1, "%d", &tmp) != 1) + return ARG_ERR_BAD_ARG; + *(int*)current->value = tmp; + return 0; + } + case arg_string: + { + *(char**)current->value = optarg + 1; + return 0; + } + case arg_strings: + { + add_string((getarg_strings*)current->value, optarg + 1); + return 0; + } + case arg_flag: + case arg_negative_flag: + { + int *flag = current->value; + if(*optarg == '\0' || + strcmp(optarg + 1, "yes") == 0 || + strcmp(optarg + 1, "true") == 0){ + *flag = !negate; + return 0; + } else if (*optarg && strcmp(optarg + 1, "maybe") == 0) { + *flag = rand() & 1; + } else { + *flag = negate; + return 0; + } + return ARG_ERR_BAD_ARG; + } + default: + abort (); + } +} + +int +getarg(struct getargs *args, size_t num_args, + int argc, char **argv, int *optind) +{ + int i, j, k; + int ret = 0; + + srand (time(NULL)); + (*optind)++; + for(i = *optind; i < argc; i++) { + if(argv[i][0] != '-') + break; + if(argv[i][1] == '-'){ + if(argv[i][2] == 0){ + i++; + break; + } + ret = arg_match_long (args, num_args, argv[i] + 2); + if(ret) + return ret; + }else{ + for(j = 1; argv[i][j]; j++) { + for(k = 0; k < num_args; k++) { + char *optarg; + if(args[k].short_name == 0) + continue; + if(argv[i][j] == args[k].short_name){ + if(args[k].type == arg_flag){ + *(int*)args[k].value = 1; + break; + } + if(args[k].type == arg_negative_flag){ + *(int*)args[k].value = 0; + break; + } + if(argv[i][j + 1]) + optarg = &argv[i][j + 1]; + else{ + i++; + optarg = argv[i]; + } + if(optarg == NULL) + return ARG_ERR_NO_ARG; + if(args[k].type == arg_integer){ + int tmp; + if(sscanf(optarg, "%d", &tmp) != 1) + return ARG_ERR_BAD_ARG; + *(int*)args[k].value = tmp; + goto out; + }else if(args[k].type == arg_string){ + *(char**)args[k].value = optarg; + goto out; + }else if(args[k].type == arg_strings){ + add_string((getarg_strings*)args[k].value, optarg); + goto out; + } + return ARG_ERR_BAD_ARG; + } + + } + if (k == num_args) + return ARG_ERR_NO_MATCH; + } + out:; + } + } + *optind = i; + return 0; +} + +#if TEST +int foo_flag = 2; +int flag1 = 0; +int flag2 = 0; +int bar_int; +char *baz_string; + +struct getargs args[] = { + { NULL, '1', arg_flag, &flag1, "one", NULL }, + { NULL, '2', arg_flag, &flag2, "two", NULL }, + { "foo", 'f', arg_negative_flag, &foo_flag, "foo", NULL }, + { "bar", 'b', arg_integer, &bar_int, "bar", "seconds"}, + { "baz", 'x', arg_string, &baz_string, "baz", "name" }, +}; + +int main(int argc, char **argv) +{ + int optind = 0; + while(getarg(args, 5, argc, argv, &optind)) + printf("Bad arg: %s\n", argv[optind]); + printf("flag1 = %d\n", flag1); + printf("flag2 = %d\n", flag2); + printf("foo_flag = %d\n", foo_flag); + printf("bar_int = %d\n", bar_int); + printf("baz_flag = %s\n", baz_string); + arg_printusage (args, 5, argv[0], "nothing here"); +} +#endif diff --git a/contrib/com_err/getarg.h b/contrib/com_err/getarg.h new file mode 100644 index 0000000..d0d9d4e --- /dev/null +++ b/contrib/com_err/getarg.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: getarg.h,v 1.5 1998/08/18 20:26:11 assar Exp $ */ + +#ifndef __GETARG_H__ +#define __GETARG_H__ + +#include <stddef.h> + +#define max(a,b) (((a)>(b))?(a):(b)) + +struct getargs{ + const char *long_name; + char short_name; + enum { arg_integer, arg_string, arg_flag, arg_negative_flag, arg_strings } type; + void *value; + const char *help; + const char *arg_help; +}; + +enum { + ARG_ERR_NO_MATCH = 1, + ARG_ERR_BAD_ARG, + ARG_ERR_NO_ARG +}; + +typedef struct getarg_strings { + int num_strings; + char **strings; +} getarg_strings; + +int getarg(struct getargs *args, size_t num_args, + int argc, char **argv, int *optind); + +void arg_printusage (struct getargs *args, + size_t num_args, + const char *progname, + const char *extra_string); + +#endif /* __GETARG_H__ */ diff --git a/contrib/com_err/lex.l b/contrib/com_err/lex.l index e98db6f..264ad6f 100644 --- a/contrib/com_err/lex.l +++ b/contrib/com_err/lex.l @@ -1,6 +1,6 @@ %{ /* - * Copyright (c) 1998 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -15,7 +15,12 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of the Institute nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -42,16 +47,14 @@ #include "compile_et.h" #include "parse.h" -#include "lex.h" -RCSID("$Id: lex.l,v 1.6 2000/06/22 00:42:52 assar Exp $"); +#if 0 +RCSID("$Id: lex.l,v 1.4 1998/11/20 05:58:52 assar Exp $"); +#endif static unsigned lineno = 1; -static int getstring(void); - -#define YY_NO_UNPUT - -#undef ECHO +void error_message(char *, ...); +int getstring(void); %} @@ -82,7 +85,7 @@ yywrap () } #endif -static int +int getstring(void) { char x[128]; @@ -114,7 +117,7 @@ getstring(void) } void -error_message (const char *format, ...) +error_message (char *format, ...) { va_list args; diff --git a/contrib/com_err/parse.y b/contrib/com_err/parse.y index 82e99ff..32875d4 100644 --- a/contrib/com_err/parse.y +++ b/contrib/com_err/parse.y @@ -1,6 +1,6 @@ %{ /* - * Copyright (c) 1998 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -15,7 +15,12 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of the Institute nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -33,12 +38,13 @@ */ #include "compile_et.h" -#include "lex.h" - -RCSID("$Id: parse.y,v 1.11 2000/06/22 00:42:52 assar Exp $"); +#if 0 +RCSID("$Id: parse.y,v 1.9 1999/07/04 14:54:58 assar Exp $"); +#endif void yyerror (char *s); -static long name2number(const char *str); +long name2number(const char *str); +void error_message(char *, ...); extern char *yytext; @@ -135,7 +141,7 @@ statement : INDEX NUMBER %% -static long +long name2number(const char *str) { const char *p; |