Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

clp.c File Reference

#include "clp.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <stdarg.h>
#include <ctype.h>

Go to the source code of this file.


Data Structures

struct  Clp_ArgType
struct  Clp_BuildString
struct  Clp_Internal
struct  Clp_LongMinMatch
struct  Clp_ParserState
struct  Clp_StringList

Defines

#define HAVE_STRTOUL   1
#define Clp_DoubledLong   (Clp_LongImplicit * 2)
#define Clp_AnyArgument   (Clp_Mandatory | Clp_Optional)
#define MAX_AMBIGUOUS_VALUES   4
#define TEST(o, f)   (((o)->flags & (f)) != 0)
#define ENSURE_BUILD_STRING(bs, space)

Typedefs

typedef Clp_StringList Clp_StringList
typedef Clp_BuildString Clp_BuildString

Functions

int calculate_long_min_match (int, Clp_Option *, int, int, int)
int parse_string (Clp_Parser *, const char *, int, void *)
int parse_int (Clp_Parser *, const char *, int, void *)
int parse_bool (Clp_Parser *, const char *, int, void *)
int parse_double (Clp_Parser *, const char *, int, void *)
int parse_string_list (Clp_Parser *, const char *, int, void *)
int ambiguity_error (Clp_Parser *, int, int *, Clp_Option *, const char *, const char *,...)
void check_duplicated_short_options (int nopt, Clp_Option *opt, int negated)
Clp_ParserClp_NewParser (int argc, char *const argv[], int nopt, Clp_Option *opt)
void Clp_DeleteParser (Clp_Parser *clp)
int Clp_SetOptionProcessing (Clp_Parser *clp, int option_processing)
Clp_ErrorHandler Clp_SetErrorHandler (Clp_Parser *clp, void(*error_handler)(char *))
int Clp_SetOptionChar (Clp_Parser *clp, int c, int option_type)
int min_different_chars (char *s, char *t)
int argcmp (const char *ref, const char *arg, int min_match)
int find_prefix_opt (const char *arg, int nopt, Clp_Option *opt, Clp_LongMinMatch *lmmvec, int *ambiguous, int *ambiguous_values, int negated)
int Clp_AddType (Clp_Parser *clp, int type_id, int flags, Clp_ArgParseFunc func, void *thunk)
int finish_string_list (Clp_Parser *clp, int type_id, int flags, Clp_Option *items, int nitems, int itemscap)
int Clp_AddStringListType (Clp_Parser *clp, int type_id, int flags,...)
int Clp_AddStringListTypeVec (Clp_Parser *clp, int type_id, int flags, int nitems, char **strings, int *values)
char * Clp_ProgramName (Clp_Parser *clp)
Clp_ParserStateClp_NewParserState (void)
void Clp_DeleteParserState (Clp_ParserState *save)
void Clp_SaveParser (Clp_Parser *clp, Clp_ParserState *save)
void Clp_RestoreParser (Clp_Parser *clp, Clp_ParserState *save)
void set_option_text (Clp_Internal *cli, char *text, int n_option_chars)
int next_argument (Clp_Parser *clp, int want_argument)
void switch_to_short_argument (Clp_Parser *clp)
Clp_Optionfind_long (Clp_Parser *clp, char *arg)
Clp_Optionfind_short (Clp_Parser *clp, int short_name)
int Clp_Next (Clp_Parser *clp)
char * Clp_Shift (Clp_Parser *clp, int allow_dashes)
Clp_BuildStringnew_build_string (void)
void free_build_string (Clp_BuildString *bs)
int grow_build_string (Clp_BuildString *bs, int want)
void append_build_string (Clp_BuildString *bs, const char *s, int l)
Clp_BuildStringClp_VaOptionError (Clp_Parser *clp, Clp_BuildString *bs, const char *fmt, va_list val)
void do_error (Clp_Parser *clp, Clp_BuildString *bs)
int Clp_OptionError (Clp_Parser *clp, const char *fmt,...)

Define Documentation

#define Clp_AnyArgument   (Clp_Mandatory | Clp_Optional)
 

Definition at line 33 of file clp.c.

Referenced by Clp_NewParser(), and Clp_Next().

#define Clp_DoubledLong   (Clp_LongImplicit * 2)
 

Definition at line 31 of file clp.c.

Referenced by next_argument().

#define ENSURE_BUILD_STRING bs,
space   
 

Value:

((((bs)->pos - (bs)->text) + (space) >= (bs)->capacity)         \
   || grow_build_string((bs), ((bs)->pos - (bs)->text) + (space)))

Definition at line 1246 of file clp.c.

Referenced by append_build_string(), and Clp_VaOptionError().

#define HAVE_STRTOUL   1
 

Definition at line 23 of file clp.c.

#define MAX_AMBIGUOUS_VALUES   4
 

Definition at line 35 of file clp.c.

Referenced by ambiguity_error(), find_long(), find_prefix_opt(), finish_string_list(), and parse_string_list().

#define TEST o,
     (((o)->flags & (f)) != 0)
 

Definition at line 115 of file clp.c.

Referenced by check_duplicated_short_options(), Clp_NewParser(), Clp_Next(), find_prefix_opt(), and find_short().


Typedef Documentation

typedef struct Clp_BuildString Clp_BuildString
 

typedef struct Clp_StringList Clp_StringList
 


Function Documentation

int ambiguity_error Clp_Parser  ,
int   ,
int *   ,
Clp_Option  ,
const char *   ,
const char *   ,
...   
[static]
 

Definition at line 1389 of file clp.c.

References append_build_string(), Clp_VaOptionError(), do_error(), free_build_string(), i, Clp_Parser::internal, MAX_AMBIGUOUS_VALUES, and Clp_Internal::program_name.

Referenced by Clp_Next(), and parse_string_list().

01392 {
01393   Clp_BuildString *bs;
01394   int i;
01395   va_list val;
01396   va_start(val, fmt);
01397   bs = Clp_VaOptionError(clp, 0, fmt, val);
01398   if (!bs) goto done;
01399   
01400   append_build_string(bs, clp->internal->program_name, -1);
01401   append_build_string(bs, ": (Possibilities are", -1);
01402   
01403   for (i = 0; i < ambiguous && i < MAX_AMBIGUOUS_VALUES; i++) {
01404     int val = ambiguous_values[i];
01405     const char *no_dash = "";
01406     if (val < 0) val = -(val + 1), no_dash = "no-";
01407     if (i == 0)
01408       append_build_string(bs, " ", 1);
01409     else if (i == ambiguous - 1)
01410       append_build_string(bs, (i == 1 ? " and " : ", and "), -1);
01411     else
01412       append_build_string(bs, ", ", 2);
01413     append_build_string(bs, prefix, -1);
01414     append_build_string(bs, no_dash, -1);
01415     append_build_string(bs, opt[val].long_name, -1);
01416   }
01417   
01418   if (ambiguous > MAX_AMBIGUOUS_VALUES)
01419     append_build_string(bs, ", and others", -1);
01420   append_build_string(bs, ".)\n", -1);
01421   va_end(val);
01422   
01423  done:
01424   do_error(clp, bs);
01425   free_build_string(bs);
01426   return 0;
01427 }

void append_build_string Clp_BuildString   bs,
const char *    s,
int    l
[static]
 

Definition at line 1251 of file clp.c.

References ENSURE_BUILD_STRING, l, and Clp_BuildString::pos.

Referenced by ambiguity_error(), and Clp_VaOptionError().

