1 /*********************************************************
2 * cc90hfe (c) Teo Developers
3 *********************************************************
4 *
5 * Copyright (C) 2012-2017 Fran�ois Mouret
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 /*
23 * Module : option.c
24 * Version : 0.7.0
25 * Cr�� par : Fran�ois Mouret 27/02/2013
26 * Modifi� par: Fran�ois Mouret 31/05/2015
27 *
28 * Management of the command line.
29 */
30
31
32 #ifndef SCAN_DEPEND
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <sys/stat.h>
38 #include <unistd.h>
39 #endif
40
41 #include "defs.h"
42 #include "main.h"
43 #include "std.h"
44 #include "option.h"
45 #include "ini.h"
46 #include "encode.h"
47 #include "errors.h"
48
49
50 enum {
51 WRONG_OPTION = 0,
52 SHORT_OPTION,
53 LONG_OPTION
54 };
55
56 struct OPTION_ENTRY *help_option = NULL;
57 struct OPTION_ENTRY *prog_option = NULL;
58
59
60
61 /* help_display:
62 * Affiche une liste d'aide.
63 */
help_display(struct OPTION_ENTRY option[])64 static void help_display (struct OPTION_ENTRY option[])
65 {
66 int i;
67 size_t size;
68
69 for (i=0; option[i].long_name!=NULL; i++)
70 {
71 size = 0;
72 printf (" ");
73 if (option[i].short_name != '\0')
74 size += printf ("-%c, ", option[i].short_name);
75 size += printf ("--%s", option[i].long_name);
76 if (option[i].argument != NULL)
77 size += printf (" <%s>",option[i].argument);
78 if (option[i].comment != NULL) {
79 do { size += printf (" "); } while (size < 19);
80 (void)printf (" %s", encode_String(option[i].comment));
81 }
82 (void)printf ("\n");
83 }
84 }
85
86
87
88 /* help:
89 * Affiche l'aide.
90 */
help(char * program_name)91 static void help (char *program_name)
92 {
93 printf ("\n%s:\n", is_fr?"Utilisation":"Usage");
94 printf (" %s [OPTION...] %s\n\n", program_name,
95 is_fr?"[FICHIER HFE]":"[HFE FILE]");
96 printf ("%s:\n", is_fr?"Options de l'aide":"Help Options");
97 help_display (help_option);
98 printf ("\n");
99 printf ("%s:\n", is_fr?"Options de l'application":"Application Options");
100 help_display (prog_option);
101 printf ("\n");
102 main_FreeAll ();
103 exit (EXIT_SUCCESS);
104 }
105
106
107
108 /* get_string:
109 * Traite une liste d'options.
110 */
get_string(struct OPTION_ENTRY * option,char * str)111 static char *get_string (struct OPTION_ENTRY *option, char *str)
112 {
113 char *p, *s, *tmp_s;
114 char **reg;
115
116 if (str != NULL)
117 {
118 s = std_strdup_printf ("%s", str);
119 if ((s != NULL)
120 && (*s == '"')
121 && ((p = strrchr (s, '"')) != NULL)
122 && (p > s))
123 {
124 *p = '\0';
125 tmp_s = std_strdup_printf ("%s", s+1);
126 s = std_free (s);
127 s = tmp_s;
128 }
129 reg = option->reg;
130 *reg = (char*)std_free (*reg);
131 *reg = std_strdup_printf ("%s",s);
132 }
133 return str;
134 }
135
136
137
138 /* option_check:
139 * Traite une liste d'options.
140 */
option_check(int argc,char * argv[],char * internal_prog_name,struct OPTION_ENTRY option[],struct STRING_LIST ** remain_option)141 static char *option_check (int argc, char *argv[],
142 char *internal_prog_name,
143 struct OPTION_ENTRY option[],
144 struct STRING_LIST **remain_option)
145 {
146 char *s = NULL;
147 int i, op;
148 int *d;
149 int option_size;
150 int option_i = 0;
151 int arg_i;
152
153 for (i=1; i<argc; i++)
154 {
155 if (argv[i][0] == '-')
156 {
157 option_size = WRONG_OPTION;
158 for (op=0; (option[op].long_name != NULL) && (option_size == WRONG_OPTION); op++)
159 {
160 option_i = op;
161 if (strlen(argv[i]) == 2)
162 {
163 if (argv[i][1] == option[op].short_name)
164 option_size = SHORT_OPTION;
165 }
166 else
167 if (argv[i][1] == '-')
168 {
169 if (strncmp (&argv[i][2], option[op].long_name,
170 strlen (option[op].long_name)) == 0)
171 option_size = LONG_OPTION;
172 }
173 }
174
175 if (option_size == WRONG_OPTION)
176 return std_strdup_printf ("%s : %s", argv[i],
177 is_fr?"Option inconnue":"Unknown option");
178
179 switch (option[option_i].type) {
180 case OPTION_ARG_FILENAME :
181 case OPTION_ARG_STRING :
182 if (option_size == SHORT_OPTION) {
183 s = std_free(s);
184 if (++i < argc)
185 s = get_string (&option[option_i], argv[i]);
186 } else {
187 arg_i = strlen (option[option_i].long_name) + 2;
188 if (argv[i][arg_i] == '=')
189 s = get_string (&option[option_i], std_strdup_printf ("%s", &argv[i][arg_i+1]));
190 }
191 if (s==NULL)
192 return std_strdup_printf ("%s %s",
193 is_fr?"Argument manquant pour":"Missing argument for",
194 argv[i]);
195 break;
196
197 case OPTION_ARG_INT :
198 d = option[option_i].reg;
199 *d = (int)strtol (argv[i+1],NULL,10);
200 if ((*d < option[option_i].min_value)
201 || (*d > option[option_i].max_value))
202 return std_strdup_printf ("%s %s (%d,%d)",
203 is_fr?"Mauvaise valeur pour":"Bad value for",
204 argv[i],
205 option[option_i].min_value,
206 option[option_i].max_value
207 );
208 i++;
209 break;
210
211 case OPTION_ARG_BOOL :
212 d = option[option_i].reg;
213 *d = TRUE;
214 break;
215
216 case OPTION_ARG_HELP :
217 help (internal_prog_name);
218 break;
219
220 default : return std_strdup_printf ("%s %s",
221 is_fr?"Type inconnu pour":"Unknown type for",
222 argv[i]);
223 }
224 }
225 else
226 *remain_option = std_StringListAppend (*remain_option, argv[i]);
227 }
228 return NULL;
229 }
230
231
232 /* ------------------------------------------------------------------------- */
233
234
235 /* option_Parse:
236 * Traite les options.
237 */
option_Parse(int argc,char * argv[],char * internal_prog_name,struct OPTION_ENTRY prog_option_list[],struct STRING_LIST ** remain_option)238 char *option_Parse (int argc, char *argv[],
239 char *internal_prog_name,
240 struct OPTION_ENTRY prog_option_list[],
241 struct STRING_LIST **remain_option)
242 {
243 struct OPTION_ENTRY help_option_list[] = {
244 { "help", 'h', OPTION_ARG_HELP, NULL,
245 is_fr?"Aide de ce programme":"Help of this program", NULL },
246 { NULL, 0, 0, NULL, NULL, NULL }
247 };
248
249 help_option = help_option_list;
250 prog_option = prog_option_list;
251
252 error_msg = std_free (error_msg);
253 error_msg = option_check (argc, argv, internal_prog_name,
254 help_option, remain_option);
255 if (error_msg != NULL) {
256 error_msg = std_free (error_msg);
257 error_msg = option_check (argc, argv, internal_prog_name,
258 prog_option, remain_option);
259 }
260 return error_msg;
261 }
262
263