/* This file is part of the YAZ toolkit. * Copyright (C) Index Data * See the file LICENSE for details. */ /** * \file options.c * \brief Implements command line options parsing */ #if HAVE_CONFIG_H #include #endif #include #include #include static int arg_no = 1; static size_t arg_off = 0; static int eof_options = 0; int options(const char *desc, char **argv, int argc, char **arg) { const char *opt_buf = 0; size_t i = 0; int ch = 0; if (arg_no >= argc) return YAZ_OPTIONS_EOF; if (arg_off == 0) { while (argv[arg_no][0] == '\0') { arg_no++; if (arg_no >= argc) return YAZ_OPTIONS_EOF; } if (argv[arg_no][0] != '-' || argv[arg_no][1] == '\0' || eof_options) { *arg = argv[arg_no++]; return 0; } arg_off++; /* skip - */ } /* we're in option mode */ if (argv[arg_no][1] == '-') { /* long opt */ if (argv[arg_no][2] == '\0') /* -- : end of options */ { eof_options = 1; arg_off = 0; ++arg_no; if (arg_no >= argc) return YAZ_OPTIONS_EOF; *arg = argv[arg_no++]; return 0; } opt_buf = argv[arg_no]+2; arg_off = strlen(argv[arg_no]); } else { /* single char opt */ ch = argv[arg_no][arg_off++]; } while (desc[i]) { int desc_char = desc[i++]; int type = 0; while (desc[i] == '{') { size_t i0 = ++i; while (desc[i] && desc[i] != '}') i++; if (opt_buf && (i - i0) == strlen(opt_buf) && memcmp(opt_buf, desc+i0, i - i0) == 0) ch = desc_char; if (desc[i]) i++; } if (desc[i] == ':') { /* option with string argument */ type = desc[i++]; } if (desc_char == ch) { if (type) /* option with argument */ { if (argv[arg_no][arg_off]) { *arg = argv[arg_no]+arg_off; arg_no++; arg_off = 0; } else { arg_no++; arg_off = 0; if (arg_no < argc) *arg = argv[arg_no++]; else *arg = ""; } } else /* option with no argument */ { if (!argv[arg_no][arg_off]) { arg_off = 0; arg_no++; } } return ch; } } *arg = argv[arg_no]+arg_off-1; arg_no = arg_no + 1; arg_off = 0; return YAZ_OPTIONS_ERROR; } /* * Local variables: * c-basic-offset: 4 * c-file-style: "Stroustrup" * indent-tabs-mode: nil * End: * vim: shiftwidth=4 tabstop=8 expandtab */