01252 {
01253   if (l < 0) l = strlen(s);
01254   if (ENSURE_BUILD_STRING(bs, l)) {
01255     memcpy(bs->pos, s, l);
01256     bs->pos += l;
01257   }
01258 }

int argcmp const char *    ref,
const char *    arg,
int    min_match
[static]
 

Definition at line 409 of file clp.c.

References arg, and ref.

Referenced by find_long(), find_prefix_opt(), and parse_bool().

00415                 :
00416         argcmp("x", "y", 1)     -->  0  / just plain wrong
00417         argcmp("a", "ax", 1)    -->  0  / ...even though min_match == 1
00418                                         and the 1st chars match
00419         argcmp("box", "bo", 3)  --> -1  / ambiguous
00420         argcmp("cat", "c=3", 1) -->  1  / handles = arguments
00421         */
00422 {
00423   const char *refstart = ref;
00424   while (*ref && *arg && *arg != '=' && *ref == *arg)
00425     ref++, arg++;
00426   if (*arg && *arg != '=')
00427     return 0;
00428   else if (ref - refstart < min_match)
00429     return -1;
00430   else
00431     return ref - refstart;
00432 }

int calculate_long_min_match int   ,
Clp_Option  ,
int   ,
int   ,
int   
[static]
 

Definition at line 391 of file clp.c.

References Clp_Option::flags, flags, Clp_Option::long_name, min_different_chars(), and Clp_Option::option_id.

Referenced by Clp_NewParser(), and finish_string_list().

00393 {
00394   int j, lmm = 1;
00395   
00396   for (j = 0; j < nopt; j++)
00397     if (opt[j].long_name
00398         && (opt[j].flags & flags) == flags_value
00399         && opt[which].option_id != opt[j].option_id
00400         && strncmp(opt[which].long_name, opt[j].long_name, lmm) == 0)
00401       lmm = min_different_chars(opt[which].long_name, opt[j].long_name);
00402   
00403   return lmm;
00404 }

void check_duplicated_short_options int    nopt,
Clp_Option   opt,
int    negated
[static]
 

Definition at line 135 of file clp.c.

References check, Clp_Negate, Clp_OnlyNegated, i, and TEST.

Referenced by Clp_NewParser().

00136 {
00137   int i;
00138   int check[256];
00139   
00140   for (i = 0; i < 256; i++)
00141     check[i] = -1;
00142   
00143   for (i = 0; i < nopt; i++)
00144     if (opt[i].short_name > 0 && opt[i].short_name < 256
00145         && (negated ? TEST(&opt[i], Clp_Negate)
00146             : !TEST(&opt[i], Clp_OnlyNegated))) {
00147       int sh = opt[i].short_name;
00148       if (check[sh] >= 0 && check[sh] != opt[i].option_id)
00149         fprintf(stderr, "CLP error: more than 1 option has short name `%c'\n",
00150                 sh);
00151       check[sh] = opt[i].option_id;
00152     }
00153 }

int Clp_AddStringListType Clp_Parser   clp,
int    type_id,
int    flags,
...   
 

Definition at line 667 of file clp.c.

References finish_string_list(), flags, Clp_Option::flags, free, Clp_Option::long_name, malloc, name, Clp_Option::option_id, and realloc.

00669                       :
00670         Clp_AddStringListType
00671           (clp, type_id, flags,
00672            char *s_1, int value_1, ..., char *s_n, int value_n, 0);
00673 
00674         Defines type_id as a type in clp.
00675         This type accepts any of the strings s_1, ..., s_n
00676         (or unambiguous abbreviations thereof);
00677         if argument s_i is given, value_i is stored in clp->val.i.
00678         If Clp_AllowNumbers is set in flags,
00679         explicit integers are also allowed.
00680 
00681         Returns 1 on success, 0 on memory allocation errors. */
00682 {
00683   int nitems = 0;
00684   int itemscap = 5;
00685   Clp_Option *items = (Clp_Option *)malloc(sizeof(Clp_Option) * itemscap);
00686   
00687   va_list val;
00688   va_start(val, flags);
00689   
00690   if (!items) goto error;
00691   
00692   /* slurp up the arguments */
00693   while (1) {
00694     int value;
00695     char *name = va_arg(val, char *);
00696     if (!name) break;
00697     value = va_arg(val, int);
00698     
00699     if (nitems >= itemscap) {
00700       Clp_Option *new_items;
00701       itemscap *= 2;
00702       new_items = (Clp_Option *)realloc(items, sizeof(Clp_Option) * itemscap);
00703       if (!new_items) goto error;
00704       items = new_items;
00705     }
00706     
00707     items[nitems].long_name = name;
00708     items[nitems].option_id = value;
00709     items[nitems].flags = 0;
00710     nitems++;
00711   }
00712 
00713   va_end(val);
00714   if (finish_string_list(clp, type_id, flags, items, nitems, itemscap))
00715     return 1;
00716   
00717  error:
00718   va_end(val);
00719   if (items) free(items);
00720   return 0;
00721 }

int Clp_AddStringListTypeVec Clp_Parser   clp,
int    type_id,
int    flags,
int    nitems,
char **    strings,
int *    values
 

Definition at line 725 of file clp.c.

References finish_string_list(), flags, free, i, and malloc.

00730 {
00731   int i;
00732   int itemscap = (nitems < 5 ? 5 : nitems);
00733   Clp_Option *items = (Clp_Option *)malloc(sizeof(Clp_Option) * itemscap);
00734   if (!items) return 0;
00735   
00736   /* copy over items */
00737   for (i = 0; i < nitems; i++) {
00738     items[i].long_name = strings[i];
00739     items[i].option_id = values[i];
00740     items[i].flags = 0;
00741   }
00742   
00743   if (finish_string_list(clp, type_id, flags, items, nitems, itemscap))
00744     return 1;
00745   else {
00746     free(items);
00747     return 0;
00748   }
00749 }

int Clp_AddType Clp_Parser   clp,
int    type_id,
int    flags,
Clp_ArgParseFunc    func,
void *    thunk
 

Definition at line 470 of file clp.c.

References Clp_Internal::argtype, Clp_ArgParseFunc, flags, Clp_ArgType::flags, Clp_ArgType::func, i, Clp_Parser::internal, Clp_Internal::nargtype, realloc, and Clp_ArgType::thunk.

Referenced by Clp_NewParser(), finish_string_list(), and main().

00479 {
00480   int i;
00481   Clp_Internal *cli = clp->internal;
00482   Clp_ArgType *new_argtype;
00483   int nargtype = cli->nargtype;
00484   assert(nargtype);
00485   
00486   if (type_id <= 0 || !func) return 0;
00487   
00488   while (nargtype <= type_id)
00489     nargtype *= 2;
00490   new_argtype = (Clp_ArgType *)
00491     realloc(cli->argtype, sizeof(Clp_ArgType) * nargtype);
00492   if (!new_argtype) return 0;
00493   cli->argtype = new_argtype;
00494   
00495   for (i = cli->nargtype; i < nargtype; i++)
00496     cli->argtype[i].func = 0;
00497   cli->nargtype = nargtype;
00498   
00499   cli->argtype[type_id].func = func;
00500   cli->argtype[type_id].flags = flags;
00501   cli->argtype[type_id].thunk = thunk;
00502   return 1;
00503 }

void Clp_DeleteParser Clp_Parser   clp
 

Definition at line 257 of file clp.c.

