2 * Eddie Kohler, Yandong Mao, Robert Morris
3 * Copyright (c) 2012-2013 President and Fellows of Harvard College
4 * Copyright (c) 2012-2013 Massachusetts Institute of Technology
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, subject to the conditions
9 * listed in the Masstree LICENSE file. These conditions include: you must
10 * preserve this copyright notice, and you cannot mention the copyright
11 * holders in advertising related to the Software without their permission.
12 * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
13 * notice is a summary of the Masstree LICENSE file; the license in that file
16 /* clp.c - Complete source code for CLP.
17 * This file is part of CLP, the command line parser package.
19 * Copyright (c) 1997-2014 Eddie Kohler, ekohler@gmail.com
21 * CLP is free software. It is distributed under the GNU General Public
22 * License, Version 2, or, alternatively and at your discretion, under the
23 * more permissive (BSD-like) Click LICENSE file as described below.
25 * Permission is hereby granted, free of charge, to any person obtaining a
26 * copy of this software and associated documentation files (the
27 * "Software"), to deal in the Software without restriction, subject to the
28 * conditions listed in the Click LICENSE file, which is available in full at
29 * http://github.com/kohler/click/blob/master/LICENSE. The conditions
30 * include: you must preserve this copyright notice, and you cannot mention
31 * the copyright holders in advertising related to the Software without
32 * their permission. The Software is provided WITHOUT ANY WARRANTY, EXPRESS
33 * OR IMPLIED. This notice is a summary of the Click LICENSE file; the
34 * license in that file is binding. */
47 # include <sys/types.h>
50 /* By default, assume we have inttypes.h, strtoul, and uintptr_t. */
51 #if !defined(HAVE_STRTOUL) && !defined(HAVE_CONFIG_H)
52 # define HAVE_STRTOUL 1
54 #if defined(HAVE_INTTYPES_H) || !defined(HAVE_CONFIG_H)
55 # include <inttypes.h>
57 #if !defined(HAVE_UINTPTR_T) && defined(HAVE_CONFIG_H)
58 typedef unsigned long uintptr_t;
67 * @brief Functions for parsing command line options.
69 * The CLP functions are used to parse command line arugments into options.
70 * It automatically handles value parsing, error messages, long options with
71 * minimum prefix matching, short options, and negated options.
73 * The CLP model works like this.
76 * <li>The user declares an array of Clp_Option structures that define the
77 * options their program accepts.</li>
78 * <li>The user creates a Clp_Parser object using Clp_NewParser(), passing in
79 * the command line arguments to parse and the Clp_Option structures.</li>
80 * <li>A loop repeatedly calls Clp_Next() to parse the arguments.</li>
83 * Unlike many command line parsing libraries, CLP steps through all arguments
84 * one at a time, rather than slurping up all options at once. This makes it
85 * meaningful to give an option more than once.
90 * #define ANIMAL_OPT 1
91 * #define VEGETABLE_OPT 2
92 * #define MINERALS_OPT 3
95 * static const Clp_Option options[] = {
96 * { "animal", 'a', ANIMAL_OPT, Clp_ValString, 0 },
97 * { "vegetable", 'v', VEGETABLE_OPT, Clp_ValString, Clp_Negate | Clp_Optional },
98 * { "minerals", 'm', MINERALS_OPT, Clp_ValInt, 0 },
99 * { "usage", 0, USAGE_OPT, 0, 0 }
102 * int main(int argc, char *argv[]) {
103 * Clp_Parser *clp = Clp_NewParser(argc, argv,
104 * sizeof(options) / sizeof(options[0]), options);
106 * while ((opt = Clp_Next(clp)) != Clp_Done)
109 * fprintf(stderr, "animal is %s\n", clp->val.s);
111 * case VEGETABLE_OPT:
113 * fprintf(stderr, "no vegetables!\n");
114 * else if (clp->have_val)
115 * fprintf(stderr, "vegetable is %s\n", clp->val.s);
117 * fprintf(stderr, "vegetables OK\n");
120 * fprintf(stderr, "%d minerals\n", clp->val.i);
123 * fprintf(stderr, "Usage: 20q [--animal=ANIMAL] [--vegetable[=VEGETABLE]] [--minerals=N]\n");
125 * case Clp_NotOption:
126 * fprintf(stderr, "non-option %s\n", clp->vstr);
133 * Here are a couple of executions.
136 * % ./20q --animal=cat
138 * % ./20q --animal=cat -a dog -afish --animal bird --an=snake
144 * % ./20q --no-vegetables
153 * '-m' expects an integer, not 'foo'
158 /* Option types for Clp_SetOptionChar */
159 #define Clp_DoubledLong (Clp_LongImplicit * 2)
161 #define Clp_InitialValType 8
162 #define MAX_AMBIGUOUS_VALUES 4
166 Clp_ValParseFunc func;
174 unsigned imandatory : 1;
175 unsigned ioptional : 1;
178 unsigned iprefmatch : 1;
179 unsigned lmmpos_short : 1;
180 unsigned lmmneg_short : 1;
181 unsigned char ilongoff;
187 #define Clp_OptionCharsSize 5
193 #define Clp_OclassSize 10
195 typedef struct Clp_Internal {
196 const Clp_Option *opt;
197 Clp_InternOption *iopt;
199 unsigned opt_generation;
201 Clp_ValType *valtype;
204 const char * const *argv;
207 Clp_Oclass oclass[Clp_OclassSize];
213 char option_chars[Clp_OptionCharsSize];
216 const char *program_name;
217 void (*error_handler)(Clp_Parser *, const char *);
219 int option_processing;
222 unsigned char is_short;
223 unsigned char whole_negated; /* true if negated by an option character */
224 unsigned char could_be_short;
225 unsigned char current_short;
226 unsigned char negated_by_no;
229 int ambiguous_values[MAX_AMBIGUOUS_VALUES];
233 struct Clp_ParserState {
234 const char * const *argv;
237 char option_chars[Clp_OptionCharsSize];
240 int option_processing;
242 unsigned opt_generation;
244 unsigned char is_short;
245 unsigned char whole_negated;
246 unsigned char current_short;
247 unsigned char negated_by_no;
251 typedef struct Clp_StringList {
253 Clp_InternOption *iopt;
256 unsigned char allow_int;
257 unsigned char val_long;
258 int nitems_invalid_report;
262 static const Clp_Option clp_option_sentinel[] = {
263 {"", 0, Clp_NotOption, 0, 0},
264 {"", 0, Clp_Done, 0, 0},
265 {"", 0, Clp_BadOption, 0, 0},
266 {"", 0, Clp_Error, 0, 0}
270 static int parse_string(Clp_Parser *, const char *, int, void *);
271 static int parse_int(Clp_Parser *, const char *, int, void *);
272 static int parse_bool(Clp_Parser *, const char *, int, void *);
273 static int parse_double(Clp_Parser *, const char *, int, void *);
274 static int parse_string_list(Clp_Parser *, const char *, int, void *);
276 static int ambiguity_error(Clp_Parser *, int, int *, const Clp_Option *,
277 const Clp_InternOption *, const char *, const char *,
285 #define U_REPLACEMENT 0xFFFD
288 encode_utf8(char *s, int n, int c)
290 if (c < 0 || c >= 0x110000 || (c >= 0xD800 && c <= 0xDFFF))
292 if (c <= 0x7F && n >= 1)
294 else if (c <= 0x7FF && n >= 2) {
295 *s++ = 0xC0 | (c >> 6);
297 } else if (c <= 0xFFFF && n >= 3) {
298 *s++ = 0xE0 | (c >> 12);
301 *s++ = 0xF0 | (c >> 18);
302 *s++ = 0x80 | ((c >> 12) & 0x3F);
304 *s++ = 0x80 | ((c >> 6) & 0x3F);
306 *s++ = 0x80 | (c & 0x3F);
312 decode_utf8(const char *s, const char **cp)
315 if ((unsigned char) *s <= 0x7F) /* 1 byte: 0x000000-0x00007F */
317 else if ((unsigned char) *s <= 0xC1) /* bad/overlong encoding */
319 else if ((unsigned char) *s <= 0xDF) { /* 2 bytes: 0x000080-0x0007FF */
320 if ((s[1] & 0xC0) != 0x80) /* bad encoding */
322 c = (*s++ & 0x1F) << 6;
324 } else if ((unsigned char) *s <= 0xEF) { /* 3 bytes: 0x000800-0x00FFFF */
325 if ((s[1] & 0xC0) != 0x80 /* bad encoding */
326 || (s[2] & 0xC0) != 0x80 /* bad encoding */
327 || ((unsigned char) *s == 0xE0 /* overlong encoding */
328 && (s[1] & 0xE0) == 0x80)
329 || ((unsigned char) *s == 0xED /* encoded surrogate */
330 && (s[1] & 0xE0) == 0xA0))
332 c = (*s++ & 0x0F) << 12;
334 } else if ((unsigned char) *s <= 0xF4) { /* 4 bytes: 0x010000-0x10FFFF */
335 if ((s[1] & 0xC0) != 0x80 /* bad encoding */
336 || (s[2] & 0xC0) != 0x80 /* bad encoding */
337 || (s[3] & 0xC0) != 0x80 /* bad encoding */
338 || ((unsigned char) *s == 0xF0 /* overlong encoding */
339 && (s[1] & 0xF0) == 0x80)
340 || ((unsigned char) *s == 0xF4 /* encoded value > 0x10FFFF */
341 && (unsigned char) s[1] >= 0x90))
343 c = (*s++ & 0x07) << 18;
344 c += (*s++ & 0x3F) << 12;
346 c += (*s++ & 0x3F) << 6;
352 for (s++; (*s & 0xC0) == 0x80; s++)
361 utf8_charlen(const char *s)
364 (void) decode_utf8(s, &sout);
369 clp_utf8_charlen(const Clp_Internal *cli, const char *s)
371 return (cli->utf8 ? utf8_charlen(s) : 1);
376 * Clp_NewParser, etc.
380 min_different_chars(const char *s, const char *t)
381 /* Returns the minimum number of bytes required to distinguish
383 If s is shorter than t, returns strlen(s). */
385 const char *sfirst = s;
386 while (*s && *t && *s == *t)
391 return s - sfirst + 1;
395 long_as_short(const Clp_Internal *cli, const Clp_Option *o,
396 Clp_InternOption *io, int failure)
398 if ((cli->long1pos || cli->long1neg) && io->ilong) {
399 const char *name = o->long_name + io->ilongoff;
401 int c = decode_utf8(name, &name);
402 if (!*name && c && c != U_REPLACEMENT)
404 } else if (name[0] && !name[1])
405 return (unsigned char) name[0];
411 compare_options(Clp_Parser *clp, const Clp_Option *o1, Clp_InternOption *io1,
412 const Clp_Option *o2, Clp_InternOption *io2)
414 Clp_Internal *cli = clp->internal;
417 /* ignore meaningless combinations */
418 if ((!io1->ishort && !io1->ilong) || (!io2->ishort && !io2->ilong)
419 || !((io1->ipos && io2->ipos) || (io1->ineg && io2->ineg))
420 || o1->option_id == o2->option_id)
423 /* look for duplication of short options */
424 short1 = (io1->ishort ? o1->short_name : -1);
425 shortx1 = long_as_short(cli, o1, io1, -2);
426 if (short1 >= 0 || shortx1 >= 0) {
427 int short2 = (io2->ishort ? o2->short_name : -3);
428 int shortx2 = long_as_short(cli, o2, io2, -4);
429 if (short1 == short2)
430 Clp_OptionError(clp, "CLP internal error: more than 1 option has short name %<%c%>", short1);
431 else if ((short1 == shortx2 || shortx1 == short2 || shortx1 == shortx2)
432 && ((io1->ipos && io2->ipos && cli->long1pos)
433 || (io1->ineg && io2->ineg && cli->long1neg)))
434 Clp_OptionError(clp, "CLP internal error: 1-char long name conflicts with short name %<%c%>", (short1 == shortx2 ? shortx2 : shortx1));
437 /* analyze longest minimum match */
439 const char *name1 = o1->long_name + io1->ilongoff;
441 /* long name's first character matches short name */
442 if (io2->ishort && !io1->iprefmatch) {
443 int name1char = (cli->utf8 ? decode_utf8(name1, 0) : (unsigned char) *name1);
444 if (name1char == o2->short_name) {
445 if (io1->ipos && io2->ipos)
446 io1->lmmpos_short = 1;
447 if (io1->ineg && io2->ineg)
448 io1->lmmneg_short = 1;
452 /* match long name to long name */
454 const char *name2 = o2->long_name + io2->ilongoff;
455 if (strcmp(name1, name2) == 0)
456 Clp_OptionError(clp, "CLP internal error: duplicate long name %<%s%>", name1);
457 if (io1->ipos && io2->ipos && !strncmp(name1, name2, io1->lmmpos)
458 && (!io1->iprefmatch || strncmp(name1, name2, strlen(name1))))
459 io1->lmmpos = min_different_chars(name1, name2);
460 if (io1->ineg && io2->ineg && !strncmp(name1, name2, io1->lmmneg)
461 && (!io1->iprefmatch || strncmp(name1, name2, strlen(name1))))
462 io1->lmmneg = min_different_chars(name1, name2);
468 calculate_lmm(Clp_Parser *clp, const Clp_Option *opt, Clp_InternOption *iopt, int nopt)
471 for (i = 0; i < nopt; ++i) {
472 iopt[i].lmmpos = iopt[i].lmmneg = 1;
473 iopt[i].lmmpos_short = iopt[i].lmmneg_short = 0;
474 for (j = 0; j < nopt; ++j)
475 compare_options(clp, &opt[i], &iopt[i], &opt[j], &iopt[j]);
479 /** @param argc number of arguments
480 * @param argv argument array
481 * @param nopt number of option definitions
482 * @param opt option definition array
485 * The new Clp_Parser that will parse the arguments in @a argv according to
486 * the option definitions in @a opt.
488 * The Clp_Parser is created with the following characteristics:
491 * <li>The "-" character introduces short options (<tt>Clp_SetOptionChar(clp,
492 * '-', Clp_Short)</tt>).</li>
493 * <li>Clp_ProgramName is set from the first argument in @a argv, if any. The
494 * first argument returned by Clp_Next() will be the second argument in @a
495 * argv. Note that this behavior differs from Clp_SetArguments.</li>
496 * <li>UTF-8 support is on iff the <tt>LANG</tt> environment variable contains
497 * one of the substrings "UTF-8", "UTF8", or "utf8". Override this with
498 * Clp_SetUTF8().</li>
499 * <li>The Clp_ValString, Clp_ValStringNotOption, Clp_ValInt, Clp_ValUnsigned,
500 * Clp_ValLong, Clp_ValUnsignedLong, Clp_ValBool, and Clp_ValDouble types are
502 * <li>Errors are reported to standard error.</li>
505 * You may also create a Clp_Parser with no arguments or options
506 * (<tt>Clp_NewParser(0, 0, 0, 0)</tt>) and set the arguments and options
509 * Returns NULL if there isn't enough memory to construct the parser.
511 * @note The CLP library will not modify the contents of @a argv or @a opt.
512 * The calling program must not modify @a opt. It may modify @a argv in
516 Clp_NewParser(int argc, const char * const *argv, int nopt, const Clp_Option *opt)
518 Clp_Parser *clp = (Clp_Parser *)malloc(sizeof(Clp_Parser));
519 Clp_Internal *cli = (Clp_Internal *)malloc(sizeof(Clp_Internal));
520 Clp_InternOption *iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nopt);
522 cli->valtype = (Clp_ValType *)malloc(sizeof(Clp_ValType) * Clp_InitialValType);
523 if (!clp || !cli || !iopt || !cli->valtype)
526 clp->option = &clp_option_sentinel[-Clp_Done];
536 cli->opt_generation = 0;
537 cli->error_handler = 0;
539 /* Assign program name (now so we can call Clp_OptionError) */
541 const char *slash = strrchr(argv[0], '/');
542 cli->program_name = slash ? slash + 1 : argv[0];
544 cli->program_name = 0;
546 /* Assign arguments, skipping program name */
547 Clp_SetArguments(clp, argc - 1, argv + 1);
549 /* Initialize UTF-8 status and option classes */
551 char *s = getenv("LANG");
552 cli->utf8 = (s && (strstr(s, "UTF-8") != 0 || strstr(s, "UTF8") != 0
553 || strstr(s, "utf8") != 0));
555 cli->oclass[0].c = '-';
556 cli->oclass[0].type = Clp_Short;
558 cli->long1pos = cli->long1neg = 0;
560 /* Add default type parsers */
562 Clp_AddType(clp, Clp_ValString, 0, parse_string, 0);
563 Clp_AddType(clp, Clp_ValStringNotOption, Clp_DisallowOptions, parse_string, 0);
564 Clp_AddType(clp, Clp_ValInt, 0, parse_int, (void*) (uintptr_t) 0);
565 Clp_AddType(clp, Clp_ValUnsigned, 0, parse_int, (void*) (uintptr_t) 1);
566 Clp_AddType(clp, Clp_ValLong, 0, parse_int, (void*) (uintptr_t) 2);
567 Clp_AddType(clp, Clp_ValUnsignedLong, 0, parse_int, (void*) (uintptr_t) 3);
568 Clp_AddType(clp, Clp_ValBool, 0, parse_bool, 0);
569 Clp_AddType(clp, Clp_ValDouble, 0, parse_double, 0);
572 Clp_SetOptions(clp, nopt, opt);
577 if (cli && cli->valtype)
588 /** @param clp the parser
590 * All memory associated with @a clp is freed. */
592 Clp_DeleteParser(Clp_Parser *clp)
601 /* get rid of any string list types */
602 for (i = 0; i < cli->nvaltype; i++)
603 if (cli->valtype[i].func == parse_string_list) {
604 Clp_StringList *clsl = (Clp_StringList *)cli->valtype[i].user_data;
617 /** @param clp the parser
618 * @param errh error handler function
619 * @return previous error handler function
621 * The error handler function is called when CLP encounters an error while
622 * parsing the command line. It is called with the arguments "<tt>(*errh)(@a
623 * clp, s)</tt>", where <tt>s</tt> is a description of the error terminated by
624 * a newline. The <tt>s</tt> descriptions produced by CLP itself are prefixed
625 * by the program name, if any. */
627 Clp_SetErrorHandler(Clp_Parser *clp, void (*errh)(Clp_Parser *, const char *))
629 Clp_Internal *cli = clp->internal;
630 Clp_ErrorHandler old = cli->error_handler;
631 cli->error_handler = errh;
635 /** @param clp the parser
636 * @param utf8 does the parser support UTF-8?
637 * @return previous UTF-8 mode
639 * In UTF-8 mode, all input strings (arguments and long names for options) are
640 * assumed to be encoded via UTF-8, and all character names
641 * (Clp_SetOptionChar() and short names for options) may cover the whole
642 * Unicode range. Out of UTF-8 mode, all input strings are treated as binary,
643 * and all character names must be unsigned char values.
645 * Furthermore, error messages in UTF-8 mode may contain Unicode quote
648 Clp_SetUTF8(Clp_Parser *clp, int utf8)
650 Clp_Internal *cli = clp->internal;
651 int old_utf8 = cli->utf8;
653 calculate_lmm(clp, cli->opt, cli->iopt, cli->nopt);
657 /** @param clp the parser
659 * @return option character treatment
661 * Returns an integer specifying how CLP treats arguments that begin
662 * with character @a c. See Clp_SetOptionChar for possibilities.
665 Clp_OptionChar(Clp_Parser *clp, int c)
667 Clp_Internal *cli = clp->internal;
669 if (cli->noclass > 0 && cli->oclass[0].c == 0)
670 oclass = cli->oclass[0].type;
671 for (i = 0; i < cli->noclass; ++i)
672 if (cli->oclass[i].c == c)
673 oclass = cli->oclass[i].type;
677 /** @param clp the parser
679 * @param type option character treatment
680 * @return previous option character treatment, or -1 on error
682 * @a type specifies how CLP treats arguments that begin with character @a c.
686 * <dt>Clp_NotOption (or 0)</dt>
687 * <dd>The argument cannot be an option.</dd>
689 * <dd>The argument is a long option.</dd>
691 * <dd>The argument is a set of short options.</dd>
692 * <dt>Clp_Short|Clp_Long</dt>
693 * <dd>The argument is either a long option or, if no matching long option is
694 * found, a set of short options.</dd>
695 * <dt>Clp_LongNegated</dt>
696 * <dd>The argument is a negated long option. For example, after
697 * Clp_SetOptionChar(@a clp, '^', Clp_LongNegated), the argument "^foo" is
698 * equivalent to "--no-foo".</dd>
699 * <dt>Clp_ShortNegated</dt>
700 * <dd>The argument is a set of negated short options.</dd>
701 * <dt>Clp_ShortNegated|Clp_LongNegated</dt>
702 * <dd>The argument is either a negated long option or, if no matching long
703 * option is found, a set of negated short options.</dd>
704 * <dt>Clp_LongImplicit</dt>
705 * <dd>The argument may be a long option, where the character @a c is actually
706 * part of the long option name. For example, after Clp_SetOptionChar(@a clp,
707 * 'f', Clp_LongImplicit), the argument "foo" may be equivalent to
711 * In UTF-8 mode, @a c may be any Unicode character. Otherwise, @a c must be
712 * an unsigned char value. The special character 0 assigns @a type to @em
715 * It is an error if @a c is out of range, @a type is illegal, or there are
716 * too many character definitions stored in @a clp already. The function
717 * returns -1 on error.
719 * A double hyphen "--" always introduces a long option. This behavior cannot
720 * currently be changed with Clp_SetOptionChar().
723 Clp_SetOptionChar(Clp_Parser *clp, int c, int type)
725 int i, long1pos, long1neg;
726 int old = Clp_OptionChar(clp, c);
727 Clp_Internal *cli = clp->internal;
729 if (type != Clp_NotOption && type != Clp_Short && type != Clp_Long
730 && type != Clp_ShortNegated && type != Clp_LongNegated
731 && type != Clp_LongImplicit && type != (Clp_Short | Clp_Long)
732 && type != (Clp_ShortNegated | Clp_LongNegated))
734 if (c < 0 || c >= (cli->utf8 ? 0x110000 : 256))
739 for (i = 0; i < cli->noclass; ++i)
740 if (cli->oclass[i].c == c)
742 if (i == Clp_OclassSize)
745 cli->oclass[i].c = c;
746 cli->oclass[i].type = type;
747 if (cli->noclass == i)
748 cli->noclass = i + 1;
750 long1pos = long1neg = 0;
751 for (i = 0; i < cli->noclass; ++i) {
752 if ((cli->oclass[i].type & Clp_Short)
753 && (cli->oclass[i].type & Clp_Long))
755 if ((cli->oclass[i].type & Clp_ShortNegated)
756 && (cli->oclass[i].type & Clp_LongNegated))
760 if (long1pos != cli->long1pos || long1neg != cli->long1neg) {
761 /* Must recheck option set */
762 cli->long1pos = long1pos;
763 cli->long1neg = long1neg;
764 calculate_lmm(clp, cli->opt, cli->iopt, cli->nopt);
770 /** @param clp the parser
771 * @param nopt number of option definitions
772 * @param opt option definition array
773 * @return 0 on success, -1 on failure
775 * Installs the option definitions in @a opt. Future option parsing will
776 * use @a opt to search for options.
778 * Also checks @a opt's option definitions for validity. "CLP internal
779 * errors" are reported via Clp_OptionError() if:
782 * <li>An option has a negative ID.</li>
783 * <li>Two different short options have the same name.</li>
784 * <li>Two different long options have the same name.</li>
785 * <li>A short and a long option are ambiguous, in that some option character
786 * might introduce either a short or a long option (e.g., Clp_SetOptionChar(@a
787 * clp, '-', Clp_Long|Clp_Short)), and a short name equals a long name.</li>
790 * If necessary memory cannot be allocated, this function returns -1 without
791 * modifying the parser.
793 * @note The CLP library will not modify the contents of @a argv or @a opt.
794 * The calling program must not modify @a opt either until another call to
795 * Clp_SetOptions() or the parser is destroyed.
798 Clp_SetOptions(Clp_Parser *clp, int nopt, const Clp_Option *opt)
800 Clp_Internal *cli = clp->internal;
801 Clp_InternOption *iopt;
803 static unsigned opt_generation = 0;
805 if (nopt > cli->nopt) {
806 iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nopt);
815 cli->opt_generation = ++opt_generation;
817 cli->current_option = -1;
819 /* Massage the options to make them usable */
820 for (i = 0; i < nopt; ++i) {
821 memset(&iopt[i], 0, sizeof(iopt[i]));
823 /* Ignore negative option_ids, which are internal to CLP */
824 if (opt[i].option_id < 0) {
825 Clp_OptionError(clp, "CLP internal error: option %d has negative option_id", i);
826 iopt[i].ilong = iopt[i].ishort = iopt[i].ipos = iopt[i].ineg = 0;
830 /* Set flags based on input flags */
831 iopt[i].ilong = (opt[i].long_name != 0 && opt[i].long_name[0] != 0);
832 iopt[i].ishort = (opt[i].short_name > 0
833 && opt[i].short_name < (cli->utf8 ? 0x110000 : 256));
835 iopt[i].ineg = (opt[i].flags & Clp_Negate) != 0;
836 iopt[i].imandatory = (opt[i].flags & Clp_Mandatory) != 0;
837 iopt[i].ioptional = (opt[i].flags & Clp_Optional) != 0;
838 iopt[i].iprefmatch = (opt[i].flags & Clp_PreferredMatch) != 0;
839 iopt[i].ilongoff = 0;
841 /* Enforce invariants */
842 if (opt[i].val_type <= 0)
843 iopt[i].imandatory = iopt[i].ioptional = 0;
844 if (opt[i].val_type > 0 && !iopt[i].ioptional)
845 iopt[i].imandatory = 1;
847 /* Options that start with 'no-' should be changed to OnlyNegated */
848 if (iopt[i].ilong && strncmp(opt[i].long_name, "no-", 3) == 0) {
851 iopt[i].ilongoff = 3;
852 if (strncmp(opt[i].long_name + 3, "no-", 3) == 0)
853 Clp_OptionError(clp, "CLP internal error: option %d begins with \"no-no-\"", i);
854 } else if (opt[i].flags & Clp_OnlyNegated) {
860 /* Check option set */
861 calculate_lmm(clp, opt, iopt, nopt);
866 /** @param clp the parser
867 * @param argc number of arguments
868 * @param argv argument array
870 * Installs the arguments in @a argv for parsing. Future option parsing will
873 * Unlike Clp_NewParser(), this function does not treat @a argv[0] specially.
874 * The first subsequent call to Clp_Next() will analyze @a argv[0].
876 * This function also sets option processing to on, as by
877 * Clp_SetOptionProcessing(@a clp, 1).
879 * @note The CLP library will not modify the contents of @a argv. The calling
880 * program should not generally modify the element of @a argv that CLP is
881 * currently analyzing.
884 Clp_SetArguments(Clp_Parser *clp, int argc, const char * const *argv)
886 Clp_Internal *cli = clp->internal;
888 cli->argc = argc + 1;
889 cli->argv = argv - 1;
892 cli->whole_negated = 0;
893 cli->option_processing = 1;
894 cli->current_option = -1;
898 /** @param clp the parser
899 * @param on whether to search for options
900 * @return previous option processing setting
902 * When option processing is off, every call to Clp_Next() returns
903 * Clp_NotOption. By default the option <tt>"--"</tt> turns off option
904 * processing and is otherwise ignored.
907 Clp_SetOptionProcessing(Clp_Parser *clp, int on)
909 Clp_Internal *cli = clp->internal;
910 int old = cli->option_processing;
911 cli->option_processing = on;
917 * functions for Clp_Option lists
920 /* the ever-glorious argcmp */
923 argcmp(const char *ref, const char *arg, int min_match, int fewer_dashes)
924 /* Returns 0 if ref and arg don't match.
925 Returns -1 if ref and arg match, but fewer than min_match characters.
926 Returns len if ref and arg match min_match or more characters;
927 len is the number of characters that matched in arg.
928 Allows arg to contain fewer dashes than ref iff fewer_dashes != 0.
931 argcmp("x", "y", 1, 0) --> 0 / just plain wrong
932 argcmp("a", "ax", 1, 0) --> 0 / ...even though min_match == 1
933 and the 1st chars match
934 argcmp("box", "bo", 3, 0) --> -1 / ambiguous
935 argcmp("cat", "c=3", 1, 0) --> 1 / handles = arguments
938 const char *refstart = ref;
939 const char *argstart = arg;
940 assert(min_match > 0);
943 while (*ref && *arg && *arg != '=' && *ref == *arg)
946 /* Allow arg to contain fewer dashes than ref */
947 if (fewer_dashes && *ref == '-' && ref[1] && ref[1] == *arg) {
952 if (*arg && *arg != '=')
954 else if (ref - refstart < min_match)
957 return arg - argstart;
961 find_prefix_opt(Clp_Parser *clp, const char *arg,
962 int nopt, const Clp_Option *opt,
963 const Clp_InternOption *iopt,
964 int *ambiguous, int *ambiguous_values)
965 /* Looks for an unambiguous match of 'arg' against one of the long
966 options in 'opt'. Returns positive if it finds one; otherwise, returns
967 -1 and possibly changes 'ambiguous' and 'ambiguous_values' to keep
968 track of at most MAX_AMBIGUOUS_VALUES possibilities. */
970 int i, fewer_dashes = 0, first_ambiguous = *ambiguous;
971 int negated = clp && clp->negated;
972 int first_charlen = (clp ? clp_utf8_charlen(clp->internal, arg) : 1);
975 for (i = 0; i < nopt; i++) {
977 if (!iopt[i].ilong || (negated ? !iopt[i].ineg : !iopt[i].ipos))
980 lmm = (negated ? iopt[i].lmmneg : iopt[i].lmmpos);
981 if (clp && clp->internal->could_be_short
982 && (negated ? iopt[i].lmmneg_short : iopt[i].lmmpos_short))
983 lmm = (first_charlen >= lmm ? first_charlen + 1 : lmm);
984 len = argcmp(opt[i].long_name + iopt[i].ilongoff, arg, lmm, fewer_dashes);
988 if (*ambiguous < MAX_AMBIGUOUS_VALUES)
989 ambiguous_values[*ambiguous] = i;
994 /* If there were no partial matches, try again with fewer_dashes true */
995 if (*ambiguous == first_ambiguous && !fewer_dashes) {
1009 val_type_binsearch(Clp_Internal *cli, int val_type)
1011 unsigned l = 0, r = cli->nvaltype;
1013 unsigned m = l + (r - l) / 2;
1014 if (cli->valtype[m].val_type == val_type)
1016 else if (cli->valtype[m].val_type < val_type)
1024 /** @param clp the parser
1025 * @param val_type value type ID
1026 * @param flags value type flags
1027 * @param parser parser function
1028 * @param user_data user data for @a parser function
1029 * @return 0 on success, -1 on failure
1031 * Defines argument type @a val_type in parser @a clp. The parsing function
1032 * @a parser will be passed argument values for type @a val_type. It should
1033 * parse the argument into values (usually in @a clp->val, but sometimes
1034 * elsewhere), report errors if necessary, and return whether the parse was
1037 * Any prior argument parser match @a val_type is removed. @a val_type must
1038 * be greater than zero.
1040 * @a flags specifies additional parsing flags. At the moment the only
1041 * relevant flag is Clp_DisallowOptions, which means that separated values
1042 * must not look like options. For example, assume argument
1043 * <tt>--a</tt>/<tt>-a</tt> has mandatory value type Clp_ValStringNotOption
1044 * (which has Clp_DisallowOptions). Then:
1047 * <li><tt>--a=--b</tt> will parse with value <tt>--b</tt>.</li>
1048 * <li><tt>-a--b</tt> will parse with value <tt>--b</tt>.</li>
1049 * <li><tt>--a --b</tt> will not parse, since the mandatory value looks like
1051 * <li><tt>-a --b</tt> will not parse, since the mandatory value looks like
1056 Clp_AddType(Clp_Parser *clp, int val_type, int flags,
1057 Clp_ValParseFunc parser, void *user_data)
1059 Clp_Internal *cli = clp->internal;
1062 if (val_type <= 0 || !parser)
1065 vtpos = val_type_binsearch(cli, val_type);
1067 if (vtpos == cli->nvaltype || cli->valtype[vtpos].val_type != val_type) {
1068 if (cli->nvaltype != 0 && (cli->nvaltype % Clp_InitialValType) == 0) {
1069 Clp_ValType *new_valtype =
1070 (Clp_ValType *) realloc(cli->valtype, sizeof(Clp_ValType) * (cli->nvaltype + Clp_InitialValType));
1073 cli->valtype = new_valtype;
1075 memmove(&cli->valtype[vtpos + 1], &cli->valtype[vtpos],
1076 sizeof(Clp_ValType) * (cli->nvaltype - vtpos));
1078 cli->valtype[vtpos].func = 0;
1081 if (cli->valtype[vtpos].func == parse_string_list) {
1082 Clp_StringList *clsl = (Clp_StringList *) cli->valtype[vtpos].user_data;
1088 cli->valtype[vtpos].val_type = val_type;
1089 cli->valtype[vtpos].func = parser;
1090 cli->valtype[vtpos].flags = flags;
1091 cli->valtype[vtpos].user_data = user_data;
1097 * Default argument parsers
1101 parse_string(Clp_Parser *clp, const char *arg, int complain, void *user_data)
1103 (void)complain, (void)user_data;
1109 parse_int(Clp_Parser* clp, const char* arg, int complain, void* user_data)
1112 uintptr_t type = (uintptr_t) user_data;
1113 if (*arg == 0 || isspace((unsigned char) *arg)
1114 || ((type & 1) && *arg == '-'))
1116 else if (type & 1) { /* unsigned */
1118 clp->val.ul = strtoul(arg, (char **) &val, 0);
1120 /* don't bother really trying to do it right */
1124 clp->val.l = strtol(arg, (char **) &val, 0);
1127 clp->val.l = strtol(arg, (char **) &val, 0);
1129 clp->val.u = (unsigned) clp->val.ul;
1130 if (*arg != 0 && *val == 0)
1134 const char *message = type & 1
1135 ? "%<%O%> expects a nonnegative integer, not %<%s%>"
1136 : "%<%O%> expects an integer, not %<%s%>";
1137 Clp_OptionError(clp, message, arg);
1144 parse_double(Clp_Parser *clp, const char *arg, int complain, void *user_data)
1148 if (*arg == 0 || isspace((unsigned char) *arg))
1151 clp->val.d = strtod(arg, (char **) &val);
1152 if (*arg != 0 && *val == 0)
1156 Clp_OptionError(clp, "%<%O%> expects a real number, not %<%s%>", arg);
1162 parse_bool(Clp_Parser *clp, const char *arg, int complain, void *user_data)
1167 if (strlen(arg) > 5 || strchr(arg, '=') != 0)
1170 for (i = 0; arg[i] != 0; i++)
1171 lcarg[i] = tolower((unsigned char) arg[i]);
1174 if (argcmp("yes", lcarg, 1, 0) > 0
1175 || argcmp("true", lcarg, 1, 0) > 0
1176 || argcmp("1", lcarg, 1, 0) > 0) {
1179 } else if (argcmp("no", lcarg, 1, 0) > 0
1180 || argcmp("false", lcarg, 1, 0) > 0
1181 || argcmp("1", lcarg, 1, 0) > 0) {
1188 Clp_OptionError(clp, "%<%O%> expects a true-or-false value, not %<%s%>", arg);
1194 * Clp_AddStringListType
1198 parse_string_list(Clp_Parser *clp, const char *arg, int complain, void *user_data)
1200 Clp_StringList *sl = (Clp_StringList *)user_data;
1201 int idx, ambiguous = 0;
1202 int ambiguous_values[MAX_AMBIGUOUS_VALUES + 1];
1204 /* actually look for a string value */
1205 idx = find_prefix_opt
1206 (0, arg, sl->nitems, sl->items, sl->iopt,
1207 &ambiguous, ambiguous_values);
1209 clp->val.i = sl->items[idx].option_id;
1211 clp->val.l = clp->val.i;
1215 if (sl->allow_int) {
1216 if (parse_int(clp, arg, 0, (void*) (uintptr_t) (sl->val_long ? 2 : 0)))
1221 const char *complaint = (ambiguous ? "ambiguous" : "invalid");
1223 ambiguous = sl->nitems_invalid_report;
1224 for (idx = 0; idx < ambiguous; idx++)
1225 ambiguous_values[idx] = idx;
1227 return ambiguity_error
1228 (clp, ambiguous, ambiguous_values, sl->items, sl->iopt,
1229 "", "option %<%V%> is %s", complaint);
1236 finish_string_list(Clp_Parser *clp, int val_type, int flags,
1237 Clp_Option *items, int nitems, int itemscap)
1240 Clp_StringList *clsl = (Clp_StringList *)malloc(sizeof(Clp_StringList));
1241 Clp_InternOption *iopt = (Clp_InternOption *)malloc(sizeof(Clp_InternOption) * nitems);
1245 clsl->items = items;
1247 clsl->nitems = nitems;
1248 clsl->allow_int = (flags & Clp_AllowNumbers) != 0;
1249 clsl->val_long = (flags & Clp_StringListLong) != 0;
1251 if (nitems < MAX_AMBIGUOUS_VALUES && nitems < itemscap && clsl->allow_int) {
1252 items[nitems].long_name = "any integer";
1253 clsl->nitems_invalid_report = nitems + 1;
1254 } else if (nitems > MAX_AMBIGUOUS_VALUES + 1)
1255 clsl->nitems_invalid_report = MAX_AMBIGUOUS_VALUES + 1;
1257 clsl->nitems_invalid_report = nitems;
1259 for (i = 0; i < nitems; i++) {
1260 iopt[i].ilong = iopt[i].ipos = 1;
1261 iopt[i].ishort = iopt[i].ineg = iopt[i].ilongoff = iopt[i].iprefmatch = 0;
1263 calculate_lmm(clp, items, iopt, nitems);
1265 if (Clp_AddType(clp, val_type, 0, parse_string_list, clsl) >= 0)
1276 /** @param clp the parser
1277 * @param val_type value type ID
1278 * @param flags string list flags
1279 * @return 0 on success, -1 on failure
1281 * Defines argument type @a val_type in parser @a clp. The parsing function
1282 * sets @a clp->val.i to an integer. The value string is matched against
1283 * strings provided in the ellipsis arguments. For example, the
1284 * Clp_AddStringListType() call below has the same effect as the
1285 * Clp_AddStringListTypeVec() call:
1289 * Clp_AddStringListType(clp, 100, Clp_AllowNumbers, "cat", 1,
1290 * "cattle", 2, "dog", 3, (const char *) NULL);
1292 * const char * const strs[] = { "cat", "cattle", "dog" };
1293 * const int vals[] = { 1, 2, 3 };
1294 * Clp_AddStringListTypeVec(clp, 100, Clp_AllowNumbers, 3, strs, vals);
1297 * @note The CLP library will not modify any of the passed-in strings. The
1298 * calling program must not modify or free them either until the parser is
1302 Clp_AddStringListType(Clp_Parser *clp, int val_type, int flags, ...)
1306 Clp_Option *items = (Clp_Option *)malloc(sizeof(Clp_Option) * itemscap);
1309 va_start(val, flags);
1314 /* slurp up the arguments */
1317 char *name = va_arg(val, char *);
1320 if (flags & Clp_StringListLong) {
1321 long lvalue = va_arg(val, long);
1322 value = (int) lvalue;
1323 assert(value == lvalue);
1325 value = va_arg(val, int);
1327 if (nitems >= itemscap) {
1328 Clp_Option *new_items;
1330 new_items = (Clp_Option *)realloc(items, sizeof(Clp_Option) * itemscap);
1336 items[nitems].long_name = name;
1337 items[nitems].option_id = value;
1338 items[nitems].flags = 0;
1343 if (finish_string_list(clp, val_type, flags, items, nitems, itemscap) >= 0)
1353 /** @param clp the parser
1354 * @param val_type value type ID
1355 * @param flags string list flags
1356 * @param nstrs number of strings in list
1357 * @param strs array of strings
1358 * @param vals array of values
1359 * @return 0 on success, -1 on failure
1361 * Defines argument type @a val_type in parser @a clp. The parsing function
1362 * sets @a clp->val.i to an integer. The value string is matched against the
1363 * @a strs. If there's a unique match, the corresponding entry from @a vals
1364 * is returned. Unique prefix matches also work. Finally, if @a flags
1365 * contains the Clp_AllowNumbers flag, then integers are also accepted.
1369 * const char * const strs[] = { "cat", "cattle", "dog" };
1370 * const int vals[] = { 1, 2, 3 };
1371 * Clp_AddStringListTypeVec(clp, 100, Clp_AllowNumbers, 3, strs, vals);
1374 * Say that option <tt>--animal</tt> takes value type 100. Then:
1377 * <li><tt>--animal=cat</tt> will succeed and set @a clp->val.i = 1.</li>
1378 * <li><tt>--animal=cattle</tt> will succeed and set @a clp->val.i = 2.</li>
1379 * <li><tt>--animal=dog</tt> will succeed and set @a clp->val.i = 3.</li>
1380 * <li><tt>--animal=d</tt> will succeed and set @a clp->val.i = 3.</li>
1381 * <li><tt>--animal=c</tt> will fail, since <tt>c</tt> is ambiguous.</li>
1382 * <li><tt>--animal=4</tt> will succeed and set @a clp->val.i = 4.</li>
1385 * @note The CLP library will not modify the contents of @a strs or @a vals.
1386 * The calling program can modify the @a strs array, but the actual strings
1387 * (for instance, @a strs[0] and @a strs[1]) must not be modified or freed
1388 * until the parser is destroyed.
1391 Clp_AddStringListTypeVec(Clp_Parser *clp, int val_type, int flags,
1392 int nstrs, const char * const *strs,
1394 /* An alternate way to make a string list type. See Clp_AddStringListType
1395 for the basics; this coalesces the strings and values into two arrays,
1396 rather than spreading them out into a variable argument list. */
1399 int itemscap = (nstrs < 5 ? 5 : nstrs);
1400 Clp_Option *items = (Clp_Option *)malloc(sizeof(Clp_Option) * itemscap);
1404 /* copy over items */
1405 for (i = 0; i < nstrs; i++) {
1406 items[i].long_name = strs[i];
1407 items[i].option_id = vals[i];
1411 if (finish_string_list(clp, val_type, flags, items, nstrs, itemscap) >= 0)
1421 * Returning information
1425 Clp_ProgramName(Clp_Parser *clp)
1427 return clp->internal->program_name;
1430 /** @param clp the parser
1431 * @param name new program name
1432 * @return previous program name
1434 * The calling program should not modify or free @a name until @a clp itself
1437 Clp_SetProgramName(Clp_Parser *clp, const char *name)
1439 const char *old = clp->internal->program_name;
1440 clp->internal->program_name = name;
1449 /** @return the parser state
1451 * A Clp_ParserState object can store a parsing state of a Clp_Parser object.
1452 * This state specifies exactly how far the Clp_Parser has gotten in parsing
1453 * an argument list. The Clp_SaveParser() and Clp_RestoreParser() functions
1454 * can be used to save this state and then restore it later, allowing a
1455 * Clp_Parser to switch among argument lists.
1457 * The initial state is empty, in that after Clp_RestoreParser(clp, state),
1458 * Clp_Next(clp) would return Clp_Done.
1460 * Parser states can be saved and restored among different parser objects.
1462 * @sa Clp_DeleteParserState, Clp_SaveParser, Clp_RestoreParser
1465 Clp_NewParserState(void)
1467 Clp_ParserState *state = (Clp_ParserState *)malloc(sizeof(Clp_ParserState));
1471 state->option_chars[0] = 0;
1473 state->option_processing = 0;
1474 state->opt_generation = 0;
1475 state->current_option = -1;
1476 state->is_short = 0;
1477 state->whole_negated = 0;
1478 state->current_short = 0;
1479 state->negated_by_no = 0;
1484 /** @param state parser state
1486 * The memory associated with @a state is freed.
1489 Clp_DeleteParserState(Clp_ParserState *state)
1494 /** @param clp the parser
1495 * @param state parser state
1496 * @sa Clp_NewParserState, Clp_RestoreParser
1499 Clp_SaveParser(const Clp_Parser *clp, Clp_ParserState *state)
1501 Clp_Internal *cli = clp->internal;
1502 state->argv = cli->argv;
1503 state->argc = cli->argc;
1504 memcpy(state->option_chars, cli->option_chars, Clp_OptionCharsSize);
1505 state->xtext = cli->xtext;
1507 state->option_processing = cli->option_processing;
1508 state->opt_generation = cli->opt_generation;
1509 state->current_option = cli->current_option;
1510 state->is_short = cli->is_short;
1511 state->whole_negated = cli->whole_negated;
1512 state->current_short = cli->current_short;
1513 state->negated_by_no = cli->negated_by_no;
1517 /** @param clp the parser
1518 * @param state parser state
1520 * The parser state in @a state is restored into @a clp. The next call to
1521 * Clp_Next() will return the same result as it would have at the time @a
1522 * state was saved (probably by Clp_SaveParser(@a clp, @a state)).
1524 * A parser state contains information about arguments (argc and argv; see
1525 * Clp_SetArguments()) and option processing (Clp_SetOptionProcessing()), but
1526 * not about options (Clp_SetOptions()). Changes to options and value types
1527 * are preserved across Clp_RestoreParser().
1529 * @sa Clp_NewParserState, Clp_SaveParser
1532 Clp_RestoreParser(Clp_Parser *clp, const Clp_ParserState *state)
1534 Clp_Internal *cli = clp->internal;
1535 cli->argv = state->argv;
1536 cli->argc = state->argc;
1537 memcpy(cli->option_chars, state->option_chars, Clp_OptionCharsSize);
1538 cli->xtext = state->xtext;
1539 cli->option_processing = state->option_processing;
1540 cli->is_short = state->is_short;
1541 cli->whole_negated = state->whole_negated;
1542 cli->current_short = state->current_short;
1543 cli->negated_by_no = state->negated_by_no;
1544 if (cli->opt_generation == state->opt_generation)
1545 cli->current_option = state->current_option;
1547 cli->current_option = -1;
1552 * Clp_Next and its helpers
1556 set_option_text(Clp_Internal *cli, const char *text, int n_option_chars)
1558 assert(n_option_chars < Clp_OptionCharsSize);
1559 memcpy(cli->option_chars, text, n_option_chars);
1560 cli->option_chars[n_option_chars] = 0;
1561 cli->xtext = text + n_option_chars;
1565 get_oclass(Clp_Parser *clp, const char *text, int *ocharskip)
1568 if (clp->internal->utf8) {
1570 c = decode_utf8(text, &s);
1571 *ocharskip = s - text;
1573 c = (unsigned char) text[0];
1576 return Clp_OptionChar(clp, c);
1580 next_argument(Clp_Parser *clp, int want_argument)
1581 /* Moves clp to the next argument.
1582 Returns 1 if it finds another option.
1583 Returns 0 if there aren't any more arguments.
1584 Returns 0, sets clp->have_val = 1, and sets clp->vstr to the argument
1585 if the next argument isn't an option.
1586 If want_argument > 0, it'll look for an argument.
1587 want_argument == 1: Accept arguments that start with Clp_NotOption
1588 or Clp_LongImplicit.
1589 want_argument == 2: Accept ALL arguments.
1591 Where is the option stored when this returns?
1592 Well, cli->argv[0] holds the whole of the next command line argument.
1593 cli->option_chars holds a string: what characters began the option?
1594 It is generally "-" or "--".
1595 cli->text holds the text of the option:
1596 for short options, cli->text[0] is the relevant character;
1597 for long options, cli->text holds the rest of the option. */
1599 Clp_Internal *cli = clp->internal;
1601 int oclass, ocharskip;
1603 /* clear relevant flags */
1606 cli->could_be_short = 0;
1608 /* if we're in a string of short options, move up one char in the string */
1609 if (cli->is_short) {
1610 cli->xtext += clp_utf8_charlen(cli, cli->xtext);
1611 if (cli->xtext[0] == 0)
1613 else if (want_argument > 0) {
1614 /* handle -O[=]argument case */
1616 if (cli->xtext[0] == '=')
1617 clp->vstr = cli->xtext + 1;
1619 clp->vstr = cli->xtext;
1625 /* if in short options, we're all set */
1629 /** if not in short options, move to the next argument **/
1630 cli->whole_negated = 0;
1638 text = cli->argv[0];
1640 if (want_argument > 1)
1643 if (text[0] == '-' && text[1] == '-') {
1644 oclass = Clp_DoubledLong;
1647 oclass = get_oclass(clp, text, &ocharskip);
1649 /* If this character could introduce either a short or a long option,
1650 try a long option first, but remember that short's a possibility for
1652 if ((oclass & (Clp_Short | Clp_ShortNegated))
1653 && (oclass & (Clp_Long | Clp_LongNegated))) {
1654 oclass &= ~(Clp_Short | Clp_ShortNegated);
1655 if (text[ocharskip])
1656 cli->could_be_short = 1;
1663 goto check_singleton;
1665 case Clp_ShortNegated:
1667 cli->whole_negated = 1;
1668 goto check_singleton;
1671 goto check_singleton;
1673 case Clp_LongNegated:
1674 cli->whole_negated = 1;
1675 goto check_singleton;
1678 /* For options introduced with one character, option-char,
1679 '[option-char]' alone is NOT an option. */
1680 if (!text[ocharskip])
1682 set_option_text(cli, text, ocharskip);
1685 case Clp_LongImplicit:
1686 /* LongImplict: option_chars == "" (since all chars are part of the
1687 option); restore head -> text of option */
1688 if (want_argument > 0)
1690 set_option_text(cli, text, 0);
1693 case Clp_DoubledLong:
1694 set_option_text(cli, text, ocharskip);
1705 assert(0 /* CLP misconfiguration: bad option type */);
1714 switch_to_short_argument(Clp_Parser *clp)
1716 Clp_Internal *cli = clp->internal;
1717 const char *text = cli->argv[0];
1718 int ocharskip, oclass = get_oclass(clp, text, &ocharskip);
1719 assert(cli->could_be_short);
1721 cli->whole_negated = (oclass & Clp_ShortNegated ? 1 : 0);
1722 set_option_text(cli, cli->argv[0], ocharskip);
1727 find_long(Clp_Parser *clp, const char *arg)
1728 /* If arg corresponds to one of clp's options, finds that option &
1729 returns it. If any argument is given after an = sign in arg, sets
1730 clp->have_val = 1 and clp->vstr to that argument. Sets cli->ambiguous
1731 to 1 iff there was no match because the argument was ambiguous. */
1733 Clp_Internal *cli = clp->internal;
1734 int optno, len, lmm;
1735 const Clp_Option *opt = cli->opt;
1736 const Clp_InternOption *iopt;
1737 int first_negative_ambiguous;
1739 /* Look for a normal option. */
1740 optno = find_prefix_opt
1741 (clp, arg, cli->nopt, opt, cli->iopt,
1742 &cli->ambiguous, cli->ambiguous_values);
1746 /* If we can't find it, look for a negated option. */
1747 /* I know this is silly, but it makes me happy to accept
1748 --no-no-option as a double negative synonym for --option. :) */
1749 first_negative_ambiguous = cli->ambiguous;
1750 while (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-') {
1752 clp->negated = !clp->negated;
1753 optno = find_prefix_opt
1754 (clp, arg, cli->nopt, opt, cli->iopt,
1755 &cli->ambiguous, cli->ambiguous_values);
1760 /* No valid option was found; return 0. Mark the ambiguous values found
1761 through '--no' by making them negative. */
1763 int i, max = cli->ambiguous;
1764 if (max > MAX_AMBIGUOUS_VALUES) max = MAX_AMBIGUOUS_VALUES;
1765 for (i = first_negative_ambiguous; i < max; i++)
1766 cli->ambiguous_values[i] = -cli->ambiguous_values[i] - 1;
1771 iopt = &cli->iopt[optno];
1772 lmm = (clp->negated ? iopt->lmmneg : iopt->lmmpos);
1773 if (cli->could_be_short
1774 && (clp->negated ? iopt->lmmneg_short : iopt->lmmpos_short)) {
1775 int first_charlen = clp_utf8_charlen(cli, arg);
1776 lmm = (first_charlen >= lmm ? first_charlen + 1 : lmm);
1778 len = argcmp(opt[optno].long_name + iopt->ilongoff, arg, lmm, 1);
1780 if (arg[len] == '=') {
1782 clp->vstr = arg + len + 1;
1789 find_short(Clp_Parser *clp, const char *text)
1790 /* If short_name corresponds to one of clp's options, returns it. */
1792 Clp_Internal *cli = clp->internal;
1793 const Clp_Option *opt = cli->opt;
1794 const Clp_InternOption *iopt = cli->iopt;
1796 if (clp->internal->utf8)
1797 c = decode_utf8(text, 0);
1799 c = (unsigned char) *text;
1801 for (i = 0; i < cli->nopt; i++)
1802 if (iopt[i].ishort && opt[i].short_name == c
1803 && (!clp->negated || iopt[i].ineg)) {
1804 clp->negated = clp->negated || !iopt[i].ipos;
1812 /** @param clp the parser
1813 * @return option ID of next option
1815 * Parse the next argument from the argument list, store information about
1816 * that argument in the fields of @a clp, and return the option's ID.
1818 * If an argument was successfully parsed, that option's ID is returned.
1819 * Other possible return values are:
1823 * <dd>There are no more arguments.</dd>
1824 * <dt>Clp_NotOption</dt>
1825 * <dd>The next argument was not an option. The argument's text is @a
1826 * clp->vstr (and @a clp->val.s).</dd>
1827 * <dt>Clp_BadOption</dt>
1828 * <dd>The next argument was a bad option: either an option that wasn't
1829 * understood, or an option lacking a required value, or an option whose value
1830 * couldn't be parsed. The option has been skipped.</dd>
1831 * <dt>Clp_Error</dt>
1832 * <dd>There was an internal error. This should never occur unless a user
1833 * messes with, for example, a Clp_Option array.</dd>
1836 * The fields of @a clp are set as follows.
1839 * <dt><tt>negated</tt></dt>
1840 * <dd>1 if the option was negated, 0 if it wasn't.</dd>
1841 * <dt><tt>have_val</tt></dt>
1842 * <dd>1 if the option had a value, 0 if it didn't. Note that negated options
1843 * are not allowed to have values.</dd>
1844 * <dt><tt>vstr</tt></dt>
1845 * <dd>The value string, if any. NULL if there was no value.</dd>
1846 * <dt><tt>val</tt></dt>
1847 * <dd>An option's value type will parse the value string into this
1851 * The parsed argument is shifted off the argument list, so that sequential
1852 * calls to Clp_Next() step through the arugment list.
1855 Clp_Next(Clp_Parser *clp)
1857 Clp_Internal *cli = clp->internal;
1859 const Clp_Option *opt;
1860 Clp_ParserState clpsave;
1861 int vtpos, complain;
1864 cli->current_option = -1;
1867 /* Get the next argument or option */
1868 if (!next_argument(clp, cli->option_processing ? 0 : 2)) {
1869 clp->val.s = clp->vstr;
1870 optno = clp->have_val ? Clp_NotOption : Clp_Done;
1871 clp->option = &clp_option_sentinel[-optno];
1875 clp->negated = cli->whole_negated;
1877 optno = find_short(clp, cli->xtext);
1879 optno = find_long(clp, cli->xtext);
1881 /* If there's ambiguity between long & short options, and we couldn't
1882 find a long option, look for a short option */
1883 if (optno < 0 && cli->could_be_short) {
1884 switch_to_short_argument(clp);
1885 optno = find_short(clp, cli->xtext);
1888 /* If we didn't find an option... */
1889 if (optno < 0 || (clp->negated && !cli->iopt[optno].ineg)) {
1890 /* default processing for the "--" option: turn off option processing
1891 and return the next argument */
1892 if (strcmp(cli->argv[0], "--") == 0) {
1893 Clp_SetOptionProcessing(clp, 0);
1894 return Clp_Next(clp);
1897 /* otherwise, report some error or other */
1899 ambiguity_error(clp, cli->ambiguous, cli->ambiguous_values,
1900 cli->opt, cli->iopt, cli->option_chars,
1901 "option %<%s%s%> is ambiguous",
1902 cli->option_chars, cli->xtext);
1903 else if (cli->is_short && !cli->could_be_short)
1904 Clp_OptionError(clp, "unrecognized option %<%s%C%>",
1905 cli->option_chars, cli->xtext);
1907 Clp_OptionError(clp, "unrecognized option %<%s%s%>",
1908 cli->option_chars, cli->xtext);
1910 clp->option = &clp_option_sentinel[-Clp_BadOption];
1911 return Clp_BadOption;
1914 /* Set the current option */
1915 cli->current_option = optno;
1916 cli->current_short = cli->is_short;
1917 cli->negated_by_no = clp->negated && !cli->whole_negated;
1919 /* The no-argument (or should-have-no-argument) case */
1921 || (!cli->iopt[optno].imandatory && !cli->iopt[optno].ioptional)) {
1922 if (clp->have_val) {
1923 Clp_OptionError(clp, "%<%O%> can%,t take an argument");
1924 clp->option = &clp_option_sentinel[-Clp_BadOption];
1925 return Clp_BadOption;
1927 clp->option = &cli->opt[optno];
1928 return cli->opt[optno].option_id;
1932 /* Get an argument if we need one, or if it's optional */
1933 /* Sanity-check the argument type. */
1934 opt = &cli->opt[optno];
1935 if (opt->val_type <= 0) {
1936 clp->option = &clp_option_sentinel[-Clp_Error];
1939 vtpos = val_type_binsearch(cli, opt->val_type);
1940 if (vtpos == cli->nvaltype
1941 || cli->valtype[vtpos].val_type != opt->val_type) {
1942 clp->option = &clp_option_sentinel[-Clp_Error];
1946 /* complain == 1 only if the argument was explicitly given,
1947 or it is mandatory. */
1948 complain = (clp->have_val != 0) || cli->iopt[optno].imandatory;
1949 Clp_SaveParser(clp, &clpsave);
1951 if (cli->iopt[optno].imandatory && !clp->have_val) {
1952 /* Mandatory argument case */
1953 /* Allow arguments to options to start with a dash, but only if the
1954 argument type allows it by not setting Clp_DisallowOptions */
1955 int disallow = (cli->valtype[vtpos].flags & Clp_DisallowOptions) != 0;
1956 next_argument(clp, disallow ? 1 : 2);
1957 if (!clp->have_val) {
1958 int got_option = cli->xtext != 0;
1959 Clp_RestoreParser(clp, &clpsave);
1961 Clp_OptionError(clp, "%<%O%> requires a non-option argument");
1963 Clp_OptionError(clp, "%<%O%> requires an argument");
1964 clp->option = &clp_option_sentinel[-Clp_BadOption];
1965 return Clp_BadOption;
1968 } else if (cli->is_short && !clp->have_val
1969 && cli->xtext[clp_utf8_charlen(cli, cli->xtext)])
1970 /* The -[option]argument case:
1971 Assume that the rest of the current string is the argument. */
1972 next_argument(clp, 1);
1974 /* Parse the argument */
1976 if (clp->have_val) {
1977 Clp_ValType *atr = &cli->valtype[vtpos];
1978 if (atr->func(clp, clp->vstr, complain, atr->user_data) <= 0) {
1982 clp->option = &clp_option_sentinel[-Clp_BadOption];
1983 return Clp_BadOption;
1985 Clp_RestoreParser(clp, &clpsave);
1991 return opt->option_id;
1995 /** @param clp the parser
1996 * @param allow_options whether options will be allowed
1998 * Remove and return the next argument from @a clp's argument array. If there
1999 * are no arguments left, or if the next argument is an option and @a
2000 * allow_options != 0, then returns null.
2003 Clp_Shift(Clp_Parser *clp, int allow_options)
2004 /* Returns the next argument from the argument list without parsing it.
2005 If there are no more arguments, returns 0. */
2007 Clp_ParserState clpsave;
2008 Clp_SaveParser(clp, &clpsave);
2009 next_argument(clp, allow_options ? 2 : 1);
2011 Clp_RestoreParser(clp, &clpsave);
2020 typedef struct Clp_BuildString {
2027 static void build_string_program_prefix(Clp_BuildString* bs,
2028 const Clp_Parser* clp);
2030 static void build_string_init(Clp_BuildString* bs, Clp_Parser* clp) {
2031 bs->data = bs->pos = bs->buf;
2032 bs->end_data = &bs->buf[sizeof(bs->buf)];
2034 build_string_program_prefix(bs, clp);
2037 static void build_string_cleanup(Clp_BuildString* bs) {
2038 if (bs->data != bs->buf)
2042 static int build_string_grow(Clp_BuildString* bs, size_t want) {
2043 size_t ipos = bs->pos - bs->data, ncap;
2046 for (ncap = (bs->end_data - bs->data) << 1; ncap < want; ncap *= 2)
2048 if (bs->data == bs->buf) {
2049 if ((bs->data = (char*) malloc(ncap)))
2050 memcpy(bs->data, bs->buf, bs->pos - bs->buf);
2052 bs->data = (char*) realloc(bs->data, ncap);
2054 bs->pos = bs->end_data = bs->data;
2057 bs->pos = bs->data + ipos;
2058 bs->end_data = bs->data + ncap;
2063 #define ENSURE_BUILD_STRING(bs, space) \
2064 ((((bs)->end_data - (bs)->pos) >= (space)) \
2065 || build_string_grow((bs), (bs)->pos - (bs)->data + (space)))
2068 append_build_string(Clp_BuildString *bs, const char *s, int l)
2072 if (ENSURE_BUILD_STRING(bs, l)) {
2073 memcpy(bs->pos, s, l);
2079 build_string_program_prefix(Clp_BuildString* bs, const Clp_Parser* clp)
2081 const Clp_Internal* cli = clp->internal;
2082 if (cli->program_name && cli->program_name[0]) {
2083 append_build_string(bs, cli->program_name, -1);
2084 append_build_string(bs, ": ", 2);
2090 Clp_vbsprintf(Clp_Parser *clp, Clp_BuildString *bs,
2091 const char *fmt, va_list val)
2093 Clp_Internal *cli = clp->internal;
2094 const char *percent;
2097 for (percent = strchr(fmt, '%'); percent; percent = strchr(fmt, '%')) {
2098 append_build_string(bs, fmt, percent - fmt);
2099 switch (*++percent) {
2102 const char *s = va_arg(val, const char *);
2103 append_build_string(bs, s ? s : "(null)", -1);
2108 const char *s = va_arg(val, const char *);
2110 c = decode_utf8(s, 0);
2112 c = (unsigned char) *s;
2117 c = va_arg(val, int);
2121 if (ENSURE_BUILD_STRING(bs, 4)) {
2122 if (c >= 32 && c <= 126)
2126 *bs->pos++ = c + 64;
2127 } else if (cli->utf8 && c >= 127 && c < 0x110000) {
2128 bs->pos = encode_utf8(bs->pos, 4, c);
2129 } else if (c >= 127 && c <= 255) {
2130 sprintf(bs->pos, "\\%03o", c & 0xFF);
2140 int d = va_arg(val, int);
2141 if (ENSURE_BUILD_STRING(bs, 32)) {
2142 sprintf(bs->pos, "%d", d);
2143 bs->pos = strchr(bs->pos, 0);
2150 int optno = cli->current_option;
2151 const Clp_Option *opt = &cli->opt[optno];
2153 append_build_string(bs, "(no current option!)", -1);
2154 else if (cli->current_short) {
2155 append_build_string(bs, cli->option_chars, -1);
2156 if (ENSURE_BUILD_STRING(bs, 5)) {
2158 bs->pos = encode_utf8(bs->pos, 5, opt->short_name);
2160 *bs->pos++ = opt->short_name;
2162 } else if (cli->negated_by_no) {
2163 append_build_string(bs, cli->option_chars, -1);
2164 append_build_string(bs, "no-", 3);
2165 append_build_string(bs, opt->long_name + cli->iopt[optno].ilongoff, -1);
2167 append_build_string(bs, cli->option_chars, -1);
2168 append_build_string(bs, opt->long_name + cli->iopt[optno].ilongoff, -1);
2170 if (optno >= 0 && clp->have_val && *percent == 'V') {
2171 if (cli->current_short && !cli->iopt[optno].ioptional)
2172 append_build_string(bs, " ", 1);
2173 else if (!cli->current_short)
2174 append_build_string(bs, "=", 1);
2175 append_build_string(bs, clp->vstr, -1);
2181 if (ENSURE_BUILD_STRING(bs, 1))
2186 append_build_string(bs, (cli->utf8 ? "\342\200\230" : "'"), -1);
2191 append_build_string(bs, (cli->utf8 ? "\342\200\231" : "'"), -1);
2195 append_build_string(bs, "%", 1);
2199 if (ENSURE_BUILD_STRING(bs, 2)) {
2201 *bs->pos++ = *percent;
2210 append_build_string(bs, fmt, -1);
2213 static const char* build_string_text(Clp_BuildString* bs, int report_oom) {
2217 } else if (report_oom)
2218 return "out of memory\n";
2224 do_error(Clp_Parser *clp, Clp_BuildString *bs)
2226 const char *text = build_string_text(bs, 1);
2227 if (clp->internal->error_handler != 0)
2228 (*clp->internal->error_handler)(clp, text);
2230 fputs(text, stderr);
2233 /** @param clp the parser
2234 * @param format error format
2236 * Format an error message from @a format and any additional arguments in
2237 * the ellipsis. The resulting error string is then printed to standard
2238 * error (or passed to the error handler specified by Clp_SetErrorHandler).
2239 * Returns the number of characters printed.
2241 * The following format characters are accepted:
2244 * <dt><tt>%</tt><tt>c</tt></dt>
2245 * <dd>A character (type <tt>int</tt>). Control characters are printed in
2246 * caret notation. If the parser is in UTF-8 mode, the character is formatted
2247 * in UTF-8. Otherwise, special characters are printed with backslashes and
2248 * octal notation.</dd>
2249 * <dt><tt>%</tt><tt>s</tt></dt>
2250 * <dd>A string (type <tt>const char *</tt>).</dd>
2251 * <dt><tt>%</tt><tt>C</tt></dt>
2252 * <dd>The argument is a string (type <tt>const char *</tt>). The first
2253 * character in this string is printed. If the parser is in UTF-8 mode, this
2254 * may involve multiple bytes.</dd>
2255 * <dt><tt>%</tt><tt>d</tt></dt>
2256 * <dd>An integer (type <tt>int</tt>). Printed in decimal.</dd>
2257 * <dt><tt>%</tt><tt>O</tt></dt>
2258 * <dd>The current option. No values are read from the argument list; the
2259 * current option is defined in the Clp_Parser object itself.</dd>
2260 * <dt><tt>%</tt><tt>V</tt></dt>
2261 * <dd>Like <tt>%</tt><tt>O</tt>, but also includes the current value,
2263 * <dt><tt>%%</tt></dt>
2264 * <dd>Prints a percent character.</dd>
2265 * <dt><tt>%</tt><tt><</tt></dt>
2266 * <dd>Prints an open quote string. In UTF-8 mode, prints a left single
2267 * quote. Otherwise prints a single quote.</dd>
2268 * <dt><tt>%</tt><tt>></tt></dt>
2269 * <dd>Prints a closing quote string. In UTF-8 mode, prints a right single
2270 * quote. Otherwise prints a single quote.</dd>
2271 * <dt><tt>%</tt><tt>,</tt></dt>
2272 * <dd>Prints an apostrophe. In UTF-8 mode, prints a right single quote.
2273 * Otherwise prints a single quote.</dd>
2276 * Note that no flag characters, precision, or field width characters are
2277 * currently supported.
2279 * @sa Clp_SetErrorHandler
2282 Clp_OptionError(Clp_Parser *clp, const char *format, ...)
2286 va_start(val, format);
2287 build_string_init(&bs, clp);
2288 Clp_vbsprintf(clp, &bs, format, val);
2289 append_build_string(&bs, "\n", 1);
2292 build_string_cleanup(&bs);
2293 return bs.pos - bs.data;
2296 /** @param clp the parser
2297 * @param f output file
2298 * @param format error format
2300 * Format an error message using @a format and additional arguments in the
2301 * ellipsis, according to the Clp_OptionError formatting conventions. The
2302 * resulting message is written to @a f.
2304 * @sa Clp_OptionError */
2306 Clp_fprintf(Clp_Parser* clp, FILE* f, const char* format, ...)
2310 va_start(val, format);
2311 build_string_init(&bs, NULL);
2312 Clp_vbsprintf(clp, &bs, format, val);
2314 if (bs.pos != bs.data)
2315 fwrite(bs.data, 1, bs.pos - bs.data, f);
2316 build_string_cleanup(&bs);
2317 return bs.pos - bs.data;
2320 /** @param clp the parser
2321 * @param f output file
2322 * @param format error format
2323 * @param val arguments
2325 * Format an error message using @a format and @a val, according to the
2326 * Clp_OptionError formatting conventions. The resulting message is written
2329 * @sa Clp_OptionError */
2331 Clp_vfprintf(Clp_Parser* clp, FILE* f, const char* format, va_list val)
2334 build_string_init(&bs, NULL);
2335 Clp_vbsprintf(clp, &bs, format, val);
2336 if (bs.pos != bs.data)
2337 fwrite(bs.data, 1, bs.pos - bs.data, f);
2338 build_string_cleanup(&bs);
2339 return bs.pos - bs.data;
2342 /** @param clp the parser
2343 * @param str output string
2344 * @param size size of output string
2345 * @param format error format
2347 * Format an error message from @a format and any additional arguments in
2348 * the ellipsis, according to the Clp_OptionError formatting conventions.
2349 * The resulting string is written to @a str. At most @a size characters are
2350 * written to @a str, including a terminating null byte. The return value is
2351 * the number of characters that would have been written (excluding the
2352 * terminating null byte) if @a size were large enough to contain the entire
2355 * @sa Clp_OptionError */
2357 Clp_vsnprintf(Clp_Parser* clp, char* str, size_t size,
2358 const char* format, va_list val)
2361 build_string_init(&bs, NULL);
2362 Clp_vbsprintf(clp, &bs, format, val);
2363 if ((size_t) (bs.pos - bs.data) < size) {
2364 memcpy(str, bs.data, bs.pos - bs.data);
2365 str[bs.pos - bs.data] = 0;
2367 memcpy(str, bs.data, size - 1);
2370 build_string_cleanup(&bs);
2371 return bs.pos - bs.data;
2375 ambiguity_error(Clp_Parser *clp, int ambiguous, int *ambiguous_values,
2376 const Clp_Option *opt, const Clp_InternOption *iopt,
2377 const char *prefix, const char *fmt, ...)
2379 Clp_Internal *cli = clp->internal;
2385 build_string_init(&bs, clp);
2386 Clp_vbsprintf(clp, &bs, fmt, val);
2387 append_build_string(&bs, "\n", 1);
2389 build_string_program_prefix(&bs, clp);
2390 append_build_string(&bs, "(Possibilities are", -1);
2392 for (i = 0; i < ambiguous && i < MAX_AMBIGUOUS_VALUES; i++) {
2393 int value = ambiguous_values[i];
2394 const char *no_dash = "";
2396 value = -(value + 1), no_dash = "no-";
2398 append_build_string(&bs, " ", 1);
2399 else if (i == ambiguous - 1)
2400 append_build_string(&bs, (i == 1 ? " and " : ", and "), -1);
2402 append_build_string(&bs, ", ", 2);
2403 append_build_string(&bs, (cli->utf8 ? "\342\200\230" : "'"), -1);
2404 append_build_string(&bs, prefix, -1);
2405 append_build_string(&bs, no_dash, -1);
2406 append_build_string(&bs, opt[value].long_name + iopt[value].ilongoff, -1);
2407 append_build_string(&bs, (cli->utf8 ? "\342\200\231" : "'"), -1);
2410 if (ambiguous > MAX_AMBIGUOUS_VALUES)
2411 append_build_string(&bs, ", and others", -1);
2412 append_build_string(&bs, ".)\n", -1);
2416 build_string_cleanup(&bs);
2421 copy_string(char *buf, int buflen, int bufpos, const char *what)
2423 int l = strlen(what);
2424 if (l > buflen - bufpos - 1)
2425 l = buflen - bufpos - 1;
2426 memcpy(buf + bufpos, what, l);
2430 /** @param clp the parser
2431 * @param buf output buffer
2432 * @param len length of output buffer
2433 * @return number of characters written to the buffer, not including the terminating NUL
2435 * A string that looks like the last option parsed by @a clp is extracted into
2436 * @a buf. The correct option characters are put into the string first,
2437 * followed by the option text. The output buffer is null-terminated unless
2440 * @sa Clp_CurOptionName
2443 Clp_CurOptionNameBuf(Clp_Parser *clp, char *buf, int len)
2445 Clp_Internal *cli = clp->internal;
2446 int optno = cli->current_option;
2449 pos += copy_string(buf, len, pos, "(no current option!)");
2450 else if (cli->current_short) {
2451 pos += copy_string(buf, len, pos, cli->option_chars);
2453 pos = (encode_utf8(buf + pos, len - pos - 1, cli->opt[optno].short_name) - buf);
2454 else if (pos < len - 1)
2455 buf[pos++] = cli->opt[optno].short_name;
2456 } else if (cli->negated_by_no) {
2457 pos += copy_string(buf, len, pos, cli->option_chars);
2458 pos += copy_string(buf, len, pos, "no-");
2459 pos += copy_string(buf, len, pos, cli->opt[optno].long_name + cli->iopt[optno].ilongoff);
2461 pos += copy_string(buf, len, pos, cli->option_chars);
2462 pos += copy_string(buf, len, pos, cli->opt[optno].long_name + cli->iopt[optno].ilongoff);
2469 /** @param clp the parser
2470 * @return string describing the current option
2472 * This function acts like Clp_CurOptionNameBuf(), but returns a pointer into
2473 * a static buffer that will be rewritten on the next call to
2474 * Clp_CurOptionName().
2476 * @note This function is not thread safe.
2478 * @sa Clp_CurOptionName
2481 Clp_CurOptionName(Clp_Parser *clp)
2483 static char buf[256];
2484 Clp_CurOptionNameBuf(clp, buf, 256);
2489 Clp_IsLong(Clp_Parser *clp, const char *long_name)
2491 Clp_Internal *cli = clp->internal;
2492 int optno = cli->current_option;
2493 return optno >= 0 && strcmp(cli->opt[optno].long_name, long_name) == 0;
2497 Clp_IsShort(Clp_Parser *clp, int short_name)
2499 Clp_Internal *cli = clp->internal;
2500 int optno = cli->current_option;
2501 return optno >= 0 && cli->opt[optno].short_name == short_name;