summaryrefslogtreecommitdiff
path: root/media/sphinxbase/src/libsphinxbase/util/cmd_ln.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/sphinxbase/src/libsphinxbase/util/cmd_ln.c')
-rw-r--r--media/sphinxbase/src/libsphinxbase/util/cmd_ln.c1082
1 files changed, 0 insertions, 1082 deletions
diff --git a/media/sphinxbase/src/libsphinxbase/util/cmd_ln.c b/media/sphinxbase/src/libsphinxbase/util/cmd_ln.c
deleted file mode 100644
index 9624829958..0000000000
--- a/media/sphinxbase/src/libsphinxbase/util/cmd_ln.c
+++ /dev/null
@@ -1,1082 +0,0 @@
-/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/* ====================================================================
- * Copyright (c) 1999-2004 Carnegie Mellon University. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * This work was supported in part by funding from the Defense Advanced
- * Research Projects Agency and the National Science Foundation of the
- * United States of America, and the CMU Sphinx Speech Consortium.
- *
- * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
- * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
- * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ====================================================================
- *
- */
-/*
- * cmd_ln.c -- Command line argument parsing.
- *
- * **********************************************
- * CMU ARPA Speech Project
- *
- * Copyright (c) 1999 Carnegie Mellon University.
- * ALL RIGHTS RESERVED.
- * **********************************************
- *
- * HISTORY
- *
- * 10-Sep-1998 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
- * Changed strcasecmp() call in cmp_name() to strcmp_nocase() call.
- *
- * 15-Jul-1997 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
- * Added required arguments handling.
- *
- * 07-Dec-96 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
- * Created, based on Eric's implementation. Basically, combined several
- * functions into one, eliminated validation, and simplified the interface.
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#ifdef _MSC_VER
-#pragma warning (disable: 4996 4018)
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "sphinxbase/cmd_ln.h"
-#include "sphinxbase/err.h"
-#include "sphinxbase/ckd_alloc.h"
-#include "sphinxbase/hash_table.h"
-#include "sphinxbase/case.h"
-#include "sphinxbase/strfuncs.h"
-
-typedef struct cmd_ln_val_s {
- anytype_t val;
- int type;
-} cmd_ln_val_t;
-
-struct cmd_ln_s {
- int refcount;
- hash_table_t *ht;
- char **f_argv;
- uint32 f_argc;
-};
-
-/** Global command-line, for non-reentrant API. */
-cmd_ln_t *global_cmdln;
-
-static void
-arg_dump_r(cmd_ln_t *, FILE *, arg_t const *, int32);
-
-static cmd_ln_t *
-parse_options(cmd_ln_t *, const arg_t *, int32, char* [], int32);
-
-/*
- * Find max length of name and default fields in the given defn array.
- * Return #items in defn array.
- */
-static int32
-arg_strlen(const arg_t * defn, int32 * namelen, int32 * deflen)
-{
- int32 i, l;
-
- *namelen = *deflen = 0;
- for (i = 0; defn[i].name; i++) {
- l = strlen(defn[i].name);
- if (*namelen < l)
- *namelen = l;
-
- if (defn[i].deflt)
- l = strlen(defn[i].deflt);
- else
- l = strlen("(null)");
- /* E_INFO("string default, %s , name %s, length %d\n",defn[i].deflt,defn[i].name,l); */
- if (*deflen < l)
- *deflen = l;
- }
-
- return i;
-}
-
-
-static int32
-cmp_name(const void *a, const void *b)
-{
- return (strcmp_nocase
- ((* (arg_t**) a)->name,
- (* (arg_t**) b)->name));
-}
-
-static arg_t const **
-arg_sort(const arg_t * defn, int32 n)
-{
- const arg_t ** pos;
- int32 i;
-
- pos = (arg_t const **) ckd_calloc(n, sizeof(arg_t *));
- for (i = 0; i < n; ++i)
- pos[i] = &defn[i];
- qsort(pos, n, sizeof(arg_t *), cmp_name);
-
- return pos;
-}
-
-static size_t
-strnappend(char **dest, size_t *dest_allocation,
- const char *source, size_t n)
-{
- size_t source_len, required_allocation;
-
- if (dest == NULL || dest_allocation == NULL)
- return -1;
- if (*dest == NULL && *dest_allocation != 0)
- return -1;
- if (source == NULL)
- return *dest_allocation;
-
- source_len = strlen(source);
- if (n && n < source_len)
- source_len = n;
-
- required_allocation = (*dest ? strlen(*dest) : 0) + source_len + 1;
- if (*dest_allocation < required_allocation) {
- if (*dest_allocation == 0) {
- *dest = (char *)ckd_calloc(required_allocation * 2, 1);
- } else {
- *dest = (char *)ckd_realloc(*dest, required_allocation * 2);
- }
- *dest_allocation = required_allocation * 2;
- }
-
- strncat(*dest, source, source_len);
-
- return *dest_allocation;
-}
-
-static size_t
-strappend(char **dest, size_t *dest_allocation,
- const char *source)
-{
- return strnappend(dest, dest_allocation, source, 0);
-}
-
-static char*
-arg_resolve_env(const char *str)
-{
- char *resolved_str = NULL;
- char env_name[100];
- const char *env_val;
- size_t alloced = 0;
- const char *i = str, *j;
-
- /* calculate required resolved_str size */
- do {
- j = strstr(i, "$(");
- if (j != NULL) {
- if (j != i) {
- strnappend(&resolved_str, &alloced, i, j - i);
- i = j;
- }
- j = strchr(i + 2, ')');
- if (j != NULL) {
- if (j - (i + 2) < 100) {
- strncpy(env_name, i + 2, j - (i + 2));
- env_name[j - (i + 2)] = '\0';
- #if !defined(_WIN32_WCE)
- env_val = getenv(env_name);
- if (env_val)
- strappend(&resolved_str, &alloced, env_val);
- #else
- env_val = 0;
- #endif
- }
- i = j + 1;
- } else {
- /* unclosed, copy and skip */
- j = i + 2;
- strnappend(&resolved_str, &alloced, i, j - i);
- i = j;
- }
- } else {
- strappend(&resolved_str, &alloced, i);
- }
- } while(j != NULL);
-
- return resolved_str;
-}
-
-static void
-arg_dump_r(cmd_ln_t *cmdln, FILE *fp, const arg_t * defn, int32 doc)
-{
- arg_t const **pos;
- int32 i, n;
- size_t l;
- int32 namelen, deflen;
- anytype_t *vp;
- char const **array;
-
- /* No definitions, do nothing. */
- if (defn == NULL || fp == NULL)
- return;
-
- /* Find max lengths of name and default value fields, and #entries in defn */
- n = arg_strlen(defn, &namelen, &deflen);
- /* E_INFO("String length %d. Name length %d, Default Length %d\n",n, namelen, deflen); */
- namelen = namelen & 0xfffffff8; /* Previous tab position */
- deflen = deflen & 0xfffffff8; /* Previous tab position */
-
- fprintf(fp, "[NAME]");
- for (l = strlen("[NAME]"); l < namelen; l += 8)
- fprintf(fp, "\t");
- fprintf(fp, "\t[DEFLT]");
- for (l = strlen("[DEFLT]"); l < deflen; l += 8)
- fprintf(fp, "\t");
-
- if (doc) {
- fprintf(fp, "\t[DESCR]\n");
- }
- else {
- fprintf(fp, "\t[VALUE]\n");
- }
-
- /* Print current configuration, sorted by name */
- pos = arg_sort(defn, n);
- for (i = 0; i < n; i++) {
- fprintf(fp, "%s", pos[i]->name);
- for (l = strlen(pos[i]->name); l < namelen; l += 8)
- fprintf(fp, "\t");
-
- fprintf(fp, "\t");
- if (pos[i]->deflt) {
- fprintf(fp, "%s", pos[i]->deflt);
- l = strlen(pos[i]->deflt);
- }
- else
- l = 0;
- for (; l < deflen; l += 8)
- fprintf(fp, "\t");
-
- fprintf(fp, "\t");
- if (doc) {
- if (pos[i]->doc)
- fprintf(fp, "%s", pos[i]->doc);
- }
- else {
- vp = cmd_ln_access_r(cmdln, pos[i]->name);
- if (vp) {
- switch (pos[i]->type) {
- case ARG_INTEGER:
- case REQARG_INTEGER:
- fprintf(fp, "%ld", vp->i);
- break;
- case ARG_FLOATING:
- case REQARG_FLOATING:
- fprintf(fp, "%e", vp->fl);
- break;
- case ARG_STRING:
- case REQARG_STRING:
- if (vp->ptr)
- fprintf(fp, "%s", (char *)vp->ptr);
- break;
- case ARG_STRING_LIST:
- array = (char const**)vp->ptr;
- if (array)
- for (l = 0; array[l] != 0; l++) {
- fprintf(fp, "%s,", array[l]);
- }
- break;
- case ARG_BOOLEAN:
- case REQARG_BOOLEAN:
- fprintf(fp, "%s", vp->i ? "yes" : "no");
- break;
- default:
- E_ERROR("Unknown argument type: %d\n", pos[i]->type);
- }
- }
- }
-
- fprintf(fp, "\n");
- }
- ckd_free(pos);
-
- fprintf(fp, "\n");
-}
-
-static char **
-parse_string_list(const char *str)
-{
- int count, i, j;
- const char *p;
- char **result;
-
- p = str;
- count = 1;
- while (*p) {
- if (*p == ',')
- count++;
- p++;
- }
- /* Should end with NULL */
- result = (char **) ckd_calloc(count + 1, sizeof(char *));
- p = str;
- for (i = 0; i < count; i++) {
- for (j = 0; p[j] != ',' && p[j] != 0; j++);
- result[i] = (char *)ckd_calloc(j + 1, sizeof(char));
- strncpy( result[i], p, j);
- p = p + j + 1;
- }
- return result;
-}
-
-static cmd_ln_val_t *
-cmd_ln_val_init(int t, const char *str)
-{
- cmd_ln_val_t *v;
- anytype_t val;
- char *e_str;
-
- if (!str) {
- /* For lack of a better default value. */
- memset(&val, 0, sizeof(val));
- }
- else {
- int valid = 1;
- e_str = arg_resolve_env(str);
-
- switch (t) {
- case ARG_INTEGER:
- case REQARG_INTEGER:
- if (sscanf(e_str, "%ld", &val.i) != 1)
- valid = 0;
- break;
- case ARG_FLOATING:
- case REQARG_FLOATING:
- if (e_str == NULL || e_str[0] == 0)
- valid = 0;
- val.fl = atof_c(e_str);
- break;
- case ARG_BOOLEAN:
- case REQARG_BOOLEAN:
- if ((e_str[0] == 'y') || (e_str[0] == 't') ||
- (e_str[0] == 'Y') || (e_str[0] == 'T') || (e_str[0] == '1')) {
- val.i = TRUE;
- }
- else if ((e_str[0] == 'n') || (e_str[0] == 'f') ||
- (e_str[0] == 'N') || (e_str[0] == 'F') |
- (e_str[0] == '0')) {
- val.i = FALSE;
- }
- else {
- E_ERROR("Unparsed boolean value '%s'\n", str);
- valid = 0;
- }
- break;
- case ARG_STRING:
- case REQARG_STRING:
- val.ptr = ckd_salloc(e_str);
- break;
- case ARG_STRING_LIST:
- val.ptr = parse_string_list(e_str);
- break;
- default:
- E_ERROR("Unknown argument type: %d\n", t);
- valid = 0;
- }
-
- ckd_free(e_str);
- if (valid == 0)
- return NULL;
- }
-
- v = (cmd_ln_val_t *)ckd_calloc(1, sizeof(*v));
- memcpy(v, &val, sizeof(val));
- v->type = t;
-
- return v;
-}
-
-/*
- * Handles option parsing for cmd_ln_parse_file_r() and cmd_ln_init()
- * also takes care of storing argv.
- * DO NOT call it from cmd_ln_parse_r()
- */
-static cmd_ln_t *
-parse_options(cmd_ln_t *cmdln, const arg_t *defn, int32 argc, char* argv[], int32 strict)
-{
- cmd_ln_t *new_cmdln;
-
- new_cmdln = cmd_ln_parse_r(cmdln, defn, argc, argv, strict);
- /* If this failed then clean up and return NULL. */
- if (new_cmdln == NULL) {
- int32 i;
- for (i = 0; i < argc; ++i)
- ckd_free(argv[i]);
- ckd_free(argv);
- return NULL;
- }
-
- /* Otherwise, we need to add the contents of f_argv to the new object. */
- if (new_cmdln == cmdln) {
- /* If we are adding to a previously passed-in cmdln, then
- * store our allocated strings in its f_argv. */
- new_cmdln->f_argv = (char **)ckd_realloc(new_cmdln->f_argv,
- (new_cmdln->f_argc + argc)
- * sizeof(*new_cmdln->f_argv));
- memcpy(new_cmdln->f_argv + new_cmdln->f_argc, argv,
- argc * sizeof(*argv));
- ckd_free(argv);
- new_cmdln->f_argc += argc;
- }
- else {
- /* Otherwise, store f_argc and f_argv. */
- new_cmdln->f_argc = argc;
- new_cmdln->f_argv = argv;
- }
-
- return new_cmdln;
-}
-
-void
-cmd_ln_val_free(cmd_ln_val_t *val)
-{
- int i;
- if (val->type & ARG_STRING_LIST) {
- char ** array = (char **)val->val.ptr;
- if (array) {
- for (i = 0; array[i] != NULL; i++) {
- ckd_free(array[i]);
- }
- ckd_free(array);
- }
- }
- if (val->type & ARG_STRING)
- ckd_free(val->val.ptr);
- ckd_free(val);
-}
-
-cmd_ln_t *
-cmd_ln_get(void)
-{
- return global_cmdln;
-}
-
-void
-cmd_ln_appl_enter(int argc, char *argv[],
- const char *default_argfn,
- const arg_t * defn)
-{
- /* Look for default or specified arguments file */
- const char *str;
-
- str = NULL;
-
- if ((argc == 2) && (strcmp(argv[1], "help") == 0)) {
- cmd_ln_print_help(stderr, defn);
- exit(1);
- }
-
- if ((argc == 2) && (argv[1][0] != '-'))
- str = argv[1];
- else if (argc == 1) {
- FILE *fp;
- E_INFO("Looking for default argument file: %s\n", default_argfn);
-
- if ((fp = fopen(default_argfn, "r")) == NULL) {
- E_INFO("Can't find default argument file %s.\n",
- default_argfn);
- }
- else {
- str = default_argfn;
- }
- if (fp != NULL)
- fclose(fp);
- }
-
-
- if (str) {
- /* Build command line argument list from file */
- E_INFO("Parsing command lines from file %s\n", str);
- if (cmd_ln_parse_file(defn, str, TRUE)) {
- E_INFOCONT("Usage:\n");
- E_INFOCONT("\t%s argument-list, or\n", argv[0]);
- E_INFOCONT("\t%s [argument-file] (default file: . %s)\n\n",
- argv[0], default_argfn);
- cmd_ln_print_help(stderr, defn);
- exit(1);
- }
- }
- else {
- cmd_ln_parse(defn, argc, argv, TRUE);
- }
-}
-
-void
-cmd_ln_appl_exit()
-{
- cmd_ln_free();
-}
-
-
-cmd_ln_t *
-cmd_ln_parse_r(cmd_ln_t *inout_cmdln, const arg_t * defn, int32 argc, char *argv[], int strict)
-{
- int32 i, j, n, argstart;
- hash_table_t *defidx = NULL;
- cmd_ln_t *cmdln;
-
- /* Construct command-line object */
- if (inout_cmdln == NULL) {
- cmdln = (cmd_ln_t*)ckd_calloc(1, sizeof(*cmdln));
- cmdln->refcount = 1;
- }
- else
- cmdln = inout_cmdln;
-
- /* Build a hash table for argument definitions */
- defidx = hash_table_new(50, 0);
- if (defn) {
- for (n = 0; defn[n].name; n++) {
- void *v;
-
- v = hash_table_enter(defidx, defn[n].name, (void *)&defn[n]);
- if (strict && (v != &defn[n])) {
- E_ERROR("Duplicate argument name in definition: %s\n", defn[n].name);
- goto error;
- }
- }
- }
- else {
- /* No definitions. */
- n = 0;
- }
-
- /* Allocate memory for argument values */
- if (cmdln->ht == NULL)
- cmdln->ht = hash_table_new(n, 0 /* argument names are case-sensitive */ );
-
-
- /* skip argv[0] if it doesn't start with dash */
- argstart = 0;
- if (argc > 0 && argv[0][0] != '-') {
- argstart = 1;
- }
-
- /* Parse command line arguments (name-value pairs) */
- for (j = argstart; j < argc; j += 2) {
- arg_t *argdef;
- cmd_ln_val_t *val;
- void *v;
-
- if (hash_table_lookup(defidx, argv[j], &v) < 0) {
- if (strict) {
- E_ERROR("Unknown argument name '%s'\n", argv[j]);
- goto error;
- }
- else if (defn == NULL)
- v = NULL;
- else
- continue;
- }
- argdef = (arg_t *)v;
-
- /* Enter argument value */
- if (j + 1 >= argc) {
- cmd_ln_print_help_r(cmdln, stderr, defn);
- E_ERROR("Argument value for '%s' missing\n", argv[j]);
- goto error;
- }
-
- if (argdef == NULL)
- val = cmd_ln_val_init(ARG_STRING, argv[j + 1]);
- else {
- if ((val = cmd_ln_val_init(argdef->type, argv[j + 1])) == NULL) {
- cmd_ln_print_help_r(cmdln, stderr, defn);
- E_ERROR("Bad argument value for %s: %s\n", argv[j],
- argv[j + 1]);
- goto error;
- }
- }
-
- if ((v = hash_table_enter(cmdln->ht, argv[j], (void *)val)) !=
- (void *)val)
- {
- if (strict) {
- cmd_ln_val_free(val);
- E_ERROR("Duplicate argument name in arguments: %s\n",
- argdef->name);
- goto error;
- }
- else {
- v = hash_table_replace(cmdln->ht, argv[j], (void *)val);
- cmd_ln_val_free((cmd_ln_val_t *)v);
- }
- }
- }
-
- /* Fill in default values, if any, for unspecified arguments */
- for (i = 0; i < n; i++) {
- cmd_ln_val_t *val;
- void *v;
-
- if (hash_table_lookup(cmdln->ht, defn[i].name, &v) < 0) {
- if ((val = cmd_ln_val_init(defn[i].type, defn[i].deflt)) == NULL) {
- E_ERROR
- ("Bad default argument value for %s: %s\n",
- defn[i].name, defn[i].deflt);
- goto error;
- }
- hash_table_enter(cmdln->ht, defn[i].name, (void *)val);
- }
- }
-
- /* Check for required arguments; exit if any missing */
- j = 0;
- for (i = 0; i < n; i++) {
- if (defn[i].type & ARG_REQUIRED) {
- void *v;
- if (hash_table_lookup(cmdln->ht, defn[i].name, &v) != 0)
- E_ERROR("Missing required argument %s\n", defn[i].name);
- }
- }
- if (j > 0) {
- cmd_ln_print_help_r(cmdln, stderr, defn);
- goto error;
- }
-
- if (strict && argc == 1) {
- E_ERROR("No arguments given, available options are:\n");
- cmd_ln_print_help_r(cmdln, stderr, defn);
- if (defidx)
- hash_table_free(defidx);
- if (inout_cmdln == NULL)
- cmd_ln_free_r(cmdln);
- return NULL;
- }
-
-#ifndef _WIN32_WCE
- /* Set up logging. We need to do this earlier because we want to dump
- * the information to the configured log, not to the stderr. */
- if (cmd_ln_exists_r(cmdln, "-logfn") && cmd_ln_str_r(cmdln, "-logfn")) {
- if (err_set_logfile(cmd_ln_str_r(cmdln, "-logfn")) < 0)
- E_FATAL_SYSTEM("cannot redirect log output");
- }
-
- /* Echo command line */
- E_INFO("Parsing command line:\n");
- for (i = 0; i < argc; i++) {
- if (argv[i][0] == '-')
- E_INFOCONT("\\\n\t");
- E_INFOCONT("%s ", argv[i]);
- }
- E_INFOCONT("\n\n");
-
- /* Print configuration */
- E_INFOCONT("Current configuration:\n");
- arg_dump_r(cmdln, err_get_logfp(), defn, 0);
-#endif
-
- hash_table_free(defidx);
- return cmdln;
-
- error:
- if (defidx)
- hash_table_free(defidx);
- if (inout_cmdln == NULL)
- cmd_ln_free_r(cmdln);
- E_ERROR("Failed to parse arguments list\n");
- return NULL;
-}
-
-cmd_ln_t *
-cmd_ln_init(cmd_ln_t *inout_cmdln, const arg_t *defn, int32 strict, ...)
-{
- va_list args;
- const char *arg, *val;
- char **f_argv;
- int32 f_argc;
-
- va_start(args, strict);
- f_argc = 0;
- while ((arg = va_arg(args, const char *))) {
- ++f_argc;
- val = va_arg(args, const char*);
- if (val == NULL) {
- E_ERROR("Number of arguments must be even!\n");
- return NULL;
- }
- ++f_argc;
- }
- va_end(args);
-
- /* Now allocate f_argv */
- f_argv = (char**)ckd_calloc(f_argc, sizeof(*f_argv));
- va_start(args, strict);
- f_argc = 0;
- while ((arg = va_arg(args, const char *))) {
- f_argv[f_argc] = ckd_salloc(arg);
- ++f_argc;
- val = va_arg(args, const char*);
- f_argv[f_argc] = ckd_salloc(val);
- ++f_argc;
- }
- va_end(args);
-
- return parse_options(inout_cmdln, defn, f_argc, f_argv, strict);
-}
-
-int
-cmd_ln_parse(const arg_t * defn, int32 argc, char *argv[], int strict)
-{
- cmd_ln_t *cmdln;
-
- cmdln = cmd_ln_parse_r(global_cmdln, defn, argc, argv, strict);
- if (cmdln == NULL) {
- /* Old, bogus behaviour... */
- E_ERROR("Failed to parse arguments list, forced exit\n");
- exit(-1);
- }
- /* Initialize global_cmdln if not present. */
- if (global_cmdln == NULL) {
- global_cmdln = cmdln;
- }
- return 0;
-}
-
-cmd_ln_t *
-cmd_ln_parse_file_r(cmd_ln_t *inout_cmdln, const arg_t * defn, const char *filename, int32 strict)
-{
- FILE *file;
- int argc;
- int argv_size;
- char *str;
- int arg_max_length = 512;
- int len = 0;
- int quoting, ch;
- char **f_argv;
- int rv = 0;
- const char separator[] = " \t\r\n";
-
- if ((file = fopen(filename, "r")) == NULL) {
- E_ERROR("Cannot open configuration file %s for reading\n",
- filename);
- return NULL;
- }
-
- ch = fgetc(file);
- /* Skip to the next interesting character */
- for (; ch != EOF && strchr(separator, ch); ch = fgetc(file)) ;
-
- if (ch == EOF) {
- fclose(file);
- return NULL;
- }
-
- /*
- * Initialize default argv, argc, and argv_size.
- */
- argv_size = 10;
- argc = 0;
- f_argv = (char **)ckd_calloc(argv_size, sizeof(char *));
- /* Silently make room for \0 */
- str = (char* )ckd_calloc(arg_max_length + 1, sizeof(char));
- quoting = 0;
-
- do {
- /* Handle arguments that are commented out */
- if (len == 0 && argc % 2 == 0) {
- while (ch == '#') {
- /* Skip everything until newline */
- for (ch = fgetc(file); ch != EOF && ch != '\n'; ch = fgetc(file)) ;
- /* Skip to the next interesting character */
- for (ch = fgetc(file); ch != EOF && strchr(separator, ch); ch = fgetc(file)) ;
- }
-
- /* Check if we are at the last line (without anything interesting in it) */
- if (ch == EOF)
- break;
- }
-
- /* Handle quoted arguments */
- if (ch == '"' || ch == '\'') {
- if (quoting == ch) /* End a quoted section with the same type */
- quoting = 0;
- else if (quoting) {
- E_ERROR("Nesting quotations is not supported!\n");
- rv = 1;
- break;
- }
- else
- quoting = ch; /* Start a quoted section */
- }
- else if (ch == EOF || (!quoting && strchr(separator, ch))) {
- /* Reallocate argv so it is big enough to contain all the arguments */
- if (argc >= argv_size) {
- char **tmp_argv;
- if (!(tmp_argv =
- (char **)ckd_realloc(f_argv, argv_size * 2 * sizeof(char *)))) {
- rv = 1;
- break;
- }
- f_argv = tmp_argv;
- argv_size *= 2;
- }
- /* Add the string to the list of arguments */
- f_argv[argc] = ckd_salloc(str);
- len = 0;
- str[0] = '\0';
- argc++;
-
- if (quoting)
- E_WARN("Unclosed quotation, having EOF close it...\n");
-
- /* Skip to the next interesting character */
- for (; ch != EOF && strchr(separator, ch); ch = fgetc(file)) ;
-
- if (ch == EOF)
- break;
-
- /* We already have the next character */
- continue;
- }
- else {
- if (len >= arg_max_length) {
- /* Make room for more chars (including the \0 !) */
- char *tmp_str = str;
- if ((tmp_str = (char *)ckd_realloc(str, (1 + arg_max_length * 2) * sizeof(char))) == NULL) {
- rv = 1;
- break;
- }
- str = tmp_str;
- arg_max_length *= 2;
- }
- /* Add the char to the argument string */
- str[len++] = ch;
- /* Always null terminate */
- str[len] = '\0';
- }
-
- ch = fgetc(file);
- } while (1);
-
- fclose(file);
-
- ckd_free(str);
-
- if (rv) {
- for (ch = 0; ch < argc; ++ch)
- ckd_free(f_argv[ch]);
- ckd_free(f_argv);
- return NULL;
- }
-
- return parse_options(inout_cmdln, defn, argc, f_argv, strict);
-}
-
-int
-cmd_ln_parse_file(const arg_t * defn, const char *filename, int32 strict)
-{
- cmd_ln_t *cmdln;
-
- cmdln = cmd_ln_parse_file_r(global_cmdln, defn, filename, strict);
- if (cmdln == NULL) {
- return -1;
- }
- /* Initialize global_cmdln if not present. */
- if (global_cmdln == NULL) {
- global_cmdln = cmdln;
- }
- return 0;
-}
-
-void
-cmd_ln_print_help_r(cmd_ln_t *cmdln, FILE *fp, arg_t const* defn)
-{
- if (defn == NULL)
- return;
- fprintf(fp, "Arguments list definition:\n");
- arg_dump_r(cmdln, fp, defn, 1);
-}
-
-int
-cmd_ln_exists_r(cmd_ln_t *cmdln, const char *name)
-{
- void *val;
- if (cmdln == NULL)
- return FALSE;
- return (hash_table_lookup(cmdln->ht, name, &val) == 0);
-}
-
-anytype_t *
-cmd_ln_access_r(cmd_ln_t *cmdln, const char *name)
-{
- void *val;
- if (hash_table_lookup(cmdln->ht, name, &val) < 0) {
- E_ERROR("Unknown argument: %s\n", name);
- return NULL;
- }
- return (anytype_t *)val;
-}
-
-char const *
-cmd_ln_str_r(cmd_ln_t *cmdln, char const *name)
-{
- anytype_t *val;
- val = cmd_ln_access_r(cmdln, name);
- if (val == NULL)
- return NULL;
- return (char const *)val->ptr;
-}
-
-char const **
-cmd_ln_str_list_r(cmd_ln_t *cmdln, char const *name)
-{
- anytype_t *val;
- val = cmd_ln_access_r(cmdln, name);
- if (val == NULL)
- return NULL;
- return (char const **)val->ptr;
-}
-
-long
-cmd_ln_int_r(cmd_ln_t *cmdln, char const *name)
-{
- anytype_t *val;
- val = cmd_ln_access_r(cmdln, name);
- if (val == NULL)
- return 0L;
- return val->i;
-}
-
-double
-cmd_ln_float_r(cmd_ln_t *cmdln, char const *name)
-{
- anytype_t *val;
- val = cmd_ln_access_r(cmdln, name);
- if (val == NULL)
- return 0.0;
- return val->fl;
-}
-
-void
-cmd_ln_set_str_r(cmd_ln_t *cmdln, char const *name, char const *str)
-{
- anytype_t *val;
- val = cmd_ln_access_r(cmdln, name);
- if (val == NULL) {
- E_ERROR("Unknown argument: %s\n", name);
- return;
- }
- ckd_free(val->ptr);
- if (str == NULL)
- val->ptr = NULL;
- else
- val->ptr = ckd_salloc(str);
-}
-
-void
-cmd_ln_set_int_r(cmd_ln_t *cmdln, char const *name, long iv)
-{
- anytype_t *val;
- val = cmd_ln_access_r(cmdln, name);
- if (val == NULL) {
- E_ERROR("Unknown argument: %s\n", name);
- return;
- }
- val->i = iv;
-}
-
-void
-cmd_ln_set_float_r(cmd_ln_t *cmdln, char const *name, double fv)
-{
- anytype_t *val;
- val = cmd_ln_access_r(cmdln, name);
- if (val == NULL) {
- E_ERROR("Unknown argument: %s\n", name);
- return;
- }
- val->fl = fv;
-}
-
-cmd_ln_t *
-cmd_ln_retain(cmd_ln_t *cmdln)
-{
- ++cmdln->refcount;
- return cmdln;
-}
-
-int
-cmd_ln_free_r(cmd_ln_t *cmdln)
-{
- if (cmdln == NULL)
- return 0;
- if (--cmdln->refcount > 0)
- return cmdln->refcount;
-
- if (cmdln->ht) {
- glist_t entries;
- gnode_t *gn;
- int32 n;
-
- entries = hash_table_tolist(cmdln->ht, &n);
- for (gn = entries; gn; gn = gnode_next(gn)) {
- hash_entry_t *e = (hash_entry_t *)gnode_ptr(gn);
- cmd_ln_val_free((cmd_ln_val_t *)e->val);
- }
- glist_free(entries);
- hash_table_free(cmdln->ht);
- cmdln->ht = NULL;
- }
-
- if (cmdln->f_argv) {
- int32 i;
- for (i = 0; i < cmdln->f_argc; ++i) {
- ckd_free(cmdln->f_argv[i]);
- }
- ckd_free(cmdln->f_argv);
- cmdln->f_argv = NULL;
- cmdln->f_argc = 0;
- }
- ckd_free(cmdln);
- return 0;
-}
-
-void
-cmd_ln_free(void)
-{
- cmd_ln_free_r(global_cmdln);
- global_cmdln = NULL;
-}
-
-/* vim: set ts=4 sw=4: */