References Clp_Internal::argtype, free, i, Clp_Parser::internal, Clp_StringList::items, Clp_StringList::long_min_match, Clp_Internal::long_min_match, Clp_Internal::nargtype, and parse_string_list().

00260 {
00261   int i;
00262   Clp_Internal *cli;
00263   if (!clp) return;
00264   
00265   cli = clp->internal;
00266   
00267   /* get rid of any string list types */
00268   for (i = 0; i < cli->nargtype; i++)
00269     if (cli->argtype[i].func == parse_string_list) {
00270       Clp_StringList *clsl = (Clp_StringList *)cli->argtype[i].thunk;
00271       free(clsl->items);
00272       free(clsl->long_min_match);
00273       free(clsl);
00274     }
00275   
00276   free(cli->argtype);
00277   free(cli->long_min_match);
00278   free(cli);
00279   free(clp);
00280 }

void Clp_DeleteParserState Clp_ParserState   save
 

Definition at line 774 of file clp.c.

References free.

00775 {
00776   free(save);
00777 }

Clp_Parser* Clp_NewParser int    argc,
char *const    argv[],
int    nopt,
Clp_Option   opt
 

Definition at line 156 of file clp.c.

References argc, Clp_Internal::argc, Clp_Internal::argtype, Clp_Internal::argv, Clp_Internal::both_short_and_long, calculate_long_min_match(), check_duplicated_short_options(), Clp_AddType(), Clp_AnyArgument, Clp_ArgBool, Clp_ArgDouble, Clp_ArgInt, Clp_ArgString, Clp_ArgStringNotOption, Clp_ArgUnsigned, Clp_DisallowOptions, Clp_Mandatory, Clp_Negate, Clp_OnlyNegated, Clp_Optional, Clp_Short, Clp_Internal::current_option, Clp_Internal::error_handler, free, i, Clp_Parser::internal, Clp_Internal::is_short, Clp_Internal::long_min_match, malloc, Clp_Internal::nargtype, Clp_Internal::nopt, Clp_Internal::opt, Clp_Internal::option_class, Clp_Internal::option_processing, parse_bool(), parse_double(), parse_int(), parse_string(), Clp_Internal::program_name, TEST, and Clp_Internal::whole_negated.

Referenced by main().

00159 {
00160   int i;
00161   Clp_Parser *clp = (Clp_Parser *)malloc(sizeof(Clp_Parser));
00162   Clp_Internal *cli = (Clp_Internal *)malloc(sizeof(Clp_Internal));
00163   Clp_LongMinMatch *lmm = (Clp_LongMinMatch *)malloc(sizeof(Clp_LongMinMatch) * nopt);
00164   if (!clp || !cli || !lmm) goto failed;
00165   
00166   clp->internal = cli;
00167   cli->long_min_match = lmm;
00168   
00169   /* Get rid of negative option_ids, which are internal to CLP */
00170   for (i = 0; i < nopt; i++)
00171     if (opt[i].option_id < 0) {
00172       fprintf(stderr, "CLP error: option %d has negative option_id\n", i);
00173       opt[i] = opt[nopt - 1];
00174       nopt--;
00175       i--;
00176     }
00177   
00178   /* Massage the options to make them usable */
00179   for (i = 0; i < nopt; i++) {
00180     /* Enforce invariants */
00181     if (opt[i].arg_type <= 0)
00182       opt[i].flags &= ~Clp_AnyArgument;
00183     if (opt[i].arg_type > 0 && !TEST(&opt[i], Clp_Optional))
00184       opt[i].flags |= Clp_Mandatory;
00185     
00186     /* Nonexistent short options have character 256. We know this won't
00187        equal any character in an argument, even if characters are signed */
00188     if (opt[i].short_name <= 0 || opt[i].short_name > 255)
00189       opt[i].short_name = 256;
00190     
00191     /* Options that start with `no-' should be changed to OnlyNegated */
00192     if (opt[i].long_name && strncmp(opt[i].long_name, "no-", 3) == 0) {
00193       opt[i].long_name += 3;
00194       opt[i].flags |= Clp_Negate | Clp_OnlyNegated;
00195     }
00196   }
00197   
00198   /* Check for duplicated short options */
00199   check_duplicated_short_options(nopt, opt, 0);
00200   check_duplicated_short_options(nopt, opt, 1);
00201   
00202   /* Calculate long options' minimum unambiguous length */
00203   for (i = 0; i < nopt; i++)
00204     if (opt[i].long_name && !TEST(&opt[i], Clp_OnlyNegated))
00205       lmm[i].pos = calculate_long_min_match
00206         (nopt, opt, i, Clp_OnlyNegated, 0);
00207   for (i = 0; i < nopt; i++)
00208     if (opt[i].long_name && TEST(&opt[i], Clp_Negate))
00209       lmm[i].neg = calculate_long_min_match
00210         (nopt, opt, i, Clp_Negate, Clp_Negate);
00211   
00212   /* Set up clp->internal */
00213   cli->opt = opt;
00214   cli->nopt = nopt;
00215   
00216   cli->argtype = (Clp_ArgType *)malloc(sizeof(Clp_ArgType) * 5);
00217   if (!cli->argtype) goto failed;
00218   cli->nargtype = 5;
00219   
00220   cli->argc = argc;
00221   cli->argv = argv;
00222   {
00223     char *slash = strrchr(argv[0], '/');
00224     cli->program_name = slash ? slash + 1 : argv[0];
00225   }
00226   cli->error_handler = 0;
00227   
00228   for (i = 0; i < 256; i++)
00229     cli->option_class[i] = 0;
00230   cli->option_class['-'] = Clp_Short;
00231   cli->both_short_and_long = 0;
00232   
00233   cli->is_short = 0;
00234   cli->whole_negated = 0;
00235   
00236   cli->option_processing = 1;
00237   cli->current_option = 0;
00238   
00239   /* Add default type parsers */
00240   Clp_AddType(clp, Clp_ArgString, 0, parse_string, 0);
00241   Clp_AddType(clp, Clp_ArgStringNotOption, Clp_DisallowOptions, parse_string, 0);
00242   Clp_AddType(clp, Clp_ArgInt, 0, parse_int, 0);
00243   Clp_AddType(clp, Clp_ArgUnsigned, 0, parse_int, (void *)cli);
00244   Clp_AddType(clp, Clp_ArgBool, 0, parse_bool, 0);
00245   Clp_AddType(clp, Clp_ArgDouble, 0, parse_double, 0);
00246   return clp;
00247   
00248  failed:
00249   if (cli && cli->argtype) free(cli->argtype);
00250   if (cli) free(cli);
00251   if (clp) free(clp);
00252   if (lmm) free(lmm);
00253   return 0;
00254 }

Clp_ParserState* Clp_NewParserState void   
 

Definition at line 768 of file clp.c.

References malloc.

00769 {
00770   return (Clp_ParserState *)malloc(sizeof(Clp_ParserState));
00771 }

int Clp_Next Clp_Parser   clp
 

Definition at line 1042 of file clp.c.

