e66b13eb68cdae070b64ea487a0e926078a94d39
[yaz-moved-to-github.git] / src / options.c
1 /*
2  * Copyright (C) 1995-2007, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  * $Id: options.c,v 1.7 2008-02-20 10:03:42 adam Exp $
6  */
7 /**
8  * \file options.c
9  * \brief Implements command line options parsing
10  */
11 #if HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14
15 #include <stdlib.h>
16 #include <string.h>
17 #include <yaz/options.h>
18
19 static int arg_no = 1;
20 static int arg_off = 0;
21
22 int options (const char *desc, char **argv, int argc, char **arg)
23 {
24     const char *opt_buf = 0;
25     int i = 0;
26     int ch = 0;
27     
28     if (arg_no >= argc)
29         return -2;
30     if (arg_off == 0)
31     {
32         while (argv[arg_no][0] == '\0')
33         {
34             arg_no++;
35             if (arg_no >= argc)
36                 return -2;
37         }
38         if (argv[arg_no][0] != '-' || argv[arg_no][1] == '\0')
39         {
40             *arg = argv[arg_no++];
41             return 0;
42         }
43         arg_off++; /* skip - */
44     }
45     if (argv[arg_no][1] == '-')
46     {   /* long opt */
47         opt_buf = argv[arg_no]+2;
48         arg_off = strlen(argv[arg_no]);
49     }
50     else
51     {   /* single char opt */
52         ch = argv[arg_no][arg_off++];
53     }
54     while (desc[i])
55     {
56         int desc_char = desc[i++];
57         int type = 0;
58         while (desc[i] == '{')
59         {
60             int i0 = ++i;
61             while (desc[i] && desc[i] != '}')
62                 i++;
63             if (opt_buf && (i - i0) == strlen(opt_buf) &&
64                 memcmp(opt_buf, desc+i0, i - i0) == 0)
65                 ch = desc_char;
66             if (desc[i])
67                 i++;
68         }
69         if (desc[i] == ':')
70         {       /* option with string argument */
71                 type = desc[i++];
72         }
73         if (desc_char == ch)
74         { 
75             if (type) /* option with argument */
76             {
77                 if (argv[arg_no][arg_off])
78                 {
79                     *arg = argv[arg_no]+arg_off;
80                     arg_no++;
81                     arg_off = 0;
82                 }
83                 else
84                 {
85                     arg_no++;
86                     arg_off = 0;
87                     if (arg_no < argc)
88                         *arg = argv[arg_no++];
89                     else
90                         *arg = "";
91                 }
92             }
93             else /* option with no argument */
94             {
95                 if (argv[arg_no][arg_off])
96                     arg_off++;
97                 else
98                 {
99                     arg_off = 0;
100                     arg_no++;
101                 }
102             }
103             return ch;
104         }               
105     }
106     *arg = argv[arg_no]+arg_off-1;
107     arg_no = arg_no + 1;
108     arg_off = 0;
109     return -1;
110 }
111 /*
112  * Local variables:
113  * c-basic-offset: 4
114  * indent-tabs-mode: nil
115  * End:
116  * vim: shiftwidth=4 tabstop=8 expandtab
117  */
118