--- argv.c 2000/12/13 13:19:10 1.1
+++ argv.c 2000/12/13 15:37:35 1.2
@@ -1,9 +1,10 @@
/*
- * Generic argv processor...
+ * $Source: /v/ossp/cvs/ossp-pkg/petidomo/libargv/argv.c,v $
+ * $Revision: 1.2 $
+ * $Date: 2000/12/13 15:37:35 $
*
- * Copyright 1995 by Gray Watson
- *
- * This file is part of the argv library.
+ * Copyright (c) 1999 by Gray Watson <gray.watson@letters.com>.
+ * All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the
@@ -13,94 +14,150 @@
* without specific, written prior permission.
*
* Gray Watson makes no representations about the suitability of the
- * software described herein for any purpose. It is provided "as is"
+ * software described herein for any purpose. It is provided "as is"
* without express or implied warranty.
- *
- * The author may be contacted at gray.watson@letters.com
- *
- * - Parse command line parameters conveniently.
- *
*/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
-#include <unistd.h>
-#include "_argv.h"
+#include "argv.h"
+#include "argv_loc.h"
/* internal routines */
-LOCAL void do_list(argv_t *grid, const int argc, char **argv,
- char *okay_p);
+static void do_list(argv_t *grid, const int arg_c, char **argv,
+ argv_t **queue_list, int *queue_head_p,
+ int *queue_tail_p, int *okay_bp);
/*
* exported variables
*/
/* This is a processed version of argv[0], pre-path removed: /bin/ls -> ls */
-EXPORT char argv_program[PROGRAM_NAME + 1] = "Unknown";
+char argv_program[PROGRAM_NAME + 1] = "Unknown";
/* A global value of argv from main after argv_process has been called */
-EXPORT char **argv_argv = NULL;
+char **argv_argv = NULL;
/* A global value of argc from main after argv_process has been called */
-EXPORT int argv_argc = 0;
+int argv_argc = 0;
/* This should be set externally to provide general program help to user */
-EXPORT char *argv_help_string = NULL;
+char *argv_help_string = NULL;
/* This should be set externally to provide version information to the user */
-EXPORT char *argv_version_string = NULL;
+char *argv_version_string = NULL;
/*
* Are we running interactively? This will exit on errors. Set to
* false to return error codes instead.
*/
-EXPORT char argv_interactive = ARGV_TRUE;
+int argv_interactive = ARGV_TRUE;
/*
* The FILE stream that argv out_puts all its errors. Set to NULL to
* not dump any error messages. Default is stderr.
*/
-EXPORT FILE *argv_error_stream = ERROR_STREAM_INIT;
+FILE *argv_error_stream = ERROR_STREAM_INIT;
/* local variables */
-LOCAL_QUEUE_DECLARE(argv_t *); /* args waiting for values */
-LOCAL argv_t empty[] = {{ ARGV_LAST }}; /* empty argument array */
-LOCAL char enabled = ARGV_FALSE; /* are the lights on? */
+static argv_t empty[] = {{ ARGV_LAST }}; /* empty argument array */
+static int enabled_b = ARGV_FALSE; /* are the lights on? */
/* global settings */
-LOCAL int global_close = GLOBAL_CLOSE_ENABLE; /* close processing */
-LOCAL int global_env = GLOBAL_ENV_BEFORE; /* env processing */
-LOCAL int global_error = GLOBAL_ERROR_SEE; /* error processing */
-LOCAL int global_multi = GLOBAL_MULTI_ACCEPT; /* multi processing */
-LOCAL int global_usage = GLOBAL_USAGE_LONG; /* usage processing */
+static int global_close = GLOBAL_CLOSE_ENABLE; /* close processing */
+static int global_env = GLOBAL_ENV_BEFORE; /* env processing */
+static int global_error = GLOBAL_ERROR_SEE; /* error processing */
+static int global_multi = GLOBAL_MULTI_ACCEPT; /* multi processing */
+static int global_usage = GLOBAL_USAGE_LONG; /* usage processing */
+static int global_lasttog = GLOBAL_LASTTOG_DISABLE; /*last-arg toggling*/
/****************************** startup routine ******************************/
/*
+ * static void argv_startup
+ *
+ * DESCRIPTION:
+ *
* Turn on the lights.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * None.
*/
-LOCAL void argv_startup(void)
+static void argv_startup(void)
{
- if (enabled)
+ if (enabled_b) {
return;
- enabled = ARGV_TRUE;
+ }
+ enabled_b = ARGV_TRUE;
/* ANSI says we cannot predefine this above */
- if (argv_error_stream == ERROR_STREAM_INIT)
+ if (argv_error_stream == ERROR_STREAM_INIT) {
argv_error_stream = stderr;
+ }
}
/***************************** general utilities *****************************/
+
+/*** ET: BSD's strsep funktion. See their man-page... ***/
+
+char *
+my_strsep(char **stringp, const char *delim)
+{
+ register char *s;
+ register const char *spanp;
+ register int c, sc;
+ char *tok;
+
+ if ((s = *stringp) == NULL)
+ return NULL;
+ for (tok = s;;)
+ {
+ c = *s++;
+ spanp = delim;
+ do
+ {
+ if ((sc = *spanp++) == c)
+ {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ *stringp = s;
+ return tok;
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
+
/*
- * Binary STR to integer translation
+ * static int btoi
+ *
+ * DESCRIPTION:
+ *
+ * Binary string to integer translation.
+ *
+ * RETURNS:
+ *
+ * Integer converted from the string.
+ *
+ * ARGUMENTS:
+ *
+ * str - String of binary 0s and 1s that we are converting.
*/
-LOCAL int btoi(const char *str)
+static int btoi(const char *str)
{
int ret = 0;
/* strip off spaces */
- for (; isspace((int)*str); str++);
+ for (; isspace((int)*str); str++) {
+ }
for (; *str == '0' || *str == '1'; str++) {
ret *= 2;
@@ -111,14 +168,27 @@
}
/*
- * Octal STR to integer translation
+ * static int otoi
+ *
+ * DESCRIPTION:
+ *
+ * Octal string to integer translation.
+ *
+ * RETURNS:
+ *
+ * Integer converted from the string.
+ *
+ * ARGUMENTS:
+ *
+ * str - String of octal digits that we are converting.
*/
-LOCAL int otoi(const char *str)
+static int otoi(const char *str)
{
int ret = 0;
/* strip off spaces */
- for (; isspace((int)*str); str++);
+ for (; isspace((int)*str); str++) {
+ }
for (; *str >= '0' && *str <= '7'; str++) {
ret *= 8;
@@ -129,174 +199,301 @@
}
/*
- * Hexadecimal STR to integer translation
+ * static int htoi
+ *
+ * DESCRIPTION:
+ *
+ * Hexadecimal string to integer translation.
+ *
+ * RETURNS:
+ *
+ * Integer converted from the string.
+ *
+ * ARGUMENTS:
+ *
+ * str - String of hexadecimal characters and digits that we are
+ * converting.
*/
-LOCAL int htoi(const char *str)
+static int htoi(const char *str)
{
int ret = 0;
/* strip off spaces */
- for (; isspace((int)*str); str++);
+ for (; isspace((int)*str); str++) {
+ }
/* skip a leading 0[xX] */
- if (*str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X'))
+ if (*str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X')) {
str += 2;
+ }
for (; isdigit((int)*str) ||
(*str >= 'a' && *str <= 'f') || (*str >= 'A' && *str <= 'F');
str++) {
ret *= 16;
- if (*str >= 'a' && *str <= 'f')
+ if (*str >= 'a' && *str <= 'f') {
ret += *str - 'a' + 10;
- else if (*str >= 'A' && *str <= 'F')
+ }
+ else if (*str >= 'A' && *str <= 'F') {
ret += *str - 'A' + 10;
- else
+ }
+ else {
ret += *str - '0';
+ }
}
return ret;
}
/*
- * Basically a strdup for compatibility sake
+ * static char *string_copy
+ *
+ * DESCRIPTION:
+ *
+ * Basically a strdup for compatibility sake.
+ *
+ * RETURNS:
+ *
+ * Character pointer that must be freed later.
+ *
+ * ARGUMENTS:
+ *
+ * str - String we are copying.
*/
-LOCAL char *string_copy(const char *ptr)
+static char *string_copy(const char *str)
{
- const char *ptr_p;
- char *ret, *ret_p;
+ const char *str_p;
+ char *copy, *copy_p;
int len;
- len = strlen(ptr);
- ret = (char *)malloc(len + 1);
- if (ret == NULL) {
- if (argv_error_stream != NULL)
+ len = strlen(str);
+ copy = (char *)malloc(len + 1);
+ if (copy == NULL) {
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: memory error during argument processing\n",
argv_program);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return NULL;
}
- for (ptr_p = ptr, ret_p = ret; *ptr_p != NULLC;)
- *ret_p++ = *ptr_p++;
- *ret_p = NULLC;
+ for (str_p = str, copy_p = copy; *str_p != '\0';) {
+ *copy_p++ = *str_p++;
+ }
+ *copy_p = '\0';
- return ret;
+ return copy;
}
/*
- * Break STR and return an array of char * whose values are tokenized
- * by TOK. it passes back the number of tokens in TOKN.
+ * static char **vectorize
*
- * NOTE: the return value should be freed later and the STR should stay
- * around until that time.
+ * DESCRIPTION:
+ *
+ * Break a string up into its arguments separated by one of the
+ * characters in a token string and return an array of char pointers.
+ *
+ * NOTE: the string argument should stay around until that time.
+ *
+ * RETURNS:
+ *
+ * Success - Allocated list of character poiners into the string
+ * argument which must be freed later.
+ *
+ * Failure - NULL
+ *
+ * ARGUMENTS:
+ *
+ * str - String we are tokenizing.
+ *
+ * tok - List of token characters to look for in the string.
+ *
+ * num_tok_p - Pointer to an integer which will be set to the number
+ * of tokens found in the string.
*/
-LOCAL char **vectorize(char *str, const char *tok, int *tokn)
+static char **vectorize(char *str, const char *tok, int *num_tok_p)
{
char **vect_p;
- char *tmp, *tok_p;
- int tok_c;
+ char *tmp, *str_p, *tok_p;
+ int tok_c, tok_n;
/* count the tokens */
tmp = string_copy(str);
- if (tmp == NULL)
+ if (tmp == NULL) {
return NULL;
+ }
- tok_p = strtok(tmp, tok);
- for (tok_c = 0; tok_p != NULL; tok_c++)
- tok_p = strtok(NULL, tok);
+ str_p = tmp;
+ tok_c = 0;
+ while (1) {
+ tok_p = my_strsep(&str_p, tok);
+ if (tok_p == NULL) {
+ break;
+ }
+ if (*tok_p != '\0') {
+ tok_c++;
+ }
+ }
+ tok_n = tok_c;
free(tmp);
- *tokn = tok_c;
+ *num_tok_p = tok_n;
- if (tok_c == 0)
+ if (tok_c == 0) {
return NULL;
+ }
/* allocate the pointer grid */
vect_p = (char **)malloc(sizeof(char *) * tok_c);
if (vect_p == NULL) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: memory error during argument processing\n",
argv_program);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return NULL;
}
/* load the tokens into the list */
- vect_p[0] = strtok(str, tok);
-
- for (tok_c = 1; tok_c < *tokn; tok_c++)
- vect_p[tok_c] = strtok(NULL, tok);
+ str_p = str;
+ for (tok_c = 0; tok_c < tok_n;) {
+ tok_p = my_strsep(&str_p, tok);
+ if (tok_p == NULL) {
+ break;
+ }
+ if (*tok_p != '\0') {
+ vect_p[0] = tok_p;
+ tok_c++;
+ }
+ }
return vect_p;
}
/*
- * Display printable chars from BUF of SIZE, non-printables as \%03o
+ * static int expand_buf
+ *
+ * DESCRIPTION:
+ *
+ * Translates a buffer of bytes into its printable version.
+ *
+ * NOTE: it does _not_ add a \0 at the end of OUT.
+ *
+ * RETURNS:
+ *
+ * Number of characters written in to the output buffer.
+ *
+ * ARGUMENTS:
+ *
+ * buf - Input buffer of bytes.
+ *
+ * buf_size - Size of the input buffer. If < 0 then the routing will
+ * translate up to the first \0.
+ *
+ * out - Output buffer for the translated characters.
+ *
+ * out_size - Maximum size of the output buffer.
*/
-LOCAL char *expand_buf(const void *buf, const int size)
+static int expand_buf(const void *buf, const int buf_size,
+ char *out, const int out_size)
{
- static char out[DUMP_SPACE_BUF];
- int size_c;
- void *buf_p;
- char *out_p;
+ int buf_c;
+ const unsigned char *buf_p, *spec_p;
+ char *max_p, *out_p = out;
- for (size_c = 0, out_p = out, buf_p = (void *)buf; size_c < size;
- size_c++, buf_p = (char *)buf_p + 1) {
- char *spec_p;
+ /* setup our max pointer */
+ max_p = out + out_size;
- /* handle special chars */
- if (out_p + 2 >= out + sizeof(out))
- break;
+ /* run through the input buffer, counting the characters as we go */
+ for (buf_c = 0, buf_p = (const unsigned char *)buf;; buf_c++, buf_p++) {
+
+ /* did we reach the end of the buffer? */
+ if (buf_size < 0) {
+ if (*buf_p == '\0') {
+ break;
+ }
+ }
+ else {
+ if (buf_c >= buf_size) {
+ break;
+ }
+ }
/* search for special characters */
- for (spec_p = SPECIAL_CHARS + 1; *(spec_p - 1) != NULLC; spec_p += 2)
- if (*spec_p == *(char *)buf_p)
+ for (spec_p = (unsigned char *)SPECIAL_CHARS + 1;
+ *(spec_p - 1) != '\0';
+ spec_p += 2) {
+ if (*spec_p == *buf_p) {
break;
+ }
+ }
/* did we find one? */
- if (*(spec_p - 1) != NULLC) {
- if (out_p + 2 >= out + sizeof(out))
+ if (*(spec_p - 1) != '\0') {
+ if (out_p + 2 >= max_p) {
break;
+ }
(void)sprintf(out_p, "\\%c", *(spec_p - 1));
out_p += 2;
continue;
}
- if (*(unsigned char *)buf_p < 128 && isprint((int)(*(char *)buf_p))) {
- if (out_p + 1 >= out + sizeof(out))
+ /* print out any 7-bit printable characters */
+ if (*buf_p < 128 && isprint(*buf_p)) {
+ if (out_p + 1 >= max_p) {
break;
+ }
*out_p = *(char *)buf_p;
out_p += 1;
}
else {
- if (out_p + 4 >= out + sizeof(out))
+ if (out_p + 4 >= max_p) {
break;
- (void)sprintf(out_p, "\\%03o", *(unsigned char *)buf_p);
+ }
+ (void)sprintf(out_p, "\\%03o", *buf_p);
out_p += 4;
}
}
- *out_p = NULLC;
- return out;
+ return out_p - out;
}
+
/****************************** usage routines *******************************/
/*
+ * static void usage_short
+ *
+ * DESCRIPTION:
+ *
* Print a short-format usage message.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * args - Array of argv_t structions whose usage messages you print.
+ *
+ * flags - User flags.
*/
-LOCAL void usage_short(const argv_t *args, const int flag)
+static void usage_short(const argv_t *args, const int flag)
{
const argv_t *arg_p;
int len, col_c = 0;
- char mark = ARGV_FALSE, *prefix;
+ int mark_b = ARGV_FALSE;
+ char *prefix;
- if (argv_error_stream == NULL)
+ if (argv_error_stream == NULL) {
return;
+ }
/* print the usage message header */
(void)fprintf(argv_error_stream, "%s%s", USAGE_LABEL, argv_program);
@@ -310,18 +507,21 @@
/* skip or-specifiers */
if (arg_p->ar_short_arg == ARGV_OR
- || arg_p->ar_short_arg == ARGV_XOR)
+ || arg_p->ar_short_arg == ARGV_XOR) {
continue;
+ }
/* skip non booleans */
- if (HAS_ARG(arg_p->ar_type))
+ if (HAS_ARG(arg_p->ar_type)) {
continue;
+ }
/* skip args with no short component */
- if (arg_p->ar_short_arg == NULLC)
+ if (arg_p->ar_short_arg == '\0') {
continue;
+ }
- if (! mark) {
+ if (! mark_b) {
len = 2 + SHORT_PREFIX_LENGTH;
prefix = " [";
@@ -340,7 +540,7 @@
(void)fprintf(argv_error_stream, "%s%s", prefix, SHORT_PREFIX);
col_c += len;
- mark = ARGV_TRUE;
+ mark_b = ARGV_TRUE;
}
len = 1;
@@ -359,7 +559,7 @@
col_c++;
}
- if (mark) {
+ if (mark_b) {
(void)fprintf(argv_error_stream, "]");
col_c++;
}
@@ -371,15 +571,18 @@
/* skip or-specifiers */
if (arg_p->ar_short_arg == ARGV_OR
- || arg_p->ar_short_arg == ARGV_XOR)
+ || arg_p->ar_short_arg == ARGV_XOR) {
continue;
+ }
/* skip booleans types */
- if (! HAS_ARG(arg_p->ar_type))
+ if (! HAS_ARG(arg_p->ar_type)) {
continue;
+ }
if (arg_p->ar_var_label == NULL) {
- if (ARGV_TYPE(arg_p->ar_type) == ARGV_BOOL_ARG) {
+ if (ARGV_TYPE(arg_p->ar_type) == ARGV_BOOL_ARG
+ || ARGV_TYPE(arg_p->ar_type) == ARGV_BOOL_INT_ARG) {
var_str = BOOL_ARG_LABEL;
var_len = BOOL_ARG_LENGTH;
}
@@ -451,102 +654,162 @@
(void)fprintf(argv_error_stream, "\n");
- if (flag == GLOBAL_USAGE_SHORTREM)
+ if (flag == GLOBAL_USAGE_SHORTREM) {
(void)fprintf(argv_error_stream,
"%*.*sUse the '%s%s' argument for more assistance.\n",
(int)USAGE_LABEL_LENGTH, (int)USAGE_LABEL_LENGTH, "",
LONG_PREFIX, USAGE_ARG);
+ }
}
/*
- * Display an argument type while keeping track of COL_C.
+ * static void display_arg
+ *
+ * DESCRIPTION:
+ *
+ * Display an argument type while keeping track of the column we are
+ * in.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * stream - Output stream we are writing to.
+ *
+ * arg_p - Argument that we are displaying.
+ *
+ * max - Maximum column position to write to.
+ *
+ * col_cp - Pointer to an integer to record the column position.
*/
-LOCAL void display_arg(FILE *stream, const argv_t *arg_p, const int max,
- int *col_c)
+static void display_arg(FILE *stream, const argv_t *arg_p, const int max,
+ int *col_cp)
{
int var_len, len;
- if (arg_p->ar_var_label == NULL)
+ if (arg_p->ar_var_label == NULL) {
var_len = 0;
- else
+ }
+ else {
var_len = strlen(arg_p->ar_var_label);
+ }
switch (ARGV_TYPE(arg_p->ar_type)) {
case ARGV_BOOL:
case ARGV_BOOL_NEG:
case ARGV_INCR:
+ case ARGV_BOOL_INT:
+ case ARGV_BOOL_INT_NEG:
break;
case ARGV_BOOL_ARG:
+ case ARGV_BOOL_INT_ARG:
(void)fprintf(stream, "%s", BOOL_ARG_LABEL);
- (*col_c) += BOOL_ARG_LENGTH;
+ (*col_cp) += BOOL_ARG_LENGTH;
break;
case ARGV_CHAR:
- case ARGV_CHARP:
- case ARGV_FLOAT:
+ case ARGV_CHAR_P:
case ARGV_SHORT:
+ case ARGV_U_SHORT:
case ARGV_INT:
case ARGV_U_INT:
case ARGV_LONG:
case ARGV_U_LONG:
+ case ARGV_FLOAT:
+ case ARGV_DOUBLE:
case ARGV_BIN:
case ARGV_OCT:
case ARGV_HEX:
+ case ARGV_SIZE:
+ case ARGV_U_SIZE:
if (arg_p->ar_var_label == NULL) {
- len = max - *col_c;
+ len = max - *col_cp;
(void)fprintf(stream, "%-.*s", len, UNKNOWN_ARG);
- *col_c += MIN(len, UNKNOWN_ARG_LENGTH);
+ *col_cp += MIN(len, (int)UNKNOWN_ARG_LENGTH);
}
else {
- len = max - *col_c;
+ len = max - *col_cp;
(void)fprintf(stream, "%-.*s", len, arg_p->ar_var_label);
- *col_c += MIN(len, var_len);
+ *col_cp += MIN(len, var_len);
}
break;
}
}
/*
- * Display an option entry ARG_P to STREAM while counting COL_C.
+ * static void display_option
+ *
+ * DESCRIPTION:
+ *
+ * Display an option entry while while keeping track of the column we
+ * are in.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * stream - Output stream we are writing to.
+ *
+ * arg_p - Argument that we are displaying.
+ *
+ * max - Maximum column position to write to.
+ *
+ * col_cp - Pointer to an integer to record the column position.
*/
-LOCAL void display_option(FILE *stream, const argv_t *arg_p, int *col_c)
+static void display_option(FILE *stream, const argv_t *arg_p, int *col_cp)
{
- if (stream == NULL)
+ if (stream == NULL) {
return;
+ }
(void)fputc('[', stream);
- (*col_c)++;
+ (*col_cp)++;
/* arg maybe does not have a -? preface */
if (arg_p->ar_short_arg != ARGV_MAYBE) {
(void)fprintf(stream, "%s%c",
SHORT_PREFIX, arg_p->ar_short_arg);
- *col_c += SHORT_PREFIX_LENGTH + 1;
+ *col_cp += SHORT_PREFIX_LENGTH + 1;
if (HAS_ARG(arg_p->ar_type)) {
/* display optional argument */
(void)fputc(' ', stream);
- (*col_c)++;
+ (*col_cp)++;
}
}
- display_arg(stream, arg_p, LONG_COLUMN - 1, col_c);
+ display_arg(stream, arg_p, LONG_COLUMN - 1, col_cp);
(void)fputc(']', stream);
- (*col_c)++;
+ (*col_cp)++;
}
/*
+ * static void usage_long
+ *
+ * DESCRIPTION:
+ *
* Print a long-format usage message.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ars - Array of argv_t structures whose usage we are printing.
*/
-LOCAL void usage_long(const argv_t *args)
+static void usage_long(const argv_t *args)
{
const argv_t *arg_p;
int col_c, len;
- if (argv_error_stream == NULL)
+ if (argv_error_stream == NULL) {
return;
+ }
/* print the usage message header */
(void)fprintf(argv_error_stream, "%s%s\n", USAGE_LABEL, argv_program);
@@ -555,8 +818,9 @@
for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++) {
/* skip or specifiers */
- if (arg_p->ar_short_arg == ARGV_OR || arg_p->ar_short_arg == ARGV_XOR)
+ if (arg_p->ar_short_arg == ARGV_OR || arg_p->ar_short_arg == ARGV_XOR) {
continue;
+ }
/* indent to the short-option col_c */
(void)fprintf(argv_error_stream, "%*.*s", SHORT_COLUMN, SHORT_COLUMN, "");
@@ -565,15 +829,21 @@
col_c = SHORT_COLUMN;
/* print the short-arg stuff if there */
- if (arg_p->ar_short_arg == NULLC) {
+ if (arg_p->ar_short_arg == '\0') {
(void)fputc('[', argv_error_stream);
col_c++;
}
else {
- if (arg_p->ar_short_arg == ARGV_MAND)
+ if (arg_p->ar_short_arg == '\0') {
+ ;
+ }
+ else if (arg_p->ar_short_arg == ARGV_MAND) {
display_arg(argv_error_stream, arg_p, COMMENT_COLUMN, &col_c);
- else
+ }
+ else {
+ /* ARGV_MAYBE handled here */
display_option(argv_error_stream, arg_p, &col_c);
+ }
/* put the long-option message on the correct column */
if (col_c < LONG_COLUMN) {
@@ -586,18 +856,18 @@
/* print the long-option message */
if (arg_p->ar_long_arg != NULL) {
len = COMMENT_COLUMN - col_c - (LONG_PREFIX_LENGTH + 1);
- if (arg_p->ar_short_arg != NULLC) {
+ if (arg_p->ar_short_arg != '\0') {
(void)fprintf(argv_error_stream, "%s", LONG_LABEL);
col_c += LONG_LABEL_LENGTH;
len -= LONG_LABEL_LENGTH;
}
(void)fprintf(argv_error_stream, "%s%-.*s",
LONG_PREFIX, len, arg_p->ar_long_arg);
- col_c += LONG_PREFIX_LENGTH + MIN(len, strlen(arg_p->ar_long_arg));
+ col_c += LONG_PREFIX_LENGTH + MIN(len, (int)strlen(arg_p->ar_long_arg));
}
/* add the optional argument if no short-arg */
- if (arg_p->ar_short_arg == NULLC) {
+ if (arg_p->ar_short_arg == '\0') {
if (HAS_ARG(arg_p->ar_type)) {
(void)fputc(' ', argv_error_stream);
col_c++;
@@ -629,22 +899,41 @@
}
/*
- * Do the usage depending on FLAG.
+ * static void do_usage
+ *
+ * DESCRIPTION:
+ *
+ * Print the usage messages.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * args - Array of argv_t structures.
+ *
+ * flag - Users flags which will tell us whether to display short or
+ * long usage messages.
*/
-LOCAL void do_usage(const argv_t *args, const int flag)
+static void do_usage(const argv_t *args, const int flag)
{
- if (argv_error_stream == NULL)
+ if (argv_error_stream == NULL) {
return;
+ }
- if (flag == GLOBAL_USAGE_SEE)
+ if (flag == GLOBAL_USAGE_SEE) {
(void)fprintf(argv_error_stream,
"%*.*sUse the '%s%s' argument for assistance.\n",
(int)USAGE_LABEL_LENGTH, (int)USAGE_LABEL_LENGTH, "",
LONG_PREFIX, USAGE_ARG);
- else if (flag == GLOBAL_USAGE_SHORT || flag == GLOBAL_USAGE_SHORTREM)
+ }
+ else if (flag == GLOBAL_USAGE_SHORT || flag == GLOBAL_USAGE_SHORTREM) {
usage_short(args, flag);
- else if (flag == GLOBAL_USAGE_LONG || flag == GLOBAL_USAGE_ALL)
+ }
+ else if (flag == GLOBAL_USAGE_LONG || flag == GLOBAL_USAGE_ALL) {
usage_long(args);
+ }
if (flag == GLOBAL_USAGE_ALL) {
(void)fprintf(argv_error_stream, "\n");
@@ -682,122 +971,128 @@
/******************************* preprocessing *******************************/
/*
- * Preprocess argument array ARGS of NUM_ARGS entries and set the MAND
- * and MAYBE boolean arrays. Returns [NO]ERROR.
+ * static int preprocess_array
+ *
+ * DESCRIPTION:
+ *
+ * Preprocess argument array entries and set the mandatory and maybe
+ * flags.
+ *
+ * RETURNS:
+ *
+ * Success - 0
+ *
+ * Faulure - -1
+ *
+ * ARGUMENTS:
+ *
+ * args - Array of argv_t structures.
+ *
+ * arg_n - Number of entries in the argv_t array. We need this for a
+ * couple of reasons.
*/
-LOCAL int preprocess_array(argv_t *args, const int num_args)
+static int preprocess_array(argv_t *args, const int arg_n)
{
argv_t *arg_p;
- char mand_array = ARGV_FALSE, maybe_field = ARGV_FALSE;
+ int mand_array_b = ARGV_FALSE, maybe_field_b = ARGV_FALSE;
/* count the args and find the first mandatory */
- for (arg_p = args; arg_p < args + num_args; arg_p++) {
+ for (arg_p = args; arg_p < args + arg_n; arg_p++) {
/* clear internal flags */
arg_p->ar_type &= ~ARGV_FLAG_USED;
/* do we have a mandatory-array? */
if (arg_p->ar_short_arg == ARGV_MAND) {
- if (mand_array) {
- if (argv_error_stream != NULL)
+ if (mand_array_b) {
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, no ARGV_MAND's can follow a MAND or MAYBE array\n",
argv_program, INTERNAL_ERROR_NAME);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return ERROR;
}
- if (maybe_field) {
- if (argv_error_stream != NULL)
+ if (maybe_field_b) {
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, no ARGV_MAND's can follow a ARGV_MAYBE\n",
argv_program, INTERNAL_ERROR_NAME);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return ERROR;
}
-#if 0
- if (arg_p->ar_long_arg != NULL) {
- if (argv_error_stream != NULL)
- (void)fprintf(argv_error_stream,
- "%s: %s, ARGV_MAND's should not have long-options\n",
- argv_program, INTERNAL_ERROR_NAME);
- if (argv_interactive)
- (void)exit(EXIT_CODE);
- return ERROR;
+ if (arg_p->ar_type & ARGV_FLAG_ARRAY) {
+ mand_array_b = ARGV_TRUE;
}
-#endif
-
- if (arg_p->ar_type & ARGV_ARRAY)
- mand_array = ARGV_TRUE;
}
/* do we have a maybe field? */
if (arg_p->ar_short_arg == ARGV_MAYBE) {
- if (mand_array) {
- if (argv_error_stream != NULL)
+ if (mand_array_b) {
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, no ARGV_MAYBE's can follow a MAND or MAYBE array\n",
argv_program, INTERNAL_ERROR_NAME);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return ERROR;
}
- maybe_field = ARGV_TRUE;
- if (arg_p->ar_type & ARGV_ARRAY)
- mand_array = ARGV_TRUE;
+ maybe_field_b = ARGV_TRUE;
+ if (arg_p->ar_type & ARGV_FLAG_ARRAY) {
+ mand_array_b = ARGV_TRUE;
+ }
}
/* handle initializing the argument array */
- if (arg_p->ar_type & ARGV_ARRAY) {
+ if (arg_p->ar_type & ARGV_FLAG_ARRAY) {
argv_array_t *arrp = (argv_array_t *)arg_p->ar_variable;
if (! HAS_ARG(arg_p->ar_type)) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, cannot have an array of boolean values\n",
argv_program, INTERNAL_ERROR_NAME);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return ERROR;
}
if (ARGV_TYPE(arg_p->ar_type) == ARGV_INCR) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, cannot have an array of incremental values\n",
argv_program, INTERNAL_ERROR_NAME);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return ERROR;
}
- arrp->aa_entryn = 0;
- }
-
-#if 0
- /* must have a valid ar_short_arg */
- if (arg_p->ar_short_arg == NULLC) {
- if (argv_error_stream != NULL)
- (void)fprintf(argv_error_stream,
- "%s: %s, short-option character is '\\0'\n",
- argv_program, INTERNAL_ERROR_NAME);
- if (argv_interactive)
- (void)exit(EXIT_CODE);
- return ERROR;
+ arrp->aa_entry_n = 0;
}
-#endif
/* verify variable pointer */
if (arg_p->ar_variable == NULL
&& arg_p->ar_short_arg != ARGV_OR
&& arg_p->ar_short_arg != ARGV_XOR) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, NULL variable specified in arg array\n",
argv_program, INTERNAL_ERROR_NAME);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return ERROR;
}
@@ -806,25 +1101,29 @@
|| arg_p->ar_short_arg == ARGV_XOR) {
/* that they are not at the start or end of list */
- if (arg_p == args || arg_p >= (args + num_args - 1)) {
- if (argv_error_stream != NULL)
+ if (arg_p == args || arg_p >= (args + arg_n - 1)) {
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, ARGV_[X]OR entries cannot be at start or end of array\n",
argv_program, INTERNAL_ERROR_NAME);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return ERROR;
}
/* that two aren't next to each other */
if ((arg_p - 1)->ar_short_arg == ARGV_OR
|| (arg_p - 1)->ar_short_arg == ARGV_XOR) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, two ARGV_[X]OR entries cannot be next to each other\n",
argv_program, INTERNAL_ERROR_NAME);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return ERROR;
}
}
@@ -834,52 +1133,76 @@
}
/*
- * Translate string argument ARG into VAR depending on its TYPE.
- * Returns [NO]ERROR.
+ * static int string_to_value
+ *
+ * DESCRIPTION:
+ *
+ * Translate string value argument into a variable value depending on
+ * its type.
+ *
+ * RETURNS:
+ *
+ * Success - 0
+ *
+ * Faulure - -1
+ *
+ * ARGUMENTS:
+ *
+ * arg - Argument string.
+ *
+ * var - Pointer to our variable.
+ *
+ * type - Type of the variable.
*/
-LOCAL int translate_value(const char *arg, ARGV_PNT var,
- const short type)
+static int string_to_value(const char *arg, ARGV_PNT var,
+ const unsigned int type)
{
argv_array_t *arr_p;
argv_type_t *type_p;
- int val_type = ARGV_TYPE(type), size = 0;
+ unsigned int val_type = ARGV_TYPE(type), size = 0;
/* find the type and the size for array */
- for (type_p = argv_types; type_p->at_value != 0; type_p++)
+ for (type_p = argv_types; type_p->at_value != 0; type_p++) {
if (type_p->at_value == val_type) {
size = type_p->at_size;
break;
}
+ }
if (type_p->at_value == 0) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream, "%s: illegal variable type %d\n",
__FILE__, val_type);
+ }
return ERROR;
}
- if (type & ARGV_ARRAY) {
+ if (type & ARGV_FLAG_ARRAY) {
arr_p = (argv_array_t *)var;
- if (arr_p->aa_entryn == 0)
+ if (arr_p->aa_entry_n == 0) {
arr_p->aa_entries = (char *)malloc(ARRAY_INCR *size);
- else if (arr_p->aa_entryn % ARRAY_INCR == 0)
+ }
+ else if (arr_p->aa_entry_n % ARRAY_INCR == 0) {
arr_p->aa_entries =
- (char *)realloc(arr_p->aa_entries, (arr_p->aa_entryn + ARRAY_INCR) *
+ (char *)realloc(arr_p->aa_entries, (arr_p->aa_entry_n + ARRAY_INCR) *
size);
+ }
if (arr_p->aa_entries == NULL) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: memory error during argument processing\n",
argv_program);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return ERROR;
}
- var = (char *)(arr_p->aa_entries) + arr_p->aa_entryn * size;
- arr_p->aa_entryn++;
+ var = (char *)(arr_p->aa_entries) + arr_p->aa_entry_n * size;
+ arr_p->aa_entry_n++;
}
/* translate depending on type */
@@ -887,34 +1210,64 @@
case ARGV_BOOL:
/* if no close argument, set to true */
- if (arg == NULL)
+ if (arg == NULL) {
*(char *)var = ARGV_TRUE;
+ }
+ else if (*(char *)arg == 't' || *(char *)arg == 'T'
+ || *(char *)arg == 'y' || *(char *)arg == 'Y'
+ || *(char *)arg == '1') {
+ *(char *)var = ARGV_TRUE;
+ }
+ else {
+ *(char *)var = ARGV_FALSE;
+ }
+ break;
+
+ case ARGV_BOOL_NEG:
+ /* if no close argument, set to false */
+ if (arg == NULL) {
+ *(char *)var = ARGV_FALSE;
+ }
else if (*(char *)arg == 't' || *(char *)arg == 'T'
|| *(char *)arg == 'y' || *(char *)arg == 'Y'
- || *(char *)arg == '1')
+ || *(char *)arg == '1') {
*(char *)var = ARGV_TRUE;
- else
+ }
+ else {
+ *(char *)var = ARGV_FALSE;
+ }
+ break;
+
+ case ARGV_BOOL_ARG:
+ if (*(char *)arg == 't' || *(char *)arg == 'T'
+ || *(char *)arg == 'y' || *(char *)arg == 'Y'
+ || *(char *)arg == '1') {
+ *(char *)var = ARGV_TRUE;
+ }
+ else {
*(char *)var = ARGV_FALSE;
+ }
break;
case ARGV_CHAR:
*(char *)var = *(char *)arg;
break;
- case ARGV_CHARP:
+ case ARGV_CHAR_P:
*(char **)var = string_copy((char *)arg);
- if (*(char **)var == NULL)
+ if (*(char **)var == NULL) {
return ERROR;
- break;
-
- case ARGV_FLOAT:
- *(float *)var = (float)atof(arg);
+ }
break;
case ARGV_SHORT:
*(short *)var = (short)atoi(arg);
break;
+ case ARGV_U_SHORT:
+ *(unsigned short *)var = (unsigned short)atoi(arg);
+ break;
+
case ARGV_INT:
*(int *)var = atoi(arg);
break;
@@ -931,6 +1284,14 @@
*(unsigned long *)var = atol(arg);
break;
+ case ARGV_FLOAT:
+ (void)sscanf(arg, "%f", (float *)var);
+ break;
+
+ case ARGV_DOUBLE:
+ (void)sscanf(arg, "%lf", (double *)var);
+ break;
+
case ARGV_BIN:
*(int *)var = btoi(arg);
break;
@@ -943,158 +1304,423 @@
*(int *)var = htoi(arg);
break;
- case ARGV_BOOL_NEG:
- /* if no close argument, set to false */
- if (arg == NULL)
- *(char *)var = ARGV_FALSE;
- else if (*(char *)arg == 't' || *(char *)arg == 'T'
- || *(char *)arg == 'y' || *(char *)arg == 'Y'
- || *(char *)arg == '1')
- *(char *)var = ARGV_TRUE;
- else
- *(char *)var = ARGV_FALSE;
- break;
-
case ARGV_INCR:
/* if no close argument then increment else set the value */
- if (arg == NULL)
+ if (arg == NULL) {
(*(int *)var)++;
- else
+ }
+ else {
*(int *)var = atoi(arg);
+ }
break;
- case ARGV_BOOL_ARG:
+ case ARGV_SIZE:
+ {
+ const char *arg_p;
+ long val;
+
+ /* take initial integer point */
+ val = atol(arg);
+ for (arg_p = arg;
+ *arg_p == ' ' || *arg_p == '-' || *arg_p == '+'
+ || (*arg_p >= '0' && *arg_p <= '9');
+ arg_p++) {
+ }
+ if (*arg_p == 'b' || *arg_p == 'B') {
+ val *= 1;
+ }
+ else if (*arg_p == 'k' || *arg_p == 'B') {
+ val *= 1024;
+ }
+ else if (*arg_p == 'm' || *arg_p == 'M') {
+ val *= 1024 * 1024;
+ }
+ else if (*arg_p == 'g' || *arg_p == 'G') {
+ val *= 1024 * 1024 * 1024;
+ }
+ *(long *)var = val;
+ }
+ break;
+
+ case ARGV_U_SIZE:
+ {
+ const char *arg_p;
+ unsigned long val;
+
+ /* take initial integer point */
+ val = (unsigned long)atol(arg);
+ for (arg_p = arg;
+ *arg_p == ' ' || *arg_p == '-' || *arg_p == '+'
+ || (*arg_p >= '0' && *arg_p <= '9');
+ arg_p++) {
+ }
+ if (*arg_p == 'b' || *arg_p == 'B') {
+ val *= 1;
+ }
+ else if (*arg_p == 'k' || *arg_p == 'B') {
+ val *= 1024;
+ }
+ else if (*arg_p == 'm' || *arg_p == 'M') {
+ val *= 1024 * 1024;
+ }
+ else if (*arg_p == 'g' || *arg_p == 'G') {
+ val *= 1024 * 1024 * 1024;
+ }
+ *(unsigned long *)var = val;
+ }
+ break;
+
+ case ARGV_BOOL_INT:
+ /* if no close argument, set to true */
+ if (arg == NULL) {
+ *(int *)var = ARGV_TRUE;
+ }
+ else if (*(char *)arg == 't' || *(char *)arg == 'T'
+ || *(char *)arg == 'y' || *(char *)arg == 'Y'
+ || *(char *)arg == '1') {
+ *(int *)var = ARGV_TRUE;
+ }
+ else {
+ *(int *)var = ARGV_FALSE;
+ }
+ break;
+
+ case ARGV_BOOL_INT_NEG:
+ /* if no close argument, set to false */
+ if (arg == NULL) {
+ *(int *)var = ARGV_FALSE;
+ }
+ else if (*(char *)arg == 't' || *(char *)arg == 'T'
+ || *(char *)arg == 'y' || *(char *)arg == 'Y'
+ || *(char *)arg == '1') {
+ *(int *)var = ARGV_TRUE;
+ }
+ else {
+ *(int *)var = ARGV_FALSE;
+ }
+ break;
+
+ case ARGV_BOOL_INT_ARG:
if (*(char *)arg == 't' || *(char *)arg == 'T'
|| *(char *)arg == 'y' || *(char *)arg == 'Y'
- || *(char *)arg == '1')
- *(char *)var = ARGV_TRUE;
- else
- *(char *)var = ARGV_FALSE;
+ || *(char *)arg == '1') {
+ *(int *)var = ARGV_TRUE;
+ }
+ else {
+ *(int *)var = ARGV_FALSE;
+ }
break;
+
}
return NOERROR;
}
/*
- * Translate value from VAR into string STR depending on its TYPE.
+ * static int value_to_string
+ *
+ * DESCRIPTION:
+ *
+ * Translate value from variable depending on its type intoits string
+ * represetnation in buffer.
+ *
+ * RETURNS:
+ *
+ * Number of characters added to the buffer.
+ *
+ * ARGUMENTS:
+ *
+ * var - Variable pointer.
+ *
+ * type - Type of variable.
+ *
+ * buf - User buffer to convert into.
+ *
+ * buf_size - Size of the user buffer.
*/
-LOCAL void display_value(const ARGV_PNT var, const short type)
+static int value_to_string(const ARGV_PNT var, const unsigned int type,
+ char *buf, const int buf_size)
{
- int val_type = ARGV_TYPE(type);
+ int len = 0;
+
+ /*
+ * NOTE: without a snprintf, we have to hope that buf_size > integer
+ * and the string repesentations of the numbers.
+ */
/* translate depending on type */
- switch (val_type) {
+ switch (ARGV_TYPE(type)) {
case ARGV_BOOL:
case ARGV_BOOL_NEG:
case ARGV_BOOL_ARG:
- if (*(char *)var)
- (void)fprintf(argv_error_stream, "ARGV_TRUE");
- else
- (void)fprintf(argv_error_stream, "ARGV_FALSE");
+ if (*(char *)var) {
+ strncpy(buf, "true (! 0)", buf_size);
+ }
+ else {
+ strncpy(buf, "false (0)", buf_size);
+ }
+ buf[buf_size - 1] = '\0';
+ len = strlen(buf);
break;
case ARGV_CHAR:
- (void)fprintf(argv_error_stream, "'%s'", expand_buf((char *)var, 1));
+ len = expand_buf((char *)var, 1, buf, buf_size);
break;
- case ARGV_CHARP:
- {
- int len;
- if (*(char **)var == NULL)
- (void)fprintf(argv_error_stream, "(null)");
- else {
- len = strlen(*(char **)var);
- (void)fprintf(argv_error_stream, "\"%s\"",
- expand_buf(*(char **)var, len));
- }
+ case ARGV_CHAR_P:
+ if (*(char **)var == NULL) {
+ strncpy(buf, "(null)", buf_size);
+ buf[buf_size - 1] = '\0';
+ len = strlen(buf);
+ }
+ else {
+ len = expand_buf(*(char **)var, -1, buf, buf_size);
}
break;
- case ARGV_FLOAT:
- (void)fprintf(argv_error_stream, "%f", *(float *)var);
+ case ARGV_SHORT:
+ (void)sprintf(buf, "%d", *(short *)var);
+ len = strlen(buf);
break;
- case ARGV_SHORT:
- (void)fprintf(argv_error_stream, "%d", *(short *)var);
+ case ARGV_U_SHORT:
+ (void)sprintf(buf, "%d", *(unsigned short *)var);
+ len = strlen(buf);
break;
case ARGV_INT:
- case ARGV_INCR:
- (void)fprintf(argv_error_stream, "%d", *(int *)var);
+ (void)sprintf(buf, "%d", *(int *)var);
+ len = strlen(buf);
break;
case ARGV_U_INT:
- (void)fprintf(argv_error_stream, "%u", *(unsigned int *)var);
+ (void)sprintf(buf, "%u", *(unsigned int *)var);
+ len = strlen(buf);
break;
case ARGV_LONG:
- (void)fprintf(argv_error_stream, "%ld", *(long *)var);
+ (void)sprintf(buf, "%ld", *(long *)var);
+ len = strlen(buf);
break;
case ARGV_U_LONG:
- (void)fprintf(argv_error_stream, "%lu", *(unsigned long *)var);
+ (void)sprintf(buf, "%lu", *(unsigned long *)var);
+ len = strlen(buf);
+ break;
+
+ case ARGV_FLOAT:
+ (void)sprintf(buf, "%f", *(float *)var);
+ len = strlen(buf);
+ break;
+
+ case ARGV_DOUBLE:
+ (void)sprintf(buf, "%f", *(double *)var);
+ len = strlen(buf);
break;
/* this should be a routine */
case ARGV_BIN:
{
- int bit_c;
- char first = ARGV_FALSE;
+ int bit_c, bit, first_b = ARGV_FALSE;
+ char binary[2 + 128 + 1], *bin_p = binary;
- (void)fputc('0', argv_error_stream);
+ if (*(int *)var == 0) {
+ strncpy(buf, "0", buf_size);
+ }
+ else {
- if (*(int *)var != 0) {
- (void)fputc('b', argv_error_stream);
+ /* initially write binary number into tmp buffer, then copy into out */
+ *bin_p++ = '0';
+ *bin_p++ = 'b';
for (bit_c = sizeof(int) * BITS_IN_BYTE - 1; bit_c >= 0; bit_c--) {
- int bit = *(int *)var & (1 << bit_c);
+ bit = *(int *)var & (1 << bit_c);
if (bit == 0) {
- if (first)
- (void)fputc('0', argv_error_stream);
+ if (first_b) {
+ *bin_p++ = '0';
+ }
}
else {
- (void)fputc('1', argv_error_stream);
- first = ARGV_TRUE;
+ *bin_p++ = '1';
+ first_b = ARGV_TRUE;
}
}
+
+ /* add on the decimal equivalent */
+ (void)sprintf(bin_p, " (%d)", *(int *)var);
+ /* find the \0 at end */
+ for (; *bin_p != '\0'; bin_p++) {
+ }
+
+ /* now we copy from the binary buffer to the output */
+ strncpy(buf, binary, buf_size);
}
+
+ buf[buf_size - 1] = '\0';
+ len = strlen(buf);
}
break;
case ARGV_OCT:
- (void)fprintf(argv_error_stream, "%#o", *(int *)var);
+ if (*(int *)var == 0) {
+ (void)strncpy(buf, "0", buf_size);
+ buf[buf_size - 1] = '\0';
+ }
+ else {
+ (void)sprintf(buf, "%#o (%d)", *(int *)var, *(int *)var);
+ }
+ len = strlen(buf);
break;
case ARGV_HEX:
- (void)fprintf(argv_error_stream, "%#x", *(int *)var);
+ if (*(int *)var == 0) {
+ (void)strcpy(buf, "0");
+ }
+ else {
+ (void)sprintf(buf, "%#x (%d)", *(int *)var, *(int *)var);
+ }
+ len = strlen(buf);
+ break;
+
+ case ARGV_INCR:
+ (void)sprintf(buf, "%d", *(int *)var);
+ len = strlen(buf);
+ break;
+
+ case ARGV_SIZE:
+ {
+ long morf, val = *(long *)var;
+
+ if (val == 0) {
+ (void)strcpy(buf, "0");
+ }
+ else if (val % (1024 * 1024 * 1024) == 0) {
+ morf = val / (1024 * 1024 * 1024);
+ (void)sprintf(buf, "%ldg (%ld)", morf, val);
+ }
+ else if (val % (1024 * 1024) == 0) {
+ morf = val / (1024 * 1024);
+ (void)sprintf(buf, "%ldm (%ld)", morf, val);
+ }
+ else if (val % 1024 == 0) {
+ morf = val / 1024;
+ (void)sprintf(buf, "%ldk (%ld)", morf, val);
+ }
+ else {
+ (void)sprintf(buf, "%ld", val);
+ }
+
+ len = strlen(buf);
+ }
+ break;
+
+ case ARGV_U_SIZE:
+ {
+ unsigned long morf, val = *(unsigned long *)var;
+
+ if (val == 0) {
+ (void)strcpy(buf, "0");
+ }
+ else if (val % (1024 * 1024 * 1024) == 0) {
+ morf = val / (1024 * 1024 * 1024);
+ (void)sprintf(buf, "%ldg (%ld)", morf, val);
+ }
+ else if (val % (1024 * 1024) == 0) {
+ morf = val / (1024 * 1024);
+ (void)sprintf(buf, "%ldm (%ld)", morf, val);
+ }
+ else if (val % 1024 == 0) {
+ morf = val / 1024;
+ (void)sprintf(buf, "%ldk (%ld)", morf, val);
+ }
+ else {
+ (void)sprintf(buf, "%ld", val);
+ }
+
+ len = strlen(buf);
+ }
+ break;
+
+ case ARGV_BOOL_INT:
+ case ARGV_BOOL_INT_NEG:
+ case ARGV_BOOL_INT_ARG:
+ if (*(int *)var) {
+ strncpy(buf, "true (! 0)", buf_size);
+ }
+ else {
+ strncpy(buf, "false (0)", buf_size);
+ }
+ buf[buf_size - 1] = '\0';
+ len = strlen(buf);
+ break;
+
+ default:
+ strncpy(buf, "(unknown)", buf_size);
+ buf[buf_size - 1] = '\0';
+ len = strlen(buf);
break;
}
+
+ return len;
}
/*
- * Translate value from VAR into string STR depending on its TYPE.
+ * static void display_variables
+ *
+ * DESCRIPTION:
+ *
+ * Display all of the variable values from our array.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * args - Array of argv_t structures whose variables we are
+ * displaying.
*/
-LOCAL void display_variables(const argv_t *args)
+static void display_variables(const argv_t *args)
{
const argv_t *arg_p;
argv_type_t *type_p;
+ char buf[256];
+ int len, col_c, val_type;
/* run through the argument structure */
for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++) {
- int col_c, val_type = ARGV_TYPE(arg_p->ar_type);
+
+ val_type = ARGV_TYPE(arg_p->ar_type);
/* skip or specifiers */
- if (arg_p->ar_short_arg == ARGV_OR || arg_p->ar_short_arg == ARGV_XOR)
+ if (arg_p->ar_short_arg == ARGV_OR || arg_p->ar_short_arg == ARGV_XOR) {
continue;
+ }
col_c = 0;
- if (arg_p->ar_short_arg == ARGV_MAND)
+ if (arg_p->ar_short_arg == '\0') {
+ if (arg_p->ar_long_arg != NULL) {
+ len = COMMENT_COLUMN - col_c - (LONG_PREFIX_LENGTH + 1);
+ if (arg_p->ar_short_arg != '\0') {
+ (void)fprintf(argv_error_stream, "%s", LONG_LABEL);
+ col_c += LONG_LABEL_LENGTH;
+ len -= LONG_LABEL_LENGTH;
+ }
+ (void)fprintf(argv_error_stream, "%s%-.*s",
+ LONG_PREFIX, len, arg_p->ar_long_arg);
+ col_c += LONG_PREFIX_LENGTH + MIN(len,
+ (int)strlen(arg_p->ar_long_arg));
+ }
+ }
+ else if (arg_p->ar_short_arg == ARGV_MAND) {
display_arg(argv_error_stream, arg_p, COMMENT_COLUMN, &col_c);
- else
+ }
+ else {
+ /* ARGV_MAYBE handled here */
display_option(argv_error_stream, arg_p, &col_c);
+ }
/* put the type in the correct column */
if (col_c < LONG_COLUMN) {
@@ -1107,13 +1733,13 @@
type_p = NULL;
for (type_p = argv_types; type_p->at_value != 0; type_p++) {
if (type_p->at_value == ARGV_TYPE(arg_p->ar_type)) {
- int len, tlen;
+ int tlen;
len = COMMENT_COLUMN - col_c - 1;
tlen = strlen(type_p->at_name);
(void)fprintf(argv_error_stream, " %-.*s", len, type_p->at_name);
col_c += MIN(len, tlen);
- if (arg_p->ar_type & ARGV_ARRAY) {
+ if (arg_p->ar_type & ARGV_FLAG_ARRAY) {
(void)fprintf(argv_error_stream, "%s", ARRAY_LABEL);
col_c += sizeof(ARRAY_LABEL) - 1;
}
@@ -1127,7 +1753,7 @@
col_c = COMMENT_COLUMN;
}
- if (arg_p->ar_type & ARGV_ARRAY) {
+ if (arg_p->ar_type & ARGV_FLAG_ARRAY) {
argv_array_t *arr_p;
int entry_c, size = 0;
@@ -1140,20 +1766,25 @@
size = type_p->at_size;
arr_p = (argv_array_t *)arg_p->ar_variable;
- if (arr_p->aa_entryn == 0)
+ if (arr_p->aa_entry_n == 0) {
(void)fprintf(argv_error_stream, "no entries");
+ }
else {
- for (entry_c = 0; entry_c < arr_p->aa_entryn; entry_c++) {
+ for (entry_c = 0; entry_c < arr_p->aa_entry_n; entry_c++) {
ARGV_PNT var;
- if (entry_c > 0)
+ if (entry_c > 0) {
(void)fputc(',', argv_error_stream);
+ }
var = (char *)(arr_p->aa_entries) + entry_c * size;
- display_value(var, val_type);
+ len = value_to_string(var, val_type, buf, sizeof(buf));
+ (void)fwrite(buf, sizeof(char), len, argv_error_stream);
}
}
}
- else
- display_value(arg_p->ar_variable, val_type);
+ else {
+ len = value_to_string(arg_p->ar_variable, val_type, buf, sizeof(buf));
+ (void)fwrite(buf, sizeof(char), len, argv_error_stream);
+ }
(void)fputc('\n', argv_error_stream);
}
}
@@ -1161,18 +1792,36 @@
/************************** checking used arguments **************************/
/*
- * Check out if WHICH argument from ARGS has an *or* specified
- * attached to it. Returns [NO]ERROR
+ * static int check_or
+ *
+ * DESCRIPTION:
+ *
+ * Check out if an argument has an ARGV_OR attached to it and both
+ * variables have not been set.
+ *
+ * RETURNS:
+ *
+ * Success - 0
+ *
+ * Faulure - -1
+ *
+ * ARGUMENTS:
+ *
+ * args - Array of argv_t structures that we are checking.
+ *
+ * which_p - Pointer to the specific argument that we are checking for
+ * the ARGV_OR.
*/
-LOCAL int check_or(const argv_t *args, const argv_t *which)
+static int check_or(const argv_t *args, const argv_t *which_p)
{
const argv_t *arg_p, *match_p = NULL;
/* check ORs below */
- for (arg_p = which - 2; arg_p >= args; arg_p -= 2) {
+ for (arg_p = which_p - 2; arg_p >= args; arg_p -= 2) {
if ((arg_p + 1)->ar_short_arg != ARGV_OR
- && (arg_p + 1)->ar_short_arg != ARGV_XOR)
+ && (arg_p + 1)->ar_short_arg != ARGV_XOR) {
break;
+ }
if (arg_p->ar_type & ARGV_FLAG_USED) {
match_p = arg_p;
break;
@@ -1181,14 +1830,15 @@
/* check ORs above */
if (match_p == NULL) {
- /* NOTE: we assume that which is not pointing now to ARGV_LAST */
- for (arg_p = which + 2;
+ /* NOTE: we assume that which_p is not pointing now to ARGV_LAST */
+ for (arg_p = which_p + 2;
arg_p->ar_short_arg != ARGV_LAST
&& (arg_p - 1)->ar_short_arg != ARGV_LAST;
arg_p += 2) {
if ((arg_p - 1)->ar_short_arg != ARGV_OR
- && (arg_p - 1)->ar_short_arg != ARGV_XOR)
+ && (arg_p - 1)->ar_short_arg != ARGV_XOR) {
break;
+ }
if (arg_p->ar_type & ARGV_FLAG_USED) {
match_p = arg_p;
break;
@@ -1197,11 +1847,13 @@
}
/* did we not find a problem? */
- if (match_p == NULL)
+ if (match_p == NULL) {
return NOERROR;
+ }
- if (argv_error_stream == NULL)
+ if (argv_error_stream == NULL) {
return ERROR;
+ }
(void)fprintf(argv_error_stream,
"%s: %s, specify only one of the following:\n",
@@ -1209,27 +1861,49 @@
/* little hack to print the one that matched and the one we were checking */
for (;;) {
- if (match_p->ar_long_arg == NULL)
- (void)fprintf(argv_error_stream, " %s%c\n",
+ if (match_p->ar_long_arg == NULL) {
+ (void)fprintf(argv_error_stream, "%*.*s%s%c\n",
+ (int)USAGE_LABEL_LENGTH, (int)USAGE_LABEL_LENGTH, "",
SHORT_PREFIX, match_p->ar_short_arg);
- else
- (void)fprintf(argv_error_stream, " %s%c (%s%s)\n",
+ }
+ else {
+ (void)fprintf(argv_error_stream, "%*.*s%s%c (%s%s)\n",
+ (int)USAGE_LABEL_LENGTH, (int)USAGE_LABEL_LENGTH, "",
SHORT_PREFIX, match_p->ar_short_arg,
LONG_PREFIX, match_p->ar_long_arg);
+ }
- if (match_p == which)
+ if (match_p == which_p) {
break;
- match_p = which;
+ }
+ match_p = which_p;
}
return ERROR;
}
/*
- * Find all the XOR arguments and make sure each group has at least
- * one specified in it. Returns [NO]ERROR.
+ * static int check_xor
+ *
+ * DESCRIPTION:
+ *
+ * Check out if an argument has an ARGV_XOR attached to it and that at
+ * least one but not both variables have been set.
+ *
+ * RETURNS:
+ *
+ * Success - 0
+ *
+ * Faulure - -1
+ *
+ * ARGUMENTS:
+ *
+ * args - Array of argv_t structures that we are checking.
+ *
+ * which_p - Pointer to the specific argument that we are checking for
+ * the ARGV_XOR.
*/
-LOCAL int check_xor(const argv_t *args)
+static int check_xor(const argv_t *args)
{
const argv_t *start_p = NULL, *arg_p;
@@ -1237,8 +1911,9 @@
for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++) {
/* only check the XORs */
- if (arg_p->ar_short_arg != ARGV_XOR)
+ if (arg_p->ar_short_arg != ARGV_XOR) {
continue;
+ }
start_p = arg_p;
@@ -1246,31 +1921,37 @@
* NOTE: we are guaranteed that we are on a XOR so there is
* something below and above...
*/
- if ((arg_p - 1)->ar_type & ARGV_FLAG_USED)
+ if ((arg_p - 1)->ar_type & ARGV_FLAG_USED) {
start_p = NULL;
+ }
/* run through all XORs */
for (;;) {
arg_p++;
- if (arg_p->ar_type & ARGV_FLAG_USED)
+ if (arg_p->ar_type & ARGV_FLAG_USED) {
start_p = NULL;
- if ((arg_p + 1)->ar_short_arg != ARGV_XOR)
+ }
+ if ((arg_p + 1)->ar_short_arg != ARGV_XOR) {
break;
+ }
arg_p++;
}
/* were none of the xor's filled? */
- if (start_p != NULL)
+ if (start_p != NULL) {
break;
+ }
}
/* did we not find a problem? */
- if (start_p == NULL)
+ if (start_p == NULL) {
return NOERROR;
+ }
/* arg_p points to the first XOR which failed */
- if (argv_error_stream == NULL)
+ if (argv_error_stream == NULL) {
return ERROR;
+ }
(void)fprintf(argv_error_stream, "%s: %s, must specify one of:\n",
argv_program, USAGE_ERROR_NAME);
@@ -1280,61 +1961,119 @@
* NOTE: we are guaranteed that we are on a XOR so there is
* something below and above...
*/
- (void)fprintf(argv_error_stream, " %s%c",
+ (void)fprintf(argv_error_stream, "%*.*s%s%c",
+ (int)USAGE_LABEL_LENGTH, (int)USAGE_LABEL_LENGTH, "",
SHORT_PREFIX, (arg_p - 1)->ar_short_arg);
- if ((arg_p - 1)->ar_long_arg != NULL)
+ if ((arg_p - 1)->ar_long_arg != NULL) {
(void)fprintf(argv_error_stream, " (%s%s)",
LONG_PREFIX, (arg_p - 1)->ar_long_arg);
+ }
(void)fprintf(argv_error_stream, "\n");
- if (arg_p->ar_short_arg != ARGV_XOR)
+ if (arg_p->ar_short_arg != ARGV_XOR) {
break;
+ }
}
return ERROR;
}
/*
- * Check to see if any mandatory arguments left. Returns [NO]ERROR.
+ * static int check_mand
+ *
+ * DESCRIPTION:
+ *
+ * Verify that all of the mandatory arguments in our array have been
+ * specified.
+ *
+ * RETURNS:
+ *
+ * Success - 0
+ *
+ * Faulure - -1
+ *
+ * ARGUMENTS:
+ *
+ * args - Array of argv_t structures that we are checking.
*/
-LOCAL int check_mand(const argv_t *args)
+static int check_mand(const argv_t *args)
{
const argv_t *arg_p;
- int slot_c = 0;
+ int mand_c = 0, flag_c = 0;
/* see if there are any mandatory args left */
- for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++)
+ for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++) {
if (arg_p->ar_short_arg == ARGV_MAND
- && (! (arg_p->ar_type & ARGV_FLAG_USED))
- && ! (arg_p->ar_type & ARGV_ARRAY))
- slot_c++;
+ && (! (arg_p->ar_type & ARGV_FLAG_USED))) {
+ mand_c++;
+ }
+ if (arg_p->ar_type & ARGV_FLAG_MAND
+ && (! (arg_p->ar_type & ARGV_FLAG_USED))) {
+ flag_c++;
+ if (argv_error_stream != NULL) {
+ if (flag_c == 1) {
+ (void)fprintf(argv_error_stream,
+ "%s: %s, these mandatory flags must be specified:\n",
+ argv_program, USAGE_ERROR_NAME);
+ }
+ (void)fprintf(argv_error_stream, "%*.*s%s%c",
+ (int)USAGE_LABEL_LENGTH, (int)USAGE_LABEL_LENGTH, "",
+ SHORT_PREFIX, arg_p->ar_short_arg);
+ if (arg_p->ar_long_arg != NULL) {
+ (void)fprintf(argv_error_stream, " (%s%s)",
+ LONG_PREFIX, arg_p->ar_long_arg);
+ }
+ (void)fprintf(argv_error_stream, "\n");
+ }
+ }
+ }
- if (slot_c > 0) {
- if (argv_error_stream != NULL)
- (void)fprintf(argv_error_stream,
- "%s: %s, %d more mandatory argument%s must be specified\n",
- argv_program, USAGE_ERROR_NAME,
- slot_c, (slot_c == 1 ? "" : "s"));
- return ERROR;
+ if (mand_c > 0 && argv_error_stream != NULL) {
+ (void)fprintf(argv_error_stream,
+ "%s: %s, %d more mandatory argument%s must be specified\n",
+ argv_program, USAGE_ERROR_NAME,
+ mand_c, (mand_c == 1 ? "" : "s"));
}
- return NOERROR;
+ if (mand_c > 0 || flag_c > 0) {
+ return ERROR;
+ }
+ else {
+ return NOERROR;
+ }
}
/*
- * Check for any missing argument options. Returns [NO]ERROR
+ * static int check_opt
+ *
+ * DESCRIPTION:
+ *
+ * Check for any missing argument options.
+ *
+ * RETURNS:
+ *
+ * Success - 0
+ *
+ * Faulure - -1
+ *
+ * ARGUMENTS:
+ *
+ * queue_head - Head of the option queue.
+ *
+ * queue_tail - Tail of the option queue.
*/
-LOCAL int check_opt(void)
+static int check_opt(const int queue_head, const int queue_tail)
{
int queue_c;
- queue_c = QUEUE_COUNT();
+ queue_c = queue_head - queue_tail;
if (queue_c > 0) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, %d more option-argument%s must be specified\n",
argv_program, USAGE_ERROR_NAME,
queue_c, (queue_c == 1 ? "" : "s"));
+ }
return ERROR;
}
@@ -1344,42 +2083,75 @@
/**************************** argument processing ****************************/
/*
- * Read in arguments from PATH and run them from the GRID. OKAY_P is
- * a pointer to the boolean error marker. Returns [NO]ERROR.
+ * static void file_args
+ *
+ * DESCRIPTION:
+ *
+ * Read in arguments from a file and process them like they were
+ * specified on the command line.
+ *
+ * RETURNS:
+ *
+ * Success - 0
+ *
+ * Faulure - -1
+ *
+ * ARGUMENTS:
+ *
+ * path -> File of the arguments we are reading in.
+ *
+ * grid -> Array of argv_t structures we are using.
+ *
+ * queue_list <-> Our option queue for storing options to arguments.
+ *
+ * queue_head_p <-> Pointer to integer which will be updated with the
+ * head position in our option queue.
+ *
+ * queue_tail_p <-> Pointer to integer which will be updated with the
+ * tail position in our option queue.
+ *
+ * okay_bp <- Pointer to an integer which is set with 0 if the
+ * arguments specified in the env variable are somehow invalid.
*/
-LOCAL void file_args(const char *path, argv_t *grid, char *okay_p)
+static void file_args(const char *path, argv_t *grid,
+ argv_t **queue_list, int *queue_head_p,
+ int *queue_tail_p, int *okay_bp)
{
char **argv, **argv_p;
- int argc, max;
+ int arg_c, max;
FILE *infile;
char line[FILE_LINE_SIZE + 1], *line_p;
/* open the input file */
infile = fopen(path, "r");
if (infile == NULL) {
- *okay_p = ARGV_FALSE;
- if (argv_error_stream != NULL)
+ *okay_bp = ARGV_FALSE;
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: could not load command-line arguments from: %s\n",
argv_program, path);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return;
}
/* get an array of char * */
- argc = 0;
+ arg_c = 0;
max = ARRAY_INCR;
argv = malloc(sizeof(char *) * max);
if (argv == NULL) {
- *okay_p = ARGV_FALSE;
+ *okay_bp = ARGV_FALSE;
(void)fclose(infile);
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: memory error during argument processing\n",
argv_program);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return;
}
argv_p = argv;
@@ -1387,52 +2159,82 @@
/* read in the file lines */
while (fgets(line, FILE_LINE_SIZE, infile) != NULL) {
/* punch the \n at end of line */
- for (line_p = line; *line_p != '\n' && *line_p != '\0'; line_p++);
+ for (line_p = line; *line_p != '\n' && *line_p != '\0'; line_p++) {
+ }
*line_p = '\0';
*argv_p = string_copy(line);
if (*argv_p == NULL) {
- *okay_p = ARGV_FALSE;
+ *okay_bp = ARGV_FALSE;
return;
}
argv_p++;
- argc++;
- if (argc == max) {
+ arg_c++;
+ if (arg_c == max) {
max += ARRAY_INCR;
argv = realloc(argv, sizeof(char *) * max);
if (argv == NULL) {
- *okay_p = ARGV_FALSE;
+ *okay_bp = ARGV_FALSE;
(void)fclose(infile);
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: memory error during argument processing\n",
argv_program);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return;
}
- argv_p = argv + argc;
+ argv_p = argv + arg_c;
}
}
/* now do the list */
- do_list(grid, argc, argv, okay_p);
+ do_list(grid, arg_c, argv, queue_list, queue_head_p, queue_tail_p, okay_bp);
/* now free up the list */
- for (argv_p = argv; argv_p < argv + argc; argv_p++)
+ for (argv_p = argv; argv_p < argv + arg_c; argv_p++) {
free(*argv_p);
+ }
free(argv);
(void)fclose(infile);
}
/*
- * Process an argument in MATCH_P which looking at GRID. sets okay_p to
- * FALSE if the argument was not okay.
+ * static void do_arg
+ *
+ * DESCRIPTION:
+ *
+ * Process an argument in MATCH_P which looking at GRID. sets okay_p
+ * to FALSE if the argument was not okay.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * grid -> Our array of argv_t structures.
+ *
+ * match_p -> Entry in our argv_t structure array that matches the
+ * specified argument.
+ *
+ * close_p -> Pointer to the value closely associated (with an '=')
+ * with this option or NULL if none.
+ *
+ * queue_list <-> Our option queue for storing options to arguments.
+ *
+ * queue_head_p <-> Pointer to integer which will be updated with the
+ * head position in our option queue.
+ *
+ * okay_bp <- Pointer to an integer which is set with 0 if the
+ * arguments specified in the env variable are somehow invalid.
*/
-LOCAL void do_arg(argv_t *grid, argv_t *match_p, const char *close_p,
- char *okay_p)
+static void do_arg(argv_t *grid, argv_t *match_p, const char *close_p,
+ argv_t **queue_list, int *queue_head_p, int *okay_bp)
{
if (global_multi == GLOBAL_MULTI_REJECT) {
/*
@@ -1440,14 +2242,15 @@
* NOTE: should this be a warning or a non-error altogether?
*/
if (match_p->ar_type & ARGV_FLAG_USED
- && (! (match_p->ar_type & ARGV_ARRAY))
+ && (! (match_p->ar_type & ARGV_FLAG_ARRAY))
&& ARGV_TYPE(match_p->ar_type) != ARGV_INCR) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, you've already specified the '%c' argument\n",
argv_program, USAGE_ERROR_NAME,
match_p->ar_short_arg);
- *okay_p = ARGV_FALSE;
+ }
+ *okay_bp = ARGV_FALSE;
}
}
@@ -1460,7 +2263,7 @@
* don't return here else we might generate an XOR error
* because the argument wasn't specified
*/
- *okay_p = ARGV_FALSE;
+ *okay_bp = ARGV_FALSE;
}
/*
@@ -1469,69 +2272,157 @@
* else queue it for needing a value argument.
*/
if (global_close == GLOBAL_CLOSE_ENABLE && close_p != NULL) {
- if (translate_value(close_p, match_p->ar_variable,
- match_p->ar_type) != NOERROR)
- *okay_p = ARGV_FALSE;
+ if (string_to_value(close_p, match_p->ar_variable,
+ match_p->ar_type) != NOERROR) {
+ *okay_bp = ARGV_FALSE;
+ }
}
else if (! HAS_ARG(match_p->ar_type)) {
- if (translate_value(NULL, match_p->ar_variable,
- match_p->ar_type) != NOERROR)
- *okay_p = ARGV_FALSE;
+ if (string_to_value(NULL, match_p->ar_variable,
+ match_p->ar_type) != NOERROR) {
+ *okay_bp = ARGV_FALSE;
+ }
}
else if (global_close == GLOBAL_CLOSE_ENABLE && close_p != NULL) {
- if (translate_value(close_p, match_p->ar_variable,
- match_p->ar_type) != NOERROR)
- *okay_p = ARGV_FALSE;
+ if (string_to_value(close_p, match_p->ar_variable,
+ match_p->ar_type) != NOERROR) {
+ *okay_bp = ARGV_FALSE;
+ }
+ }
+ else {
+ queue_list[*queue_head_p] = match_p;
+ (*queue_head_p)++;
+ }
+}
+
+/*
+ * static int is_number
+ *
+ * DESCRIPTION:
+ *
+ * Examine an argument string to see if it really is a negative number
+ * being passed into a previously specified argument.
+ *
+ * Thanks much to Nick Kisseberth <nkissebe@hera.itg.uiuc.edu> for
+ * pointing out this oversight.
+ *
+ * RETURNS:
+ *
+ * 1 if a number otherwise 0.
+ *
+ * ARGUMENTS:
+ *
+ * str - String which may be a number.
+ */
+static int is_number(const char *str)
+{
+ const char *str_p;
+
+ /* empty strings are not numbers */
+ if (str[0] == '\0') {
+ return 0;
}
- else
- QUEUE_ENQUEUE(match_p);
+
+ /*
+ * All chars in the string should be number chars for it to be a
+ * number. Yes this will return yes if the argument is "00-" but
+ * we'll chalk this up to user error.
+ */
+ for (str_p = str; *str_p != '\0'; str_p++) {
+ if (strchr(NUMBER_ARG_CHARS, *str_p) == NULL) {
+ return 0;
+ }
+ }
+
+ return 1;
}
/*
- * Process a list of arguments ARGV and ARGV as it applies to ARGS.
- * on NUM_ARGS members. OKAY_P is a pointer to the boolean error
- * marker.
+ * static void do_list
+ *
+ * DESCRIPTION:
+ *
+ * Process a list of arguments with our array of argv_t structures
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * grid - Our array of argv_t structures.
+ *
+ * arg_c - Number of arguments in argv.
+ *
+ * argv - User argument array of character pointers.
+ *
+ * queue_list <-> Our option queue for storing options to arguments.
+ *
+ * queue_head_p <-> Pointer to integer which will be updated with the
+ * head position in our option queue.
+ *
+ * queue_tail_p <-> Pointer to integer which will be updated with the
+ * tail position in our option queue.
+ *
+ * okay_bp - Pointer to an integer which is set with 0 if the
+ * arguments specified in the env variable are somehow invalid.
*/
-LOCAL void do_list(argv_t *grid, const int argc, char **argv,
- char *okay_p)
+static void do_list(argv_t *grid, const int arg_c, char **argv,
+ argv_t **queue_list, int *queue_head_p,
+ int *queue_tail_p, int *okay_bp)
{
argv_t *grid_p, *match_p;
int len, char_c, unwant_c = 0;
- char last_arg = ARGV_FALSE;
+ int last_arg_b = ARGV_FALSE;
char *close_p = NULL, **arg_p;
/* run throught rest of arguments */
- for (arg_p = argv; arg_p < argv + argc; arg_p++) {
+ for (arg_p = argv; arg_p < argv + arg_c; arg_p++) {
/* have we reached the LAST_ARG marker? */
- if (! last_arg && strcmp(LAST_ARG, *arg_p) == 0) {
- last_arg = ARGV_TRUE;
- continue;
- }
-
- /* check for close equals marker */
- if (! last_arg && global_close == GLOBAL_CLOSE_ENABLE) {
- close_p = strchr(*arg_p, ARG_EQUALS);
- /* if we find the special char then punch the null and set pointer */
- if (close_p != NULL) {
- *close_p = NULLC;
- close_p++;
+ if (strcmp(LAST_ARG, *arg_p) == 0) {
+ if (last_arg_b) {
+ if (global_lasttog == GLOBAL_LASTTOG_ENABLE) {
+ last_arg_b = ARGV_FALSE;
+ continue;
+ }
+ }
+ else {
+ last_arg_b = ARGV_TRUE;
+ continue;
}
}
/* are we processing a long option? */
- if (! last_arg && strncmp(LONG_PREFIX, *arg_p, LONG_PREFIX_LENGTH) == 0) {
+ if ((! last_arg_b)
+ && strncmp(LONG_PREFIX, *arg_p, LONG_PREFIX_LENGTH) == 0) {
+
+ /*
+ * check for close equals marker
+ *
+ * NOTE: duplicated in the short prefix section below. In here otherwise
+ * we process normal args with x=5 instead of just -x=5.
+ */
+ if (global_close == GLOBAL_CLOSE_ENABLE) {
+ close_p = strchr(*arg_p, ARG_EQUALS);
+ /* if we found the special char then punch the null and set pointer */
+ if (close_p != NULL) {
+ *close_p = '\0';
+ close_p++;
+ }
+ }
/* get length of rest of argument */
len = strlen(*arg_p) - LONG_PREFIX_LENGTH;
/* we need more than the prefix */
if (len <= 0) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, empty long-option prefix '%s'\n",
argv_program, USAGE_ERROR_NAME, *arg_p);
- *okay_p = ARGV_FALSE;
+ }
+ *okay_bp = ARGV_FALSE;
continue;
}
@@ -1539,18 +2430,20 @@
/* run though long options looking for a match */
for (grid_p = grid; grid_p->ar_short_arg != ARGV_LAST; grid_p++) {
- if (grid_p->ar_long_arg == NULL)
+ if (grid_p->ar_long_arg == NULL) {
continue;
+ }
if (strncmp(*arg_p + LONG_PREFIX_LENGTH,
grid_p->ar_long_arg, len) == 0) {
if (match_p != NULL) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, '%s' might be '%s' or '%s'\n",
argv_program, USAGE_ERROR_NAME, *arg_p,
grid_p->ar_long_arg, match_p->ar_long_arg);
- *okay_p = ARGV_FALSE;
+ }
+ *okay_bp = ARGV_FALSE;
break;
}
@@ -1562,11 +2455,13 @@
}
/* if we found a match but quit then we must have found two matches */
- if (match_p != NULL && grid_p->ar_short_arg != ARGV_LAST)
+ if (match_p != NULL && grid_p->ar_short_arg != ARGV_LAST) {
continue;
+ }
if (match_p != NULL) {
- (void)do_arg(grid, match_p, close_p, okay_p);
+ (void)do_arg(grid, match_p, close_p, queue_list, queue_head_p,
+ okay_bp);
continue;
}
@@ -1576,17 +2471,20 @@
if (strncmp(FILE_ARG, *arg_p + LONG_PREFIX_LENGTH, len) == 0) {
if (global_close == GLOBAL_CLOSE_ENABLE && close_p != NULL) {
/* open the file and read in the args */
- file_args(close_p, grid, okay_p);
+ file_args(close_p, grid, queue_list, queue_head_p, queue_tail_p,
+ okay_bp);
}
else {
/* HACK: we enqueue null for the file argument */
- QUEUE_ENQUEUE(NULL);
+ queue_list[*queue_head_p] = NULL;
+ (*queue_head_p)++;
}
continue;
}
/* check for special usage value */
- if (strncmp(USAGE_ARG, *arg_p + LONG_PREFIX_LENGTH, len) == 0) {
+ if (strncmp(USAGE_ARG, *arg_p + LONG_PREFIX_LENGTH, len) == 0
+ || strncmp(HELP_ARG, *arg_p + LONG_PREFIX_LENGTH, len) == 0) {
if (argv_interactive) {
do_usage(grid, global_usage);
(void)exit(0);
@@ -1625,12 +2523,15 @@
if (strncmp(HELP_ARG, *arg_p + LONG_PREFIX_LENGTH, len) == 0) {
if (argv_interactive) {
if (argv_error_stream != NULL) {
- if (argv_help_string == NULL)
+ if (argv_help_string == NULL) {
(void)fprintf(argv_error_stream,
"%s: I'm sorry, no help is available.\n",
argv_program);
- else
- (void)fprintf(argv_error_stream, "%s\n", argv_help_string);
+ }
+ else {
+ (void)fprintf(argv_error_stream, "%s: %s\n",
+ argv_program, argv_help_string);
+ }
}
(void)exit(0);
}
@@ -1641,12 +2542,14 @@
if (strncmp(VERSION_ARG, *arg_p + LONG_PREFIX_LENGTH, len) == 0) {
if (argv_interactive) {
if (argv_error_stream != NULL) {
- if (argv_version_string == NULL)
+ if (argv_version_string == NULL) {
(void)fprintf(argv_error_stream,
"%s: no version information is available.\n",
argv_program);
- else
+ }
+ else {
(void)fprintf(argv_error_stream, "%s\n", argv_version_string);
+ }
}
(void)exit(0);
}
@@ -1656,35 +2559,53 @@
/* check for display arguments value */
if (strncmp(DISPLAY_ARG, *arg_p + LONG_PREFIX_LENGTH, len) == 0) {
if (argv_interactive) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
display_variables(grid);
+ }
(void)exit(0);
}
continue;
}
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, unknown long option '%s'.\n",
argv_program, USAGE_ERROR_NAME, *arg_p);
- *okay_p = ARGV_FALSE;
+ }
+ *okay_bp = ARGV_FALSE;
continue;
}
/* are we processing a short option? */
- if (! last_arg
+ if ((! last_arg_b)
&& strncmp(SHORT_PREFIX, *arg_p, SHORT_PREFIX_LENGTH) == 0) {
+ /*
+ * check for close equals marker
+ *
+ * NOTE: duplicated in the long prefix section above. In here otherwise
+ * we process normal args with x=5 instead of just -x=5.
+ */
+ if (global_close == GLOBAL_CLOSE_ENABLE) {
+ close_p = strchr(*arg_p, ARG_EQUALS);
+ /* if we found the special char then punch the null and set pointer */
+ if (close_p != NULL) {
+ *close_p = '\0';
+ close_p++;
+ }
+ }
+
/* get length of rest of argument */
len = strlen(*arg_p) - SHORT_PREFIX_LENGTH;
/* we need more than the prefix */
if (len <= 0) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, empty short-option prefix '%s'\n",
argv_program, USAGE_ERROR_NAME, *arg_p);
- *okay_p = ARGV_FALSE;
+ }
+ *okay_bp = ARGV_FALSE;
continue;
}
@@ -1692,9 +2613,12 @@
for (char_c = 0; char_c < len; char_c++) {
/* run through the arg list looking for a match */
- for (match_p = grid; match_p->ar_short_arg != ARGV_LAST; match_p++)
- if (match_p->ar_short_arg == (*arg_p)[SHORT_PREFIX_LENGTH + char_c])
+ for (match_p = grid; match_p->ar_short_arg != ARGV_LAST; match_p++) {
+ if (match_p->ar_short_arg ==
+ (*arg_p)[SHORT_PREFIX_LENGTH + char_c]) {
break;
+ }
+ }
/* did we not find argument? */
if (match_p->ar_short_arg == ARGV_LAST) {
@@ -1708,83 +2632,157 @@
continue;
}
+ /*
+ * allow values with negative signs if we are at the start
+ * of an argument list, and if the argument is a number, and
+ * we already have a variable looking for a value. Thanks
+ * to Nick Kisseberth <nkissebe@hera.itg.uiuc.edu> for
+ * pointing out this oversight.
+ */
+ if (char_c == 0 && is_number(*arg_p)
+ && *queue_head_p > *queue_tail_p) {
+
+ match_p = queue_list[*queue_tail_p];
+ /*
+ * NOTE: we don't advance the queue tail here unless we
+ * find out that we can use it below
+ */
+
+ switch (ARGV_TYPE(match_p->ar_type)) {
+
+ case ARGV_SHORT:
+ case ARGV_INT:
+ case ARGV_LONG:
+ case ARGV_FLOAT:
+ case ARGV_DOUBLE:
+ string_to_value(*arg_p, match_p->ar_variable, match_p->ar_type);
+ char_c = len;
+ /* we actually used it so we advance the queue tail position */
+ (*queue_tail_p)++;
+ continue;
+ break;
+ }
+ }
+
/* create an error string */
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, unknown short option '%s%c'.\n",
argv_program, USAGE_ERROR_NAME, SHORT_PREFIX,
(*arg_p)[SHORT_PREFIX_LENGTH + char_c]);
- *okay_p = ARGV_FALSE;
+ }
+ *okay_bp = ARGV_FALSE;
continue;
}
- do_arg(grid, match_p, close_p, okay_p);
+ do_arg(grid, match_p, close_p, queue_list, queue_head_p, okay_bp);
}
continue;
}
/* could this be a value? */
- if (grid->ar_short_arg != ARGV_LAST && QUEUE_COUNT() > 0) {
- QUEUE_DEQUEUE(match_p);
+ if (grid->ar_short_arg != ARGV_LAST && *queue_head_p > *queue_tail_p) {
+
+ /* pull the variable waiting for a value from the queue */
+ match_p = queue_list[*queue_tail_p];
+ (*queue_tail_p)++;
+
/* HACK: is this the file argument */
- if (match_p == NULL)
- file_args(close_p, grid, okay_p);
- else
- if (translate_value(*arg_p, match_p->ar_variable,
- match_p->ar_type) != NOERROR)
- *okay_p = ARGV_FALSE;
+ if (match_p == NULL) {
+ file_args(*arg_p, grid, queue_list, queue_head_p, queue_tail_p,
+ okay_bp);
+ }
+ else {
+ if (string_to_value(*arg_p, match_p->ar_variable,
+ match_p->ar_type) != NOERROR) {
+ *okay_bp = ARGV_FALSE;
+ }
+ }
continue;
}
/* process mandatory args if some left to process */
- for (grid_p = grid; grid_p->ar_short_arg != ARGV_LAST; grid_p++)
+ for (grid_p = grid; grid_p->ar_short_arg != ARGV_LAST; grid_p++) {
if (grid_p->ar_short_arg == ARGV_MAND
- && (! (grid_p->ar_type & ARGV_FLAG_USED)))
+ && ((! (grid_p->ar_type & ARGV_FLAG_USED))
+ || grid_p->ar_type & ARGV_FLAG_ARRAY)) {
break;
+ }
+ }
if (grid_p->ar_short_arg != ARGV_LAST) {
/* absorb another mand. arg */
- if (translate_value(*arg_p, grid_p->ar_variable,
- grid_p->ar_type) != NOERROR)
- *okay_p = ARGV_FALSE;
- if (! (grid_p->ar_type & ARGV_ARRAY))
- grid_p->ar_type |= ARGV_FLAG_USED;
+ if (string_to_value(*arg_p, grid_p->ar_variable,
+ grid_p->ar_type) != NOERROR) {
+ *okay_bp = ARGV_FALSE;
+ }
+ grid_p->ar_type |= ARGV_FLAG_USED;
continue;
}
/* process maybe args if some left to process */
- for (grid_p = grid; grid_p->ar_short_arg != ARGV_LAST; grid_p++)
+ for (grid_p = grid; grid_p->ar_short_arg != ARGV_LAST; grid_p++) {
if (grid_p->ar_short_arg == ARGV_MAYBE
- && (! (grid_p->ar_type & ARGV_FLAG_USED)))
+ && ((! (grid_p->ar_type & ARGV_FLAG_USED))
+ || grid_p->ar_type & ARGV_FLAG_ARRAY)) {
break;
+ }
+ }
if (grid_p->ar_short_arg != ARGV_LAST) {
/* absorb another maybe arg */
- if (translate_value(*arg_p, grid_p->ar_variable,
- grid_p->ar_type) != NOERROR)
- *okay_p = ARGV_FALSE;
- if (! (grid_p->ar_type & ARGV_ARRAY))
- grid_p->ar_type |= ARGV_FLAG_USED;
+ if (string_to_value(*arg_p, grid_p->ar_variable,
+ grid_p->ar_type) != NOERROR) {
+ *okay_bp = ARGV_FALSE;
+ }
+ grid_p->ar_type |= ARGV_FLAG_USED;
continue;
}
/* default is an error */
unwant_c++;
- *okay_p = ARGV_FALSE;
+ *okay_bp = ARGV_FALSE;
}
- if (unwant_c > 0 && argv_error_stream != NULL)
+ if (unwant_c > 0 && argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, %d unwanted additional argument%s\n",
argv_program, USAGE_ERROR_NAME,
unwant_c, (unwant_c == 1 ? "" : "s"));
+ }
}
/****************************** env processing *******************************/
/*
- * Handle the args from the ENV variable. Returns [NO]ERROR.
+ * static int do_env_args
+ *
+ * DESCRIPTION:
+ *
+ * Handle the args from the environmentatl variable.
+ *
+ * RETURNS:
+ *
+ * Success - 0
+ *
+ * Faulure - -1
+ *
+ * ARGUMENTS:
+ *
+ * args - Array of argv_t structures we are using.
+ *
+ * queue_list <-> Our option queue for storing options to arguments.
+ *
+ * queue_head_p <-> Pointer to integer which will be updated with the
+ * head position in our option queue.
+ *
+ * queue_tail_p <-> Pointer to integer which will be updated with the
+ * tail position in our option queue.
+ *
+ * okay_bp - Pointer to an integer which is set with 0 if the
+ * arguments specified in the env variable are somehow invalid.
*/
-LOCAL int do_env_args(argv_t *args, char *okay_p)
+static int do_env_args(argv_t *args, argv_t **queue_list,
+ int *queue_head_p, int *queue_tail_p, int *okay_bp)
{
int env_c, env_n;
char **vect_p, env_name[256], *environ_p;
@@ -1793,26 +2791,32 @@
(void)sprintf(env_name, ENVIRON_FORMAT, argv_program);
/* NOTE: by default the env name is all uppercase */
- for (environ_p = env_name; *environ_p != NULLC; environ_p++)
- if (islower((int)*environ_p))
+ for (environ_p = env_name; *environ_p != '\0'; environ_p++) {
+ if (islower((int)*environ_p)) {
*environ_p = toupper((int)*environ_p);
+ }
+ }
environ_p = getenv(env_name);
- if (environ_p == NULL)
+ if (environ_p == NULL) {
return NOERROR;
+ }
/* break the list into tokens and do the list */
environ_p = string_copy(environ_p);
- if (environ_p == NULL)
+ if (environ_p == NULL) {
return ERROR;
+ }
vect_p = vectorize(environ_p, " \t", &env_n);
if (vect_p != NULL) {
- do_list(args, env_n, vect_p, okay_p);
+ do_list(args, env_n, vect_p, queue_list, queue_head_p, queue_tail_p,
+ okay_bp);
/* free token list */
- for (env_c = 0; env_c < env_n; env_c++)
+ for (env_c = 0; env_c < env_n; env_c++) {
free(vect_p[env_c]);
+ }
free(vect_p);
}
free(environ_p);
@@ -1821,610 +2825,594 @@
}
/*
- * Process the global env variable. Returns [NO]ERROR.
+ * static int process_env
+ *
+ * DESCRIPTION:
+ *
+ * Process the global env variables.
+ *
+ * RETURNS:
+ *
+ * Success - 0
+ *
+ * Faulure - -1
+ *
+ * ARGUMENTS:
+ *
+ * None.
*/
-LOCAL int process_env(void)
+static int process_env(void)
{
- static char done = ARGV_FALSE;
- char *environ_p, *env_p, *arg;
+ static int done_b = ARGV_FALSE;
+ char *environ, *tok_p, *env_p;
int len;
/* make sure we only do this once */
- if (done)
+ if (done_b) {
return NOERROR;
+ }
- done = ARGV_TRUE;
+ done_b = ARGV_TRUE;
/* get the argv information */
- environ_p = getenv(GLOBAL_NAME);
- if (environ_p == NULL)
+ environ = getenv(GLOBAL_NAME);
+ if (environ == NULL) {
return NOERROR;
+ }
/* save a copy of it */
- environ_p = string_copy(environ_p);
- if (environ_p == NULL)
+ environ = string_copy(environ);
+ if (environ == NULL) {
return ERROR;
+ }
- arg = environ_p;
+ env_p = environ;
for (;;) {
- env_p = strtok(arg, " \t,:");
- if (env_p == NULL)
+ tok_p = my_strsep(&env_p, " \t,:");
+ if (tok_p == NULL) {
break;
- arg = NULL;
+ }
+ /* skip any empty tokens */
+ if (*tok_p == '\0') {
+ continue;
+ }
len = strlen(GLOBAL_CLOSE);
- if (strncmp(GLOBAL_CLOSE, env_p, len) == 0) {
- env_p += len;
- if (strcmp(env_p, "disable") == 0)
+ if (strncmp(GLOBAL_CLOSE, tok_p, len) == 0) {
+ tok_p += len;
+ if (strcmp(tok_p, "disable") == 0
+ || strcmp(tok_p, "off") == 0
+ || strcmp(tok_p, "no") == 0
+ || strcmp(tok_p, "0") == 0) {
global_close = GLOBAL_CLOSE_DISABLE;
- else if (strcmp(env_p, "enable") == 0)
+ }
+ else if (strcmp(tok_p, "enable") == 0
+ || strcmp(tok_p, "on") == 0
+ || strcmp(tok_p, "yes") == 0
+ || strcmp(tok_p, "1") == 0) {
global_close = GLOBAL_CLOSE_ENABLE;
+ }
+ else {
+ if (argv_error_stream != NULL) {
+ (void)fprintf(argv_error_stream,
+ "%s: illegal env variable '%s' '%s' argument '%s'\n",
+ __FILE__, GLOBAL_NAME, GLOBAL_CLOSE, tok_p);
+ }
+ }
+ continue;
+ }
+
+ len = strlen(GLOBAL_LASTTOG);
+ if (strncmp(GLOBAL_LASTTOG, tok_p, len) == 0) {
+ tok_p += len;
+ if (strcmp(tok_p, "disable") == 0
+ || strcmp(tok_p, "off") == 0
+ || strcmp(tok_p, "no") == 0
+ || strcmp(tok_p, "0") == 0) {
+ global_lasttog = GLOBAL_LASTTOG_DISABLE;
+ }
+ else if (strcmp(tok_p, "enable") == 0
+ || strcmp(tok_p, "on") == 0
+ || strcmp(tok_p, "yes") == 0
+ || strcmp(tok_p, "1") == 0) {
+ global_lasttog = GLOBAL_LASTTOG_ENABLE;
+ }
else {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: illegal env variable '%s' '%s' argument '%s'\n",
- __FILE__, GLOBAL_NAME, GLOBAL_CLOSE, env_p);
+ __FILE__, GLOBAL_NAME, GLOBAL_LASTTOG, tok_p);
+ }
}
continue;
}
len = strlen(GLOBAL_ENV);
- if (strncmp(GLOBAL_ENV, env_p, len) == 0) {
- env_p += len;
- if (strcmp(env_p, "none") == 0)
+ if (strncmp(GLOBAL_ENV, tok_p, len) == 0) {
+ tok_p += len;
+ if (strcmp(tok_p, "none") == 0) {
global_env = GLOBAL_ENV_NONE;
- else if (strcmp(env_p, "before") == 0)
+ }
+ else if (strcmp(tok_p, "before") == 0) {
global_env = GLOBAL_ENV_BEFORE;
- else if (strcmp(env_p, "after") == 0)
+ }
+ else if (strcmp(tok_p, "after") == 0) {
global_env = GLOBAL_ENV_AFTER;
+ }
else {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: illegal env variable '%s' '%s' argument '%s'\n",
- __FILE__, GLOBAL_NAME, GLOBAL_ENV, env_p);
+ __FILE__, GLOBAL_NAME, GLOBAL_ENV, tok_p);
+ }
}
continue;
}
len = strlen(GLOBAL_ERROR);
- if (strncmp(GLOBAL_ERROR, env_p, len) == 0) {
- env_p += len;
- if (strcmp(env_p, "none") == 0)
+ if (strncmp(GLOBAL_ERROR, tok_p, len) == 0) {
+ tok_p += len;
+ if (strcmp(tok_p, "none") == 0) {
global_error = GLOBAL_ERROR_NONE;
- else if (strcmp(env_p, "see") == 0)
+ }
+ else if (strcmp(tok_p, "see") == 0) {
global_error = GLOBAL_ERROR_SEE;
- else if (strcmp(env_p, "short") == 0)
+ }
+ else if (strcmp(tok_p, "short") == 0) {
global_error = GLOBAL_ERROR_SHORT;
- else if (strcmp(env_p, "shortrem") == 0)
+ }
+ else if (strcmp(tok_p, "shortrem") == 0) {
global_error = GLOBAL_ERROR_SHORTREM;
- else if (strcmp(env_p, "long") == 0)
+ }
+ else if (strcmp(tok_p, "long") == 0) {
global_error = GLOBAL_ERROR_LONG;
- else if (strcmp(env_p, "all") == 0)
+ }
+ else if (strcmp(tok_p, "all") == 0) {
global_error = GLOBAL_ERROR_ALL;
+ }
else {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: illegal env variable '%s' '%s' argument '%s'\n",
- __FILE__, GLOBAL_NAME, GLOBAL_ERROR, env_p);
+ __FILE__, GLOBAL_NAME, GLOBAL_ERROR, tok_p);
+ }
}
continue;
}
len = strlen(GLOBAL_MULTI);
- if (strncmp(GLOBAL_MULTI, env_p, len) == 0) {
- env_p += len;
- if (strcmp(env_p, "reject") == 0)
+ if (strncmp(GLOBAL_MULTI, tok_p, len) == 0) {
+ tok_p += len;
+ if (strcmp(tok_p, "reject") == 0) {
global_multi = GLOBAL_MULTI_REJECT;
- else if (strcmp(env_p, "accept") == 0)
+ }
+ else if (strcmp(tok_p, "accept") == 0) {
global_multi = GLOBAL_MULTI_ACCEPT;
+ }
else {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: illegal env variable '%s' '%s' argument '%s'\n",
- __FILE__, GLOBAL_NAME, GLOBAL_MULTI, env_p);
+ __FILE__, GLOBAL_NAME, GLOBAL_MULTI, tok_p);
+ }
}
continue;
}
len = strlen(GLOBAL_USAGE);
- if (strncmp(GLOBAL_USAGE, env_p, len) == 0) {
- env_p += len;
- if (strcmp(env_p, "short") == 0)
+ if (strncmp(GLOBAL_USAGE, tok_p, len) == 0) {
+ tok_p += len;
+ if (strcmp(tok_p, "short") == 0) {
global_usage = GLOBAL_USAGE_SHORT;
- else if (strcmp(env_p, "shortrem") == 0)
+ }
+ else if (strcmp(tok_p, "shortrem") == 0) {
global_usage = GLOBAL_USAGE_SHORTREM;
- else if (strcmp(env_p, "long") == 0)
+ }
+ else if (strcmp(tok_p, "long") == 0) {
global_usage = GLOBAL_USAGE_LONG;
- else if (strcmp(env_p, "all") == 0)
+ }
+ else if (strcmp(tok_p, "all") == 0) {
global_usage = GLOBAL_USAGE_ALL;
+ }
else {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: illegal env variable '%s' '%s' argument '%s'\n",
- __FILE__, GLOBAL_NAME, GLOBAL_USAGE, env_p);
+ __FILE__, GLOBAL_NAME, GLOBAL_USAGE, tok_p);
+ }
}
continue;
}
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: illegal env variable '%s' setting '%s'\n",
- __FILE__, GLOBAL_NAME, env_p);
+ __FILE__, GLOBAL_NAME, tok_p);
+ }
}
- free(environ_p);
+ free(environ);
return NOERROR;
}
+/***************************** exported routines *****************************/
+
/*
- * Processes ARGS from ARGC and ARGV. Returns 0 if no error else -1.
+ * int argv_process_no_env
+ *
+ * DESCRIPTION:
+ *
+ * Process the user arguments with an argv_t structure array. Like
+ * argv_process_args but without the processing of the argv
+ * environmental variables.
+ *
+ * RETURNS:
+ *
+ * Success - 0
+ *
+ * Failure - -1
+ *
+ * ARGUMENTS:
+ *
+ * args - Array of argv_t structures.
+ *
+ * arg_c - Number of arguments in the argv array.
+ *
+ * argv - Array of character pointers terminated by 0L.
*/
-LOCAL int process_args(argv_t *args, const int argc, char **argv)
+int argv_process_no_env(argv_t *args, const int arg_c, char **argv)
{
- int num_args;
+ int arg_n;
const char *prog_p;
- char okay = ARGV_TRUE;
+ int okay_b = ARGV_TRUE;
argv_t *arg_p;
+ argv_t **queue_list=NULL;
+ int queue_head = 0, queue_tail = 0;
- if (process_env() != NOERROR)
- return ERROR;
-
- if (args == NULL)
+ if (args == NULL) {
args = empty;
+ }
- if (argc < 0) {
- if (argv_error_stream != NULL)
+ if (arg_c < 0) {
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, argc argument to argv_process is %d\n",
- __FILE__, INTERNAL_ERROR_NAME, argc);
- if (argv_interactive)
+ __FILE__, INTERNAL_ERROR_NAME, arg_c);
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return ERROR;
}
if (argv == NULL) {
- if (argv_error_stream != NULL)
+ if (argv_error_stream != NULL) {
(void)fprintf(argv_error_stream,
"%s: %s, argv argument to argv_process is NULL\n",
__FILE__, INTERNAL_ERROR_NAME);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return ERROR;
}
/* set global variables */
argv_argv = argv;
- argv_argc = argc;
+ argv_argc = arg_c;
/* build the program name from the argv[0] path */
{
const char *tmp_p;
prog_p = *argv;
- for (tmp_p = *argv; *tmp_p != NULLC; tmp_p++)
- if (*tmp_p == '/')
+ for (tmp_p = *argv; *tmp_p != '\0'; tmp_p++) {
+ if (*tmp_p == '/') {
prog_p = tmp_p + 1;
+ }
+ }
}
/* so we can step on the environmental space */
(void)strncpy(argv_program, prog_p, PROGRAM_NAME);
/* count the args */
- num_args = 0;
- for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++)
- num_args++;
+ arg_n = 0;
+ for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++) {
+ arg_n++;
+ }
/* verify the argument array */
- if (preprocess_array(args, num_args) != NOERROR)
+ if (preprocess_array(args, arg_n) != NOERROR) {
return ERROR;
+ }
/* allocate our value queue */
- if (num_args > 0)
- QUEUE_ALLOC(argv_t *, num_args);
+ if (arg_n > 0) {
+ /* allocate our argument queue */
+ queue_list = (argv_t **)malloc(sizeof(argv_t *) * arg_n);
+ if (queue_list == NULL) {
+ return ERROR;
+ }
+ queue_head = 0;
+ queue_tail = 0;
+ }
/* do the env args before? */
if (global_env == GLOBAL_ENV_BEFORE) {
- if (do_env_args(args, &okay) != NOERROR)
+ if (do_env_args(args, queue_list, &queue_head, &queue_tail,
+ &okay_b) != NOERROR) {
return ERROR;
+ }
}
/* do the external args */
- do_list(args, argc - 1, argv + 1, &okay);
+ do_list(args, arg_c - 1, argv + 1, queue_list, &queue_head, &queue_tail,
+ &okay_b);
- /* do the env args after? */
+ /* DO the env args after? */
if (global_env == GLOBAL_ENV_AFTER) {
- do_env_args(args, &okay);
- if (do_env_args(args, &okay) != NOERROR)
+ if (do_env_args(args, queue_list, &queue_head, &queue_tail,
+ &okay_b) != NOERROR) {
return ERROR;
+ }
}
/* make sure the XOR and MAND args and argument-options are okay */
- if (check_mand(args) != NOERROR)
- okay = ARGV_FALSE;
- if (check_opt() != NOERROR)
- okay = ARGV_FALSE;
- if (check_xor(args) != NOERROR)
- okay = ARGV_FALSE;
+ if (check_mand(args) != NOERROR) {
+ okay_b = ARGV_FALSE;
+ }
+ if (check_opt(queue_head, queue_tail) != NOERROR) {
+ okay_b = ARGV_FALSE;
+ }
+ if (check_xor(args) != NOERROR) {
+ okay_b = ARGV_FALSE;
+ }
/* if we allocated the space then free it */
- if (num_args > 0)
- QUEUE_FREE();
+ if (arg_n > 0) {
+ free(queue_list);
+ }
/* was there an error? */
- if (! okay) {
- if (argv_error_stream != NULL)
+ if (! okay_b) {
+ if (argv_error_stream != NULL) {
do_usage(args, global_error);
- if (argv_interactive)
+ }
+ if (argv_interactive) {
(void)exit(EXIT_CODE);
+ }
return ERROR;
}
return NOERROR;
}
-/***************************** exported routines *****************************/
-
/*
- * Processes ARGC number of arguments from ARGV depending on argument
- * info array ARGS (if null then an empty array is used). This
- * routine will not modify the argv array in any way.
+ * int argv_process
+ *
+ * DESCRIPTION:
+ *
+ * Processes a number of arguments depending on the argument array.
+ * This routine will not modify the argv array in any way.
*
* NOTE: it will modify the args array by setting various flags in the
* type field. returns 0 if no error else -1.
+ *
+ * ARGUMENTS:
+ *
+ * args - Array of argv_t structures that we are using to process the
+ * user argument array. If null then an empty array is used.
+ *
+ * argc - Number of arguments in the argv argument array.
+ *
+ * argv - Array of character pointer arguments terminated by a 0L.
*/
-EXPORT int argv_process(argv_t *args, const int argc, char **argv)
+int argv_process(argv_t *args, const int argc, char **argv)
{
- if (! enabled)
+ if (! enabled_b) {
argv_startup();
+ }
+
+ /* we only process env variables here */
+ if (process_env() != NOERROR) {
+ return ERROR;
+ }
- if (process_args(args, argc, argv) == NOERROR)
+ if (argv_process_no_env(args, argc, argv) == NOERROR) {
return NOERROR;
- else
+ }
+ else {
return ERROR;
+ }
}
/*
- * Processes arguments sent in via the STRING that a web-server might
- * send to program in ARG0. Use DELIM to set up the delimiters of the
- * arguments in the string. query_string processing should have "&"
- * and path_info should have "/". You may want to add "=" if you use
- * arg=value. The '=' delimiter is treated as special so //x=// will
- * strip the extra /'s in a row but will create a null argument for x.
- *
- * WARNING: you cannot use argv_copy_args after this is called because a
- * temporary grid is created. returns 0 on noerror else -1.
- */
-EXPORT int argv_web_process_string(argv_t *args, const char *arg0,
- const char *string,
- const char *delim)
-{
- const char *str_p, *delim_p, *delim_str;
- char *copy, *copy_p, **argv;
- int argc, ret, alloced;
-
- if (! enabled)
+ * int argv_usage
+ *
+ * DESCRIPTION:
+ *
+ * Print the standard usage messages for our argument array. You can
+ * specify whether you want to see a short or long usage messages.
+ *
+ * NOTE: if this is called before argv_process then the program name
+ * may be invalid.
+ *
+ * RETURNS:
+ *
+ * Success - 0
+ *
+ * Failure - -1
+ *
+ * ARGUMENTS:
+ *
+ * args - Our argument array to print the usage messages about. If
+ * null then an empty array is used.
+ *
+ * which - Either ARGV_USAGE_SHORT (for short usage messages),
+ * ARGV_USAGE_LONG (for long usage messages), or ARGV_USAGE_DEFAULT
+ * (the user's default either long or short).
+ */
+int argv_usage(const argv_t *args, const int which)
+{
+ if (! enabled_b) {
argv_startup();
-
- if (delim == NULL)
- delim_str = "";
- else
- delim_str = delim;
-
- /* copy incoming string so we can punch nulls */
- copy = malloc(strlen(string) + 1);
- if (copy == NULL) {
- if (argv_error_stream != NULL)
- (void)fprintf(argv_error_stream,
- "%s: memory error during argument processing\n",
- argv_program);
- if (argv_interactive)
- (void)exit(EXIT_CODE);
- return ERROR;
}
- /* create argv array */
- alloced = ARG_MALLOC_INCR;
- argv = (char **)malloc(sizeof(char *) * alloced);
- if (argv == NULL) {
- free(copy);
- if (argv_error_stream != NULL)
- (void)fprintf(argv_error_stream,
- "%s: memory error during argument processing\n",
- argv_program);
- if (argv_interactive)
- (void)exit(EXIT_CODE);
+ if (process_env() != NOERROR) {
return ERROR;
}
- argc = 0;
- argv[argc++] = (char *)arg0;
- str_p = string;
- /* skip starting multiple arg delimiters */
- for (; *str_p != NULLC; str_p++) {
- for (delim_p = delim_str; *delim_p != NULLC; delim_p++)
- if (*str_p == *delim_p)
- break;
- if (*delim_p == NULLC)
- break;
+ if (args == NULL) {
+ args = empty;
}
- /* start of the string is argv[1] */
- if (*str_p != NULLC) {
- if (argc >= alloced) {
- alloced += ARG_MALLOC_INCR;
- argv = (char **)realloc(argv, sizeof(char *) * alloced);
- if (argv == NULL) {
- free(copy);
- if (argv_error_stream != NULL)
- (void)fprintf(argv_error_stream,
- "%s: memory error during argument processing\n",
- argv_program);
- if (argv_interactive)
- (void)exit(EXIT_CODE);
- return ERROR;
- }
- }
- argv[argc++] = copy;
+ if (which == ARGV_USAGE_SHORT) {
+ usage_short(args, 0);
}
-
- for (copy_p = copy;; str_p++) {
- int val;
-
- /* are we done? */
- if (*str_p == NULLC) {
- *copy_p = NULLC;
- break;
- }
-
- /* is this a argument seperator? */
- for (delim_p = delim_str; *delim_p != NULLC; delim_p++)
- if (*str_p == *delim_p)
- break;
- if (*delim_p != NULLC) {
- *copy_p++ = NULLC;
-
- /*
- * look ahead and skip multiple arg delimiters. we have a
- * special case if the delimiter is '='. This means that we
- * need to generate a null string argument.
- */
- if (*str_p != '=') {
- for (;; str_p++) {
- for (delim_p = delim_str; *delim_p != NULLC; delim_p++)
- if (*(str_p + 1) == *delim_p)
- break;
- if (*delim_p == NULLC)
- break;
- }
- }
-
- /* if we are not at the end of the string, create a new arg */
- if (*str_p == '=' || *(str_p + 1) != NULLC) {
- if (argc >= alloced) {
- alloced += ARG_MALLOC_INCR;
- argv = (char **)realloc(argv, sizeof(char *) * alloced);
- if (argv == NULL) {
- if (argv_error_stream != NULL)
- (void)fprintf(argv_error_stream,
- "%s: memory error during argument processing\n",
- argv_program);
- if (argv_interactive)
- (void)exit(EXIT_CODE);
- return ERROR;
- }
- }
- argv[argc++] = copy_p;
- }
- continue;
- }
-
- /* a space */
- if (*str_p == '+') {
- *copy_p++ = ' ';
- continue;
- }
-
- /* no binary character, than it is normal */
- if (*str_p != '%') {
- *copy_p++ = *str_p;
- continue;
- }
-
- str_p++;
-
- if (*str_p >= 'a' && *str_p <= 'f')
- val = 10 + *str_p - 'a';
- else if (*str_p >= 'A' && *str_p <= 'F')
- val = 10 + *str_p - 'A';
- else if (*str_p >= '0' && *str_p <= '9')
- val = *str_p - '0';
- else
- continue;
-
- str_p++;
-
- if (*str_p >= 'a' && *str_p <= 'f')
- val = val * 16 + (10 + *str_p - 'a');
- else if (*str_p >= 'A' && *str_p <= 'F')
- val = val * 16 + (10 + *str_p - 'A');
- else if (*str_p >= '0' && *str_p <= '9')
- val = val * 16 + (*str_p - '0');
- else
- str_p--;
-
- *copy_p++ = (char)val;
+ else if (which == ARGV_USAGE_LONG) {
+ usage_long(args);
+ }
+ else {
+ /* default/env settings */
+ do_usage(args, global_usage);
}
- ret = process_args(args, argc, argv);
-
- free(copy);
- free(argv);
-
- if (ret == NOERROR)
- return NOERROR;
- else
- return ERROR;
+ return NOERROR;
}
/*
- * Processes arguments sent in via the QUERY_STRING environmental
- * variable that a web-server might send to program in ARG0. Returns
- * 0 on noerror else -1.
+ * int argv_was_used
+ *
+ * DESCRIPTION:
+ *
+ * See if an argument was used in a previous call to argv_process.
+ *
+ * RETURNS:
+ *
+ * 1 if yes it was used, else 0 if not.
+ *
+ * ARGUMENTS:
+ *
+ * args - Argument list to search.
+ *
+ * short_arg - Short argument to see if it was used.
*/
-EXPORT int argv_web_process(argv_t *args, const char *arg0)
+int argv_was_used(const argv_t *args, const char short_arg)
{
- char *env, *work = NULL;
- int ret, len;
+ const argv_t *arg_p;
- if (! enabled)
+ if (! enabled_b) {
argv_startup();
-
- env = getenv("REQUEST_METHOD");
- if (env != NULL && strcmp(env, "POST") == 0) {
- env = getenv("CONTENT_LENGTH");
- if (env != NULL) {
- len = atoi(env);
- if (len > 0) {
- work = (char *)malloc(len + 1);
- if (work == NULL) {
- if (argv_error_stream != NULL)
- (void)fprintf(argv_error_stream,
- "%s: memory error during argument processing\n",
- argv_program);
- if (argv_interactive)
- (void)exit(EXIT_CODE);
- return ERROR;
- }
- (void)read(STDIN, work, len);
- work[len] = NULLC;
- }
- }
}
- if (work == NULL) {
- env = getenv("QUERY_STRING");
-
- /* if it is not set or empty, then nothing to do */
- if (env == NULL || *env == NULLC) {
- work = (char *)malloc(1);
- if (work == NULL) {
- if (argv_error_stream != NULL)
- (void)fprintf(argv_error_stream,
- "%s: memory error during argument processing\n",
- argv_program);
- if (argv_interactive)
- (void)exit(EXIT_CODE);
- return ERROR;
+ for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++) {
+ if (arg_p->ar_short_arg == short_arg) {
+ if (arg_p->ar_type & ARGV_FLAG_USED) {
+ return 1;
+ }
+ else {
+ return 0;
}
- work[0] = NULLC;
- }
- else {
- work = string_copy(env);
- if (work == NULL)
- return ERROR;
}
}
- ret = argv_web_process_string(args, arg0, work, "&=");
- free(work);
-
- if (ret == NOERROR)
- return NOERROR;
- else
- return ERROR;
+ return 0;
}
/*
- * Print the standard usage messages for argument array ARGS (if null
- * then an empty array is used). WHICH chooses between long or short
- * messages (see argv.h).
+ * int argv_long_was_used
*
- * NOTE: if this is called before argv_process then the program name may
- * be messed up.
- */
-EXPORT int argv_usage(const argv_t *args, const int which)
-{
- if (! enabled)
- argv_startup();
-
- if (process_env() != NOERROR)
- return ERROR;
-
- if (args == NULL)
- args = empty;
-
- if (which == ARGV_USAGE_SHORT)
- usage_short(args, 0);
- else if (which == ARGV_USAGE_LONG)
- usage_long(args);
- else
- /* default/env settings */
- do_usage(args, global_usage);
-
- return NOERROR;
-}
-
-/*
- * See if ARG argument was used in a previous call to argv_process on
- * ARGS. Returns 1 if yes else 0.
+ * DESCRIPTION:
+ *
+ * See if a long argument was used in a previous call to argv_process.
+ *
+ * RETURNS:
+ *
+ * 1 if yes it was used, else 0 if not.
+ *
+ * ARGUMENTS:
+ *
+ * args - Argument list to search.
+ *
+ * long_arg - Long argument to see if it was used.
*/
-EXPORT int argv_was_used(const argv_t *args, const char arg)
+int argv_long_was_used(const argv_t *args, const char *long_arg)
{
const argv_t *arg_p;
- if (! enabled)
+ if (! enabled_b) {
argv_startup();
+ }
- for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++)
- if (arg_p->ar_short_arg == arg) {
- if (arg_p->ar_type & ARGV_FLAG_USED)
+ for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++) {
+ if (arg_p->ar_long_arg == long_arg) {
+ if (arg_p->ar_type & ARGV_FLAG_USED) {
return 1;
- else
+ }
+ else {
return 0;
+ }
}
+ }
return 0;
}
/*
- * Frees up any allocations in ARGS that may have been done by
+ * void argv_cleanup
+ *
+ * DESCRIPTION:
+ *
+ * Frees up any allocations associated with the argument array during
* argv_process. This should be done at the end of the program or
* after all the arguments have been referenced.
+ *
+ * RETURNS:
+ *
+ * None.
+ *
+ * ARGUMENTS:
+ *
+ * args - Argument array we are cleaning up.
*/
-EXPORT void argv_cleanup(const argv_t *args)
+void argv_cleanup(const argv_t *args)
{
const argv_t *arg_p;
int entry_c;
- if (! enabled)
+ if (! enabled_b) {
argv_startup();
+ }
- if (args == NULL)
+ if (args == NULL) {
return;
+ }
/* run through the argument structure */
for (arg_p = args; arg_p->ar_short_arg != ARGV_LAST; arg_p++) {
/* handle any arrays */
- if (arg_p->ar_type & ARGV_ARRAY) {
+ if (arg_p->ar_type & ARGV_FLAG_ARRAY) {
argv_array_t *arr_p = (argv_array_t *)arg_p->ar_variable;
/* free any entries */
- if (arr_p->aa_entryn > 0) {
- if (ARGV_TYPE(arg_p->ar_type) == ARGV_CHARP) {
- for (entry_c = 0; entry_c < arr_p->aa_entryn; entry_c++)
+ if (arr_p->aa_entry_n > 0) {
+ if (ARGV_TYPE(arg_p->ar_type) == ARGV_CHAR_P) {
+ for (entry_c = 0; entry_c < arr_p->aa_entry_n; entry_c++) {
free(ARGV_ARRAY_ENTRY(*arr_p, char *, entry_c));
+ }
}
free(arr_p->aa_entries);
}
arr_p->aa_entries = NULL;
- arr_p->aa_entryn = 0;
+ arr_p->aa_entry_n = 0;
continue;
}
/* handle individual charps */
if (arg_p->ar_type & ARGV_FLAG_USED
- && ARGV_TYPE(arg_p->ar_type) == ARGV_CHARP) {
+ && ARGV_TYPE(arg_p->ar_type) == ARGV_CHAR_P) {
free(*(char **)arg_p->ar_variable);
continue;
}
@@ -2432,44 +3420,102 @@
}
/*
- * Copy all the args (after the 0th), one after the other, into BUF of
- * MAX_SIZE. Returns 0 on no error else -1.
+ * int argv_copy_args
+ *
+ * DESCRIPTION:
+ *
+ * Copy all the arguements (not including the 0th) one after the other
+ * into the user specified buffer.
+ *
+ * NOTE: you can get the 0th argument from argv_argv[0] or
+ * argv_program.
+ *
+ * RETURNS:
+ *
+ * Success - 0
+ *
+ * Failure - -1
*
- * NOTE: you can get the 0th argument from argv_argv[0].
+ * ARGUMENTS:
+ *
+ * buf - Buffer to copy all of the user arguments into.
+ *
+ * buf_size - Size of the buffer.
*/
-EXPORT int argv_copy_args(char *buf, const int max_size)
+int argv_copy_args(char *buf, const int buf_size)
{
char **argv_p, *buf_p = buf, *arg_p;
- int argc, size_c = max_size;
+ int arg_c, size_c = buf_size;
- if (! enabled)
+ if (! enabled_b) {
argv_startup();
+ }
- if (process_env() != NOERROR)
- return ERROR;
-
- if (max_size == 0)
+ if (buf_size <= 0) {
return NOERROR;
+ }
+
+ *buf_p = '\0';
- *buf_p = NULLC;
+ if (process_env() != NOERROR) {
+ return ERROR;
+ }
- if (argv_argv == NULL || max_size == 1)
+ if (argv_argv == NULL || buf_size == 1) {
return NOERROR;
+ }
- for (argv_p = argv_argv + 1, argc = 1; argc < argv_argc; argv_p++, argc++) {
+ for (argv_p = argv_argv + 1, arg_c = 1;
+ arg_c < argv_argc;
+ argv_p++, arg_c++) {
- if (size_c < 2)
+ /* we compare against 2 for the ' ' and the \0 */
+ if (size_c < 2) {
break;
+ }
if (argv_p > argv_argv + 1) {
*buf_p++ = ' ';
size_c--;
}
- for (arg_p = *argv_p; *arg_p != NULLC && size_c >= 2; size_c--)
+ /* we always compare against 2 to include the \0 */
+ for (arg_p = *argv_p; *arg_p != '\0' && size_c >= 2; size_c--) {
*buf_p++ = *arg_p++;
+ }
}
- *buf_p = NULLC;
+ *buf_p = '\0';
return NOERROR;
}
+
+/*
+ * int argv_value_string
+ *
+ * DESCRIPTION:
+ *
+ * Convert the value of a RC entry to its string equivalent in the
+ * buffer provided.
+ *
+ * RETURNS:
+ *
+ * Length of bytes copied into the buffer.
+ *
+ * ARGUMENTS:
+ *
+ * argv_entry_p - Pointer to an entry in a argv_t list.
+ *
+ * buf - Buffer to convert the value into.
+ *
+ * buf_size - Size of the buffer.
+ */
+int argv_value_string(const argv_t *argv_entry_p, char *buf,
+ const int buf_size)
+{
+ if (! enabled_b) {
+ argv_startup();
+ }
+
+ return value_to_string(argv_entry_p->ar_variable, argv_entry_p->ar_type,
+ buf, buf_size);
+}
|