References ambiguity_error(), Clp_Internal::ambiguous, Clp_Internal::ambiguous_values, Clp_Parser::arg, Clp_Option::arg_type, Clp_Internal::argtype, Clp_Internal::argv, Clp_AnyArgument, Clp_BadOption, Clp_DisallowOptions, Clp_Done, Clp_Error, Clp_Mandatory, Clp_Negate, Clp_NotOption, Clp_OptionError(), Clp_RestoreParser(), Clp_SaveParser(), Clp_SetOptionProcessing(), Clp_Internal::could_be_short, Clp_Internal::current_option, Clp_Internal::current_short, find_long(), find_short(), Clp_ArgType::func, Clp_Parser::have_arg, Clp_Parser::internal, Clp_Internal::is_short, Clp_Internal::nargtype, Clp_Parser::negated, Clp_Internal::negated_by_no, next_argument(), Clp_Internal::opt, Clp_Internal::option_chars, Clp_Option::option_id, Clp_Internal::option_processing, switch_to_short_argument(), TEST, Clp_Internal::text, Clp_ArgType::thunk, and Clp_Internal::whole_negated.

Referenced by main().

01062 {
01063   Clp_Internal *cli = clp->internal;
01064   Clp_Option *opt;
01065   Clp_ParserState clpsave;
01066   int complain;
01067   
01068   /** Set up clp **/
01069   cli->current_option = 0;
01070   cli->ambiguous = 0;
01071   
01072   /** Get the next argument or option **/
01073   if (!next_argument(clp, cli->option_processing ? 0 : 2))
01074     return clp->have_arg ? Clp_NotOption : Clp_Done;
01075   
01076   clp->negated = cli->whole_negated;
01077   if (cli->is_short)
01078     opt = find_short(clp, cli->text[0]);
01079   else
01080     opt = find_long(clp, cli->text);
01081   
01082   /** If there's ambiguity between long & short options, and we couldn't find
01083       a long option, look for a short option **/
01084   if (!opt && cli->could_be_short) {
01085     switch_to_short_argument(clp);
01086     opt = find_short(clp, cli->text[0]);
01087   }
01088   
01089   /** If we didn't find an option... **/
01090   if (!opt || (clp->negated && !TEST(opt, Clp_Negate))) {
01091     
01092     /* default processing for the "--" option: turn off option processing
01093        and return the next argument */
01094     if (strcmp(cli->argv[0], "--") == 0) {
01095       Clp_SetOptionProcessing(clp, 0);
01096       return Clp_Next(clp);
01097     }
01098     
01099     /* otherwise, report some error or other */
01100     if (cli->ambiguous)
01101       ambiguity_error(clp, cli->ambiguous, cli->ambiguous_values,
01102                       cli->opt, cli->option_chars,
01103                       "option `%s%s' is ambiguous",
01104                       cli->option_chars, cli->text);
01105     else if (cli->is_short && !cli->could_be_short)
01106       Clp_OptionError(clp, "unrecognized option `%s%c'",
01107                       cli->option_chars, cli->text[0]);
01108     else
01109       Clp_OptionError(clp, "unrecognized option `%s%s'",
01110                       cli->option_chars, cli->text);
01111     return Clp_BadOption;
01112   }
01113   
01114   /** Set the current option **/
01115   cli->current_option = opt;
01116   cli->current_short = cli->is_short;
01117   cli->negated_by_no = clp->negated && !cli->whole_negated;
01118   
01119   /** The no-argument (or should-have-no-argument) case **/
01120   if (clp->negated || !TEST(opt, Clp_AnyArgument)) {
01121     if (clp->have_arg) {
01122       Clp_OptionError(clp, "`%O' can't take an argument");
01123       return Clp_BadOption;
01124     } else
01125       return opt->option_id;
01126   }
01127   
01128   /** Get an argument if we need one, or if it's optional **/
01129   /* Sanity-check the argument type. */
01130   if (opt->arg_type <= 0 || opt->arg_type >= cli->nargtype
01131       || cli->argtype[ opt->arg_type ].func == 0)
01132     return Clp_Error;
01133   
01134   /* complain == 1 only if the argument was explicitly given,
01135      or it is mandatory. */
01136   complain = (clp->have_arg != 0) || TEST(opt, Clp_Mandatory);
01137   Clp_SaveParser(clp, &clpsave);
01138   
01139   if (TEST(opt, Clp_Mandatory) && !clp->have_arg) {
01140     /* Mandatory argument case */
01141     /* Allow arguments to options to start with a dash, but only if the
01142        argument type allows it by not setting Clp_DisallowOptions */
01143     int disallow = TEST(&cli->argtype[opt->arg_type], Clp_DisallowOptions);
01144     next_argument(clp, disallow ? 1 : 2);
01145     if (!clp->have_arg) {
01146       int got_option = cli->text != 0;
01147       Clp_RestoreParser(clp, &clpsave);
01148       if (got_option)
01149         Clp_OptionError(clp, "`%O' requires a non-option argument");
01150       else
01151         Clp_OptionError(clp, "`%O' requires an argument");
01152       return Clp_BadOption;
01153     }
01154     
01155   } else if (cli->is_short && !clp->have_arg && cli->text[1] != 0)
01156     /* The -[option]argument case:
01157        Assume that the rest of the current string is the argument. */
01158     next_argument(clp, 1);
01159   
01160   /** Parse the argument **/
01161   if (clp->have_arg) {
01162     Clp_ArgType *atr = &cli->argtype[ opt->arg_type ];
01163     if (atr->func(clp, clp->arg, complain, atr->thunk) <= 0) {
01164       /* parser failed */
01165       clp->have_arg = 0;
01166       if (TEST(opt, Clp_Mandatory))
01167         return Clp_BadOption;
01168       else
01169         Clp_RestoreParser(clp, &clpsave);
01170     }
01171   }
01172   
01173   return opt->option_id;
01174 }

int Clp_OptionError Clp_Parser   clp,
const char *    fmt,
...   
 

Definition at line 1376 of file clp.c.

References Clp_VaOptionError(), do_error(), and free_build_string().

Referenced by Clp_Next(), handle_extension(), main(), parse_bool(), parse_color(), parse_dimensions(), parse_double(), parse_frame_spec(), parse_int(), parse_position(), parse_rectangle(), parse_scale_factor(), and parse_two_colors().

01377 {
01378   Clp_BuildString *bs;
01379   va_list val;
01380   va_start(val, fmt);
01381   bs = Clp_VaOptionError(clp, 0, fmt, val);
01382   va_end(val);
01383   do_error(clp, bs);
01384   free_build_string(bs);
01385   return 0;
01386 }

char* Clp_ProgramName Clp_Parser   clp
 

Definition at line 757 of file clp.c.

References Clp_Parser::internal, and Clp_Internal::program_name.

Referenced by main().

00758 {
00759   return clp->internal->program_name;
00760 }

void Clp_RestoreParser Clp_Parser   clp,
Clp_ParserState   save
 

Definition at line 795 of file clp.c.

References Clp_Internal::argc, Clp_ParserState::argc, Clp_Internal::argv, Clp_ParserState::argv, Clp_Parser::internal, Clp_Internal::is_short, Clp_ParserState::is_short, Clp_Internal::option_chars, Clp_ParserState::option_chars, Clp_Internal::text, Clp_ParserState::text, Clp_Internal::whole_negated, and Clp_ParserState::whole_negated.

Referenced by Clp_Next(), and Clp_Shift().

00797 {
00798   Clp_Internal *cli = clp->internal;
00799   cli->argv = save->argv;
00800   cli->argc = save->argc;
00801   memcpy(cli->option_chars, save->option_chars, 3);
00802   cli->text = save->text;
00803   cli->is_short = save->is_short;
00804   cli->whole_negated = save->whole_negated;
00805 }

void Clp_SaveParser Clp_Parser   clp,
Clp_ParserState   save
 

Definition at line 781 of file clp.c.

