/*--------------------------------------------------------------------------- * Purpose: Render into a string a one-line description of a switch. * * Return: The result buffer. * * Programmer: Robb Matzke * Tuesday, June 6, 2000 * * Modifications: *--------------------------------------------------------------------------- */ static char * switch_synopsis(switch_t *sw, char *buffer) { int type, required; char name[32]; switch_arg(sw, &type, sizeof name, name, &required, NULL); buffer[0] = '\0'; /* Short */ if (sw->short_name) { strcat(buffer, sw->short_name); if (type) { strcat(buffer, " "); if (!required) strcat(buffer, "["); strcat(buffer, name); if (!required) strcat(buffer, "]"); } } /* Long */ if (sw->long_name) { if (buffer[0]) strcat(buffer, ", "); strcat(buffer, sw->long_name); if (type) { if (!required) strcat(buffer, "["); strcat(buffer, "="); strcat(buffer, name); if (!required) strcat(buffer, "]"); } } return buffer; }
CommandLine& CommandLine::AppendSwitch(const StringType& name, const StringType& value) { switches_[name] = value; // Since we have |last_not_param_| to demarcate switches and parameters, we here // leave switch prefix unprepended. StringType switch_arg(name); if (!value.empty()) { switch_arg.append(L"=").append(value); } argv_.emplace(std::next(last_not_param_), switch_arg); ++last_not_param_; return *this; }
/*--------------------------------------------------------------------------- * Purpose: This function gets called to parse the switch value based * on the switch's arg spec. If RELAX is non-zero then an * error is treated as if the argument is not present. * * Programmer: Robb Matzke * Thursday, June 1, 2000 * * Modifications: *--------------------------------------------------------------------------- */ int switch_parse_arg(switch_t *sw, const char *argv, const char *value, int relax, void(*error)(const char*, ...)) { int i, type, required, d, retval=0; char *rest; const char *tmp; double g; const char *sw_name = sw->long_name?sw->long_name:sw->short_name; const char *dflt=NULL; switch_arg(sw, &type, 0, NULL, &required, &dflt); if (required && !value) { (error)("switch `%s' requires an argument", sw_name); return -1; } switch (type) { case 0: /* no argument possible */ return 0; case 'g': /* floating-point argument */ for (i=0; i<2; i++) { if (NULL==(tmp=i?dflt:value) || !*tmp) continue; g = strtod(tmp, &rest); if (rest && *rest) { if (!relax) { (error)("switch `%s' should have a floating-point " "argument", sw_name); return -1; } } else { sw->lexeme = tmp; sw->value.g = g; retval = i?0:1; break; } } break; case 'd': /* integer argument */ for (i=0; i<2; i++) { if (NULL==(tmp=i?dflt:value) || !*tmp) continue; d = strtol(tmp, &rest, 0); if (rest && *rest) { if (!relax) { (error)("switch `%s' should have an integer argument", sw_name); return -1; } } else { sw->lexeme = tmp; sw->value.d = d; retval = i?0:1; break; } } break; case 'u': /* unsigned integer argument */ for (i=0; i<2; i++) { if (NULL==(tmp=i?dflt:value) || !*tmp) continue; d = strtol(tmp, &rest, 0); if ((rest && *rest) || d<0) { if (!relax) { (error)("switch `%s' should have a non-negative integer " "argument", sw_name); return -1; } } else { sw->lexeme = tmp; sw->value.d = d; retval = i?0:1; break; } } break; case 's': /* string argument */ for (i=0; i<2; i++) { if (NULL==(tmp=i?dflt:value)) continue; /*empty string okay*/ sw->lexeme = tmp; sw->value.s = tmp; retval = i?0:1; break; } break; case 'b': /* boolean */ for (i=0; i<2; i++) { if (NULL==(tmp=i?dflt:value)) continue; /*empty string okay*/ if (!tmp[0] || !strcmp(tmp, "f") || !strcmp(tmp, "false") || !strcmp(tmp, "n") || !strcmp(tmp, "no")) { sw->lexeme = tmp; sw->value.d = 0; retval = i?0:1; break; } else if (!strcmp(tmp, "t") || !strcmp(tmp, "true") || !strcmp(tmp, "y") || !strcmp(tmp, "yes")) { sw->lexeme = tmp; sw->value.d = 1; retval = i?0:1; break; } else { d = strtol(tmp, &rest, 0); if (!rest || !*rest) { sw->lexeme = tmp; sw->value.d = d; retval = i?0:1; break; } else if (!relax) { (error)("switch `%s' should have a Boolean argument", sw_name); return -1; } } } break; default: abort(); } return retval; }