Tizen 2.0 Release
[external/libgnutls26.git] / src / cfg / cmdline.c
1 /*
2  * libcfg+ - precise command line & config file parsing library
3  *
4  * cmdline.c - command line parsing
5  * ____________________________________________________________
6  *
7  * Developed by Ondrej Jombik <nepto@platon.sk>
8  *          and Lubomir Host <rajo@platon.sk>
9  * Copyright (c) 2001-2004 Platon SDG, http://platon.sk/
10  * All rights reserved.
11  *
12  * See README file for more information about this software.
13  * See COPYING file for license information.
14  *
15  * Download the latest version from
16  * http://platon.sk/projects/libcfg+/
17  */
18
19 /* $Platon: libcfg+/src/cmdline.c,v 1.36 2004/01/12 06:03:09 nepto Exp $ */
20
21 /* Includes {{{ */
22 #ifdef HAVE_CONFIG_H
23 #  include "config.h"
24 #endif
25
26 #if STDC_HEADERS
27 #  include <stdlib.h>
28 #else
29 #  if HAVE_STDLIB_H
30 #    include <stdlib.h>
31 #  endif
32 #endif
33 #if HAVE_STRING_H
34 #  if !STDC_HEADERS && HAVE_MEMORY_H
35 #    include <memory.h>
36 #  endif
37 #  include <string.h>
38 #endif
39 #if HAVE_STRINGS_H
40 #  include <strings.h>
41 #endif
42
43 #include <platon/str/strplus.h>
44 #include <platon/str/strdyn.h>
45
46 #include "cfg+.h"
47 #include "shared.h"
48 /* }}} */
49
50         int
51 cfg_cmdline_get_next_opt(con)
52         const CFG_CONTEXT con;
53 { /* {{{ */
54         int arg_used;
55         int ret_val;
56
57         con->error_code = CFG_OK;
58
59         /* Initial position seek */
60         if (! con->parsing_started) {
61                 con->parsing_started = 1;
62
63                 if (con->begin_pos < 0) {
64                         con->error_code = CFG_ERROR_SEEK_ERROR;
65                         return con->error_code;
66                 }
67
68                 if (con->begin_pos > 0) {
69                         for (; con->cur_idx < con->begin_pos; con->cur_idx++)
70                                 if (con->argv[con->cur_idx] == NULL) {
71                                         con->error_code = CFG_ERROR_SEEK_ERROR;
72                                         return con->error_code;
73                                 }
74                 }
75
76                 if (con->flags & CFG_SKIP_FIRST)
77                         con->cur_idx_tmp = 1;
78                 else
79                         con->cur_idx_tmp = 0;
80         }
81
82         /*
83          * Main loop
84          */
85         while (1) {
86
87                 arg_used = 0;
88
89                 /* Updating cur_idx step by step and testing for NULL in argv. */
90                 for (; con->cur_idx_tmp > 0; con->cur_idx_tmp--, con->cur_idx++)
91                         if (con->argv[con->cur_idx] == NULL)
92                                 break;
93
94                 /* Finished? (size is reached) */
95                 if (con->size >= 0 && con->cur_idx >= con->begin_pos + con->size)
96                         break;
97
98                 /* Finished? (NULL is detected) */
99                 if (con->argv[con->cur_idx] == NULL)
100                         break;
101
102                 if (con->cur_opt_type & CFG_SHORT_OPTIONS) {
103
104                         con->cur_opt[0] = con->cur_arg[0];
105                         PLATON_FUNC(strdel)(con->cur_arg);
106
107                         if (strlen(con->cur_arg) == 0) {
108                                 con->cur_opt_type -= CFG_SHORT_OPTIONS;
109                                 free(con->cur_arg);
110
111                                 /* strdup() doesn't accept NULL as parameter */
112                                 con->cur_arg = con->argv[con->cur_idx + 1] != NULL
113                                         ? strdup(con->argv[con->cur_idx + 1])
114                                         : NULL;
115                         }
116                 }
117                 else {
118                         register int leftover_init = 0;
119
120                         /* Test if previous argument was leftover and also there is not
121                            advanced leftovers initializations set in context flags. */
122                         if (! (con->flags & CFG_ADVANCED_LEFTOVERS)
123                                         && con->cur_opt_type == CFG_NONE_OPTION
124                                         && con->cur_opt == NULL && con->cur_arg != NULL
125                                         && con->argv[con->cur_idx - 1] != NULL
126                                         && ! strcmp(con->cur_arg, con->argv[con->cur_idx - 1]))
127                                 leftover_init = 1;
128
129                         __cfg_free_currents(con);
130
131                         if (! PLATON_FUNC(strdyn_compare)(con->prop[CFG_LINE_STOP_STRING],
132                                                 con->argv[con->cur_idx])) {
133                                 con->error_code = CFG_ERROR_STOP_STR_FOUND;
134                                 return con->error_code;
135                         }
136
137                         /* Skip option analyze in __cfg_cmdline_set_currents(),
138                            count it as leftover. */
139                         if (leftover_init) {
140                                 con->cur_opt_type = CFG_NONE_OPTION;
141                                 con->cur_opt = NULL;
142                                 if ((con->cur_arg = strdup(con->argv[con->cur_idx])) == NULL) {
143                                         con->error_code = CFG_ERROR_NOMEM;
144                                         return con->error_code;
145                                 }
146                         }
147                         else {
148                                 if (__cfg_cmdline_set_currents(con) != CFG_OK) {
149                                         con->error_code = CFG_ERROR_NOMEM;
150                                         return con->error_code;
151                                 }
152                         }
153                 }
154
155                 con->error_code = __cfg_process_currents(con, &ret_val, &arg_used);
156                 if (con->error_code != CFG_OK)
157                         return con->error_code;
158
159                 if (arg_used) {
160                         if (! (con->cur_opt_type & CFG_LONG_SEPINIT)
161                                         && !(con->cur_opt_type & CFG_SHORT_OPTIONS)
162                                         && !(con->cur_opt_type == CFG_NONE_OPTION))
163                                 con->cur_idx_tmp++;
164
165                         if (con->cur_opt_type & CFG_SHORT_OPTIONS)
166                                 con->cur_opt_type -= CFG_SHORT_OPTIONS;
167                 }
168
169                 if (! (con->cur_opt_type & CFG_SHORT_OPTIONS))
170                         con->cur_idx_tmp++;
171
172                 if (ret_val > 0)
173                         return ret_val;
174         }
175
176         return con->error_code; /* CFG_OK */
177 } /* }}} */
178
179 /* Modeline for ViM {{{
180  * vim:set ts=4:
181  * vim600:fdm=marker fdl=0 fdc=0:
182  * }}} */
183