References Clp_ParserState::argc, Clp_Internal::argc, Clp_ParserState::argv, Clp_Internal::argv, Clp_Parser::internal, Clp_ParserState::is_short, Clp_Internal::is_short, Clp_ParserState::option_chars, Clp_Internal::option_chars, Clp_ParserState::text, Clp_Internal::text, Clp_ParserState::whole_negated, and Clp_Internal::whole_negated.

Referenced by Clp_Next(), and Clp_Shift().

00783 {
00784   Clp_Internal *cli = clp->internal;
00785   save->argv = cli->argv;
00786   save->argc = cli->argc;
00787   memcpy(save->option_chars, cli->option_chars, 3);
00788   save->text = cli->text;
00789   save->is_short = cli->is_short;
00790   save->whole_negated = cli->whole_negated;
00791 }

Clp_ErrorHandler Clp_SetErrorHandler Clp_Parser   clp,
void(*    error_handler)(char *)
 

Definition at line 297 of file clp.c.

References Clp_ErrorHandler, Clp_Internal::error_handler, and Clp_Parser::internal.

00300 {
00301   Clp_Internal *cli = clp->internal;
00302   Clp_ErrorHandler old = cli->error_handler;
00303   cli->error_handler = error_handler;
00304   return old;
00305 }

int Clp_SetOptionChar Clp_Parser   clp,
int    c,
int    option_type
 

Definition at line 309 of file clp.c.

References Clp_Internal::both_short_and_long, c, Clp_Long, Clp_LongImplicit, Clp_LongNegated, Clp_Short, Clp_ShortNegated, i, Clp_Parser::internal, Clp_Internal::long_min_match, Clp_Internal::nopt, Clp_Internal::opt, and Clp_Internal::option_class.

Referenced by main().

00311                                     :
00312 
00313         0 == Clp_NotOption `character' isn't an option.
00314         Clp_Short       `character' introduces a list of short options.
00315         Clp_Long        `character' introduces a long option.
00316         Clp_ShortNegated `character' introduces a negated list of
00317                         short options.
00318         Clp_LongNegated `character' introduces a negated long option.
00319         Clp_LongImplicit `character' introduces a long option, and *is part
00320                         of the long option itself*.
00321 
00322         Some values are not allowed (Clp_Long | Clp_LongNegated isn't allowed,
00323         for instance). c=0 means ALL characters are that type. Returns 0 on
00324         failure (you gave an illegal option_type), 1 on success. */
00325 {
00326   int i;
00327   Clp_Internal *cli = clp->internal;
00328   
00329   if (option_type < 0 || option_type >= 2*Clp_LongImplicit
00330       || ((option_type & Clp_Short) && (option_type & Clp_ShortNegated))
00331       || ((option_type & Clp_Long) && (option_type & Clp_LongNegated))
00332       || ((option_type & Clp_LongImplicit) && (option_type & (Clp_Short | Clp_ShortNegated | Clp_Long | Clp_LongNegated))))
00333     return 0;
00334   
00335   if (c == 0)
00336     for (i = 1; i < 256; i++)
00337       cli->option_class[i] = option_type;
00338   else
00339     cli->option_class[c] = option_type;
00340 
00341   /* If an option character can introduce either short or long options, then
00342      we need to fix up the long_min_match values. We may have set the
00343      long_min_match for option `--abcde' to 1, if no other option starts with
00344      `a'. But if `-' can introduce either a short option or a long option, AND
00345      a short option `-a' exists, then the long_min_match for `--abcde' must be
00346      set to 2! */
00347   if (!cli->both_short_and_long) {
00348     int either_short = option_type & (Clp_Short | Clp_ShortNegated);
00349     int either_long = option_type & (Clp_Long | Clp_LongNegated);
00350     if (either_short && either_long) {
00351       unsigned char have_short[257];
00352       for (i = 0; i < 256; i++)
00353         have_short[i] = 0;
00354       for (i = 0; i < cli->nopt; i++)
00355         have_short[cli->opt[i].short_name] = 1;
00356       for (i = 0; i < cli->nopt; i++)
00357         if (cli->opt[i].long_name && cli->long_min_match[i].pos == 1) {
00358           /* if `--Cxxxx's short name is `-C', keep long_min_match == 1 */
00359           unsigned char first = (unsigned char)cli->opt[i].long_name[0];
00360           if (have_short[first] && first != cli->opt[i].short_name)
00361             cli->long_min_match[i].pos++;
00362         }
00363       cli->both_short_and_long = 1;
00364     }
00365   }
00366   
00367   return 1;
00368 }

int Clp_SetOptionProcessing Clp_Parser   clp,
int    option_processing
 

Definition at line 284 of file clp.c.

References Clp_Parser::internal, and Clp_Internal::option_processing.

Referenced by Clp_Next().

00288 {
00289   Clp_Internal *cli = clp->internal;
00290   int old = cli->option_processing;
00291   cli->option_processing = option_processing;
00292   return old;
00293 }

char* Clp_Shift Clp_Parser   clp,
int    allow_dashes
 

Parse the argument *

Definition at line 1178 of file clp.c.

References Clp_Parser::arg, Clp_RestoreParser(), Clp_SaveParser(), Clp_Parser::have_arg, and next_argument().

Referenced by handle_extension(), and parse_two_colors().

01181 {
01182   Clp_ParserState clpsave;
01183   Clp_SaveParser(clp, &clpsave);
01184   next_argument(clp, allow_dashes ? 2 : 1);
01185   if (!clp->have_arg)
01186     Clp_RestoreParser(clp, &clpsave);
01187   return clp->arg;
01188 }

Clp_BuildString* Clp_VaOptionError Clp_Parser   clp,
Clp_BuildString   bs,
const char *    fmt,
va_list    val
[static]
 

Definition at line 1262 of file clp.c.

References append_build_string(), c, Clp_Internal::current_option, Clp_Internal::current_short, ENSURE_BUILD_STRING, Clp_Parser::internal, Clp_Option::long_name, Clp_Internal::negated_by_no, new_build_string(), Clp_Internal::option_chars, Clp_BuildString::pos, Clp_Internal::program_name, and Clp_Option::short_name.

Referenced by ambiguity_error(), and Clp_OptionError().

01264                                                                           :
01265         
01266         s       Print a string from the argument list.
01267         c       Print an int from the argument list as a character.
01268         d       Print an int from the argument list.
01269         O       Print the name of the current option;
01270                 take nothing from the argument list.
01271                 
01272         No field specifications or flags are allowed. Always returns 0. */
01273 {
01274   Clp_Internal *cli = clp->internal;
01275   const char *percent;
01276   
01277   if (!bs) bs = new_build_string();
01278   if (!bs) return 0;
01279   append_build_string(bs, cli->program_name, -1);
01280   append_build_string(bs, ": ", 2);
01281   
01282   for (percent = strchr(fmt, '%'); percent; percent = strchr(fmt, '%')) {
01283     append_build_string(bs, fmt, percent - fmt);
01284     switch (*++percent) {
01285       
01286      case 's': {
01287        char *s = va_arg(val, char *);
01288        if (s) append_build_string(bs, s, -1);
01289        else append_build_string(bs, "(null)", 6);
01290        break;
01291      }
01292      
01293      case 'c': {
01294        int c = va_arg(val, int);
01295        if (ENSURE_BUILD_STRING(bs, 4)) {
01296          if (c >= 32 && c <= 126)
01297            *bs->pos++ = c;
01298          else if (c < 32) {
01299            *bs->pos++ = '^';
01300            *bs->pos++ = c + 64;
01301          } else {
01302            sprintf(bs->pos, "\\%03o", c);
01303            bs->pos += 4;
01304          }
01305        }
01306        break;
01307      }
01308      
01309      case 'd': {
01310        int d = va_arg(val, int);
01311        if (ENSURE_BUILD_STRING(bs, 32)) {
01312          sprintf(bs->pos, "%d", d);
01313          bs->pos = strchr(bs->pos, 0);
01314        }
01315        break;
01316      }
01317      
01318      case 'O': {
01319        Clp_Option *opt = cli->current_option;
01320        if (!opt)
01321          append_build_string(bs, "(no current option!)", -1);
01322        else if (cli->current_short) {
01323          append_build_string(bs, cli->option_chars, -1);
01324          if (ENSURE_BUILD_STRING(bs, 1))
01325            *bs->pos++ = opt->short_name;
01326        } else if (cli->negated_by_no) {
01327          append_build_string(bs, cli->option_chars, -1);
01328          append_build_string(bs, "no-", 3);
01329          append_build_string(bs, opt->long_name, -1);
01330        } else {
01331          append_build_string(bs, cli->option_chars, -1);
01332          append_build_string(bs, opt->long_name, -1);
01333        }
01334        break;
01335      }
01336      
01337      case '%':
01338       if (ENSURE_BUILD_STRING(bs, 1))
01339         *bs->pos++ = '%';
01340       break;
01341       
01342      default:
01343       if (ENSURE_BUILD_STRING(bs, 2)) {
01344         *bs->pos++ = '%';
01345         *bs->pos++ = *percent;
01346       }
01347       break;
01348       
01349     }
01350     fmt = ++percent;
01351   }
01352   
01353   append_build_string(bs, fmt, -1);
01354   append_build_string(bs, "\n", 1);
01355   
01356   return bs;
01357 }

void do_error Clp_Parser   clp,
Clp_BuildString   bs
[static]
 

Definition at line 1360 of file clp.c.

References Clp_BuildString::bad, Clp_Internal::error_handler, Clp_Parser::internal, Clp_BuildString::pos, and Clp_BuildString::text.

Referenced by ambiguity_error(), and Clp_OptionError().

01361 {
01362   char *text;
01363   if (bs && !bs->bad) {
01364     *bs->pos = 0;
01365     text = bs->text;
01366   } else
01367     text = "out of memory\n";
01368   
01369   if (clp->internal->error_handler != 0)
01370     (*clp->internal->error_handler)(text);
01371   else
01372     fputs(text, stderr);
01373 }

Clp_Option* find_long Clp_Parser   clp,
char *    arg
[static]
 

Definition at line 971 of file clp.c.

References Clp_Internal::ambiguous, Clp_Internal::ambiguous_values, Clp_Parser::arg, arg, argcmp(), find_prefix_opt(), Clp_Parser::have_arg, i, Clp_Parser::internal, Clp_Internal::long_min_match, MAX_AMBIGUOUS_VALUES, Clp_Parser::negated, Clp_Internal::nopt, Clp_Internal::opt, and Clp_LongMinMatch::pos.

Referenced by Clp_Next().

00976 {
00977   Clp_Internal *cli = clp->internal;
00978   int value, len;
00979   Clp_Option *opt = cli->opt;
00980   int first_negative_ambiguous;
00981   
00982   /* Look for a normal option. */
00983   value = find_prefix_opt
00984     (arg, cli->nopt, opt, cli->long_min_match,
00985      &cli->ambiguous, cli->ambiguous_values, clp->negated);
00986   if (value >= 0)
00987     goto worked;
00988   
00989   /* If we can't find it, look for a negated option. */
00990   /* I know this is silly, but it makes me happy to accept
00991      --no-no-option as a double negative synonym for --option. :) */
00992   first_negative_ambiguous = cli->ambiguous;
00993   while (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-') {
00994     arg += 3;
00995     clp->negated = !clp->negated;
00996     value = find_prefix_opt
00997       (arg, cli->nopt, opt, cli->long_min_match,
00998        &cli->ambiguous, cli->ambiguous_values, clp->negated);
00999     if (value >= 0)
01000       goto worked;
01001   }
01002   
01003   /* No valid option was found; return 0. Mark the ambiguous values found
01004      through `--no' by making them negative. */
01005   {
01006     int i, max = cli->ambiguous;
01007     if (max > MAX_AMBIGUOUS_VALUES) max = MAX_AMBIGUOUS_VALUES;
01008     for (i = first_negative_ambiguous; i < max; i++)
01009       cli->ambiguous_values[i] = -cli->ambiguous_values[i] - 1;
01010     return 0;
01011   }
01012   
01013  worked:
01014   len = argcmp(opt[value].long_name, arg, cli->long_min_match[value].pos);
01015   if (arg[len] == '=') {
01016     clp->have_arg = 1;
01017     clp->arg = arg + len + 1;
01018   }
01019   return &opt[value];
01020 }

int find_prefix_opt const char *    arg,
int    nopt,
Clp_Option   opt,
Clp_LongMinMatch   lmmvec,
int *    ambiguous,
int *    ambiguous_values,
int    negated
[static]
 

Definition at line 435 of file clp.c.

References arg, argcmp(), Clp_Negate, Clp_OnlyNegated, i, MAX_AMBIGUOUS_VALUES, and TEST.

Referenced by find_long(), and parse_string_list().

00442 {
00443   int i;
00444   for (i = 0; i < nopt; i++) {
00445     int len, lmm;
00446     if (!opt[i].long_name
00447         || (negated && !TEST(&opt[i], Clp_Negate))
00448         || (!negated && TEST(&opt[i], Clp_OnlyNegated)))
00449       continue;
00450     
00451     lmm = (negated ? lmmvec[i].neg : lmmvec[i].pos);
00452     len = argcmp(opt[i].long_name, arg, lmm);
00453     if (len > 0)
00454       return i;
00455     else if (len < 0) {
00456       if (*ambiguous < MAX_AMBIGUOUS_VALUES)
00457         ambiguous_values[*ambiguous] = i;
00458       (*ambiguous)++;
00459     }
00460   }
00461   return -1;
00462 }

Clp_Option* find_short Clp_Parser   clp,
int    short_name
[static]
 

Definition at line 1024 of file clp.c.

References Clp_Negate, Clp_OnlyNegated, i, Clp_Parser::internal, Clp_Parser::negated, Clp_Internal::nopt, Clp_Internal::opt, and TEST.

Referenced by Clp_Next().

01026 {
01027   Clp_Internal *cli = clp->internal;
01028   Clp_Option *opt = cli->opt;
01029   int i;
01030   
01031   for (i = 0; i < cli->nopt; i++)
01032     if (opt[i].short_name == short_name
01033         && (clp->negated ? TEST(&opt[i], Clp_Negate)
01034             : !TEST(&opt[i], Clp_OnlyNegated)))
01035       return &opt[i];
01036   
01037   return 0;
01038 }

int finish_string_list Clp_Parser   clp,
int    type_id,
int    flags,
Clp_Option   items,
int    nitems,
int    itemscap
 

Definition at line 633 of file clp.c.

References Clp_StringList::allow_int, calculate_long_min_match(), Clp_AddType(), Clp_AllowNumbers, flags, free, i, Clp_StringList::items, Clp_StringList::long_min_match, Clp_Option::long_name, malloc, MAX_AMBIGUOUS_VALUES, Clp_StringList::nitems, Clp_StringList::nitems_invalid_report, and parse_string_list().

Referenced by Clp_AddStringListType(), and Clp_AddStringListTypeVec().

00635 {
00636   int i;
00637   Clp_StringList *clsl = (Clp_StringList *)malloc(sizeof(Clp_StringList));
00638   Clp_LongMinMatch *lmm = (Clp_LongMinMatch *)malloc(sizeof(Clp_LongMinMatch) * nitems);
00639   if (!clsl || !lmm) goto error;
00640   
00641   clsl->items = items;
00642   clsl->long_min_match = lmm;
00643   clsl->nitems = nitems;
00644   clsl->allow_int = (flags & Clp_AllowNumbers) != 0;
00645   
00646   if (nitems < MAX_AMBIGUOUS_VALUES && nitems < itemscap && clsl->allow_int) {
00647     items[nitems].long_name = "any integer";
00648     clsl->nitems_invalid_report = nitems + 1;
00649   } else if (nitems > MAX_AMBIGUOUS_VALUES + 1)
00650     clsl->nitems_invalid_report = MAX_AMBIGUOUS_VALUES + 1;
00651   else
00652     clsl->nitems_invalid_report = nitems;
00653   
00654   for (i = 0; i < nitems; i++)
00655     lmm[i].pos = calculate_long_min_match(nitems, items, i, 0, 0);
00656   
00657   if (Clp_AddType(clp, type_id, 0, parse_string_list, clsl))
00658     return 1;
00659 
00660  error:
00661   if (clsl) free(clsl);
00662   if (lmm) free(lmm);
00663   return 0;
00664 }

void free_build_string Clp_BuildString   bs [static]
 

Definition at line 1220 of file clp.c.

References free, and Clp_BuildString::text.

Referenced by ambiguity_error(), and Clp_OptionError().

01221 {
01222   if (bs) free(bs->text);
01223   free(bs);
01224 }

int grow_build_string Clp_BuildString   bs,
int    want
[static]
 

Definition at line 1227 of file clp.c.

References Clp_BuildString::bad, Clp_BuildString::capacity, Clp_BuildString::pos, realloc, and Clp_BuildString::text.

01228 {
01229   char *new_text;
01230   int ipos = bs->pos - bs->text;
01231   int new_capacity = bs->capacity;
01232   while (want >= new_capacity)
01233     new_capacity *= 2;
01234   new_text = (char *)realloc(bs->text, new_capacity);
01235   if (!new_text) {
01236     bs->bad = 1;
01237     return 0;
01238   } else {
01239     bs->text = new_text;
01240     bs->pos = bs->text + ipos;
01241     bs->capacity = new_capacity;
01242     return 1;
01243   }
01244 }

int min_different_chars char *    s,
char *    t
[static]
 

Definition at line 376 of file clp.c.

Referenced by calculate_long_min_match().

00380 {
00381   char *sfirst = s;
00382   while (*s && *t && *s == *t)
00383     s++, t++;
00384   if (!*s)
00385     return s - sfirst;
00386   else
00387     return s - sfirst + 1;
00388 }

Clp_BuildString* new_build_string void    [static]
 

Definition at line 1203 of file clp.c.

References Clp_BuildString::bad, Clp_BuildString::capacity, free, malloc, Clp_BuildString::pos, and Clp_BuildString::text.

Referenced by Clp_VaOptionError().

01204 {
01205   Clp_BuildString *bs = (Clp_BuildString *)malloc(sizeof(Clp_BuildString));
01206   if (!bs) goto bad;
01207   bs->text = (char *)malloc(256);
01208   if (!bs->text) goto bad;
01209   bs->pos = bs->text;
01210   bs->capacity = 256;
01211   bs->bad = 0;
01212   return bs;
01213   
01214  bad:
01215   if (bs) free(bs);
01216   return 0;
01217 }

int next_argument Clp_Parser   clp,
int    want_argument
[static]
 

Definition at line 827 of file clp.c.

References Clp_Parser::arg, Clp_Internal::argc, Clp_Internal::argv, Clp_DoubledLong, Clp_Long, Clp_LongImplicit, Clp_LongNegated, Clp_NotOption, Clp_Short, Clp_ShortNegated, Clp_Internal::could_be_short, Clp_Parser::have_arg, Clp_Parser::internal, Clp_Internal::is_short, Clp_Internal::option_class, set_option_text(), Clp_Internal::text, and Clp_Internal::whole_negated.

Referenced by Clp_Next(), and Clp_Shift().

00834                           : Accept arguments that start with Clp_NotOption
00835                 or Clp_LongImplicit.
00836         want_argument == 2: Accept ALL arguments.
00837         
00838         Where is the option stored when this returns?
00839         Well, cli->argv[0] holds the whole of the next command line argument.
00840         cli->option_chars holds a string: what characters began the option?
00841         It is generally "-" or "--".
00842         cli->text holds the text of the option:
00843         for short options, cli->text[0] is the relevant character;
00844         for long options, cli->text holds the rest of the option. */
00845 {
00846   Clp_Internal *cli = clp->internal;
00847   char *text;
00848   int option_class;
00849 
00850   /* clear relevant flags */
00851   clp->have_arg = 0;
00852   clp->arg = 0;
00853   cli->could_be_short = 0;
00854   
00855   /* if we're in a string of short options, move up one char in the string */
00856   if (cli->is_short) {
00857     ++cli->text;
00858     if (cli->text[0] == 0)
00859       cli->is_short = 0;
00860     else if (want_argument > 0) {
00861       /* handle -O[=]argument case */
00862       clp->have_arg = 1;
00863       if (cli->text[0] == '=')
00864         clp->arg = cli->text + 1;
00865       else
00866         clp->arg = cli->text;
00867       cli->is_short = 0;
00868       return 0;
00869     }
00870   }
00871   
00872   /* if in short options, we're all set */
00873   if (cli->is_short)
00874     return 1;
00875   
00876   /** if not in short options, move to the next argument **/
00877   cli->whole_negated = 0;
00878   cli->text = 0;
00879   
00880   if (cli->argc <= 1)
00881     return 0;
00882   
00883   cli->argc--;
00884   cli->argv++;
00885   text = cli->argv[0];
00886   
00887   if (want_argument > 1)
00888     goto not_option;
00889   
00890   option_class = cli->option_class[ (unsigned char)text[0] ];
00891   if (text[0] == '-' && text[1] == '-')
00892     option_class = Clp_DoubledLong;
00893   
00894   /* If this character could introduce either a short or a long option,
00895      try a long option first, but remember that short's a possibility for
00896      later. */
00897   if ((option_class & (Clp_Short | Clp_ShortNegated))
00898       && (option_class & (Clp_Long | Clp_LongNegated))) {
00899     option_class &= ~(Clp_Short | Clp_ShortNegated);
00900     if (text[1] != 0) cli->could_be_short = 1;
00901   }
00902   
00903   switch (option_class) {
00904     
00905    case Clp_Short:
00906     cli->is_short = 1;
00907     goto check_singleton;
00908     
00909    case Clp_ShortNegated:
00910     cli->is_short = 1;
00911     cli->whole_negated = 1;
00912     goto check_singleton;
00913     
00914    case Clp_Long:
00915     goto check_singleton;
00916     
00917    case Clp_LongNegated:
00918     cli->whole_negated = 1;
00919     goto check_singleton;
00920     
00921    check_singleton:
00922     /* For options introduced with one character, option-char,
00923        `[option-char]' alone is NOT an option. */
00924     if (text[1] == 0)
00925       goto not_option;
00926     set_option_text(cli, text, 1);
00927     break;
00928     
00929    case Clp_LongImplicit:
00930     /* LongImplict: option_chars == "" (since all chars are part of the
00931        option); restore head -> text of option */
00932     if (want_argument > 0)
00933       goto not_option;
00934     set_option_text(cli, text, 0);
00935     break;
00936     
00937    case Clp_DoubledLong:
00938     set_option_text(cli, text, 2);
00939     break;
00940     
00941    not_option: 
00942    case Clp_NotOption:
00943     cli->is_short = 0;
00944     clp->have_arg = 1;
00945     clp->arg = text;
00946     return 0;
00947     
00948    default:
00949     assert(0 && "misconfiguration");
00950     
00951   }
00952   
00953   return 1;
00954 }

int parse_bool Clp_Parser  ,
const char *   ,
int   ,
void *   
[static]
 

Definition at line 562 of file clp.c.

References arg, argcmp(), Clp_OptionError(), i, and Clp_Parser::val.

Referenced by Clp_NewParser().

00563 {
00564   int i;
00565   char lcarg[6];
00566   if (strlen(arg) > 5 || strchr(arg, '=') != 0)
00567     goto error;
00568   
00569   for (i = 0; arg[i] != 0; i++)
00570     lcarg[i] = tolower(arg[i]);
00571   lcarg[i] = 0;
00572   
00573   if (argcmp("yes", lcarg, 1) > 0
00574       || argcmp("true", lcarg, 1) > 0
00575       || argcmp("1", lcarg, 1) > 0) {
00576     clp->val.i = 1;
00577     return 1;
00578   } else if (argcmp("no", lcarg, 1) > 0
00579              || argcmp("false", lcarg, 1) > 0
00580              || argcmp("1", lcarg, 1) > 0) {
00581     clp->val.i = 0;
00582     return 1;
00583   }
00584   
00585  error:
00586   if (complain)
00587     Clp_OptionError(clp, "`%O' expects a true-or-false value, not `%s'", arg);
00588   return 0;
00589 }

int parse_double Clp_Parser  ,
const char *   ,
int   ,
void *   
[static]
 

Definition at line 549 of file clp.c.

References arg, Clp_OptionError(), strtod(), and Clp_Parser::val.

Referenced by Clp_NewParser().

00550 {
00551   char *val;
00552   clp->val.d = strtod(arg, &val);
00553   if (*arg != 0 && *val == 0)
00554     return 1;
00555   else if (complain)
00556     return Clp_OptionError(clp, "`%O' expects a real number, not `%s'", arg);
00557   else
00558     return 0;
00559 }

int parse_int Clp_Parser  ,
const char *   ,
int   ,
void *   
[static]
 

Definition at line 518 of file clp.c.

References arg, base, Clp_OptionError(), and Clp_Parser::val.

Referenced by Clp_NewParser(), and parse_string_list().

00519 {
00520   char *val;
00521   int base = 10;
00522   if (arg[0] == '0' && (arg[1] == 'x' || arg[1] == 'X')) {
00523     base = 16;
00524     arg += 2;
00525   }
00526   
00527   if (thunk != 0) {             /* unsigned */
00528 #if HAVE_STRTOUL
00529     clp->val.u = strtoul(arg, &val, base);
00530 #else
00531     /* don't bother trying to do it right */
00532     clp->val.u = strtol(arg, &val, base);
00533 #endif
00534   } else
00535     clp->val.i = strtol(arg, &val, base);
00536   if (*arg != 0 && *val == 0)
00537     return 1;
00538   else if (complain) {
00539     const char *message = thunk != 0
00540       ? "`%O' expects a nonnegative integer, not `%s'"
00541       : "`%O' expects an integer, not `%s'";
00542     if (base == 16) arg -= 2;
00543     return Clp_OptionError(clp, message, arg);
00544   } else
00545     return 0;
00546 }

int parse_string Clp_Parser  ,
const char *   ,
int   ,
void *   
[static]
 

Definition at line 511 of file clp.c.

References arg, and Clp_Parser::val.

Referenced by Clp_NewParser().

00512 {
00513   clp->val.s = (char *)arg;
00514   return 1;
00515 }

int parse_string_list Clp_Parser  ,
const char *   ,
int   ,
void *   
[static]
 

Definition at line 597 of file clp.c.

References Clp_StringList::allow_int, ambiguity_error(), arg, find_prefix_opt(), Clp_StringList::items, Clp_StringList::long_min_match, MAX_AMBIGUOUS_VALUES, Clp_StringList::nitems, Clp_StringList::nitems_invalid_report, Clp_Option::option_id, parse_int(), and Clp_Parser::val.

Referenced by Clp_DeleteParser(), and finish_string_list().

00598 {
00599   Clp_StringList *sl = (Clp_StringList *)thunk;
00600   int index, ambiguous = 0;
00601   int ambiguous_values[MAX_AMBIGUOUS_VALUES + 1];
00602   
00603   /* actually look for a string value */
00604   index = find_prefix_opt
00605     (arg, sl->nitems, sl->items, sl->long_min_match,
00606      &ambiguous, ambiguous_values, 0);
00607   if (index >= 0) {
00608     clp->val.i = sl->items[index].option_id;
00609     return 1;
00610   }
00611   
00612   if (sl->allow_int) {
00613     if (parse_int(clp, arg, 0, 0))
00614       return 1;
00615   }
00616   
00617   if (complain) {
00618     char *complaint = (ambiguous ? "an ambiguous" : "not a valid");
00619     if (!ambiguous) {
00620       ambiguous = sl->nitems_invalid_report;
00621       for (index = 0; index < ambiguous; index++)
00622         ambiguous_values[index] = index;
00623     }
00624     return ambiguity_error
00625       (clp, ambiguous, ambiguous_values, sl->items, "",
00626        "`%s' is %s argument to `%O'", arg, complaint);
00627   } else
00628     return 0;
00629 }

void set_option_text Clp_Internal   cli,
char *    text,
int    n_option_chars
[static]
 

Definition at line 813 of file clp.c.

References Clp_Internal::option_chars, and Clp_Internal::text.

Referenced by next_argument(), and switch_to_short_argument().

00814 {
00815   char *option_chars = cli->option_chars;
00816   assert(n_option_chars < 3);
00817   
00818   while (n_option_chars-- > 0)
00819     *option_chars++ = *text++;
00820   *option_chars = 0;
00821   
00822   cli->text = text;
00823 }

void switch_to_short_argument Clp_Parser   clp [static]
 

if not in short options, move to the next argument *

Definition at line 958 of file clp.c.

References Clp_Internal::argv, Clp_ShortNegated, Clp_Internal::could_be_short, Clp_Parser::internal, Clp_Internal::is_short, Clp_Internal::option_class, set_option_text(), and Clp_Internal::whole_negated.

Referenced by Clp_Next().

00959 {
00960   Clp_Internal *cli = clp->internal;
00961   const char *text = cli->argv[0];
00962   int option_class = cli->option_class[ (unsigned char)text[0] ];
00963   cli->is_short = 1;
00964   cli->whole_negated = (option_class & Clp_ShortNegated ? 1 : 0);
00965   set_option_text(cli, cli->argv[0], 1);
00966   assert(cli->could_be_short);
00967 }
 

Powered by Plone

This site conforms to the following standards: