1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4
5#ifndef GAA_NO_WIN32
6#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(WINDOWS)
7#define GAA_WIN32
8#endif
9#endif
10
11static void* gaa_malloc( size_t size) {
12void* ret;
13	ret = malloc(size);
14	if (ret==NULL) {
15		fprintf(stderr, "gaa: could not allocate memory");
16		exit(1);
17	}
18	return ret;
19}
20
21static void __gaa_helpsingle(char short_name, char *name,
22	char *arg_desc, char *opt_help)
23{
24     int col1, col3, col4, tabsize = 3, curr;
25     int i;
26
27     col1 = 5; /* Default values */
28     col3 = 30;
29     col4 = 70;
30
31     curr = 0;
32     for(i = 0; i < col1; i++)
33        {
34        printf(" ");
35        curr++;
36        }
37     if(short_name)
38        {
39        if(name && *name)
40          {
41            printf("-%c, ", short_name);
42            curr += 4;
43          }
44        else
45          {
46            printf("-%c ", short_name);
47            curr += 3;
48          }
49        }
50     if(name && *name)
51        {
52          printf("--%s ", name);
53          curr += 3 + strlen(name);
54        }
55     if(arg_desc && *arg_desc)
56        {
57          printf("%s ", arg_desc);
58          curr += 1 + strlen(arg_desc);
59        }
60     if(curr >= col3)
61        {
62          printf("\n");
63          curr = 0;
64        }
65     if(opt_help) /* let's print the option's help body */
66        {
67        const char *str = opt_help;
68        while(*str)
69          {
70             while(curr < col3)
71               {
72                 printf(" ");
73                 curr++;
74               }
75             switch(*str)
76               {
77                 case '\n':
78                     printf("\n");
79                     curr = 0;
80                     break;
81                 case '\t':
82                     do
83                        {
84                        printf(" ");
85                        curr++;
86                        }
87                     while((curr - col3) % tabsize != 0 && curr < col4);
88                 case ' ':
89                     if(*str == ' ')
90                        {
91                        curr++;
92                        printf(" ");
93                        }
94                     for(i = 1; str[i] && str[i] != ' ' && str[i] != '\n'
95                        && str[i] != '\t'; i++);
96                     if(curr + i - 1 >= col4)
97                        curr = col4;
98                     break;
99                default:
100                     printf("%c", *str);
101                     curr++;
102               }
103             if(curr >= col4)
104               {
105                 printf("\n");
106                 curr = 0;
107               }
108             str++;
109          }
110        }
111     printf("\n");
112}
113
114void gaa_help(void)
115{
116@
117#line 100 "gaa.skel"
118}
119/* Copy of C area */
120@
121#line 104 "gaa.skel"
122/* GAA HEADER */
123#ifndef GAA_HEADER_POKY
124#define GAA_HEADER_POKY
125
126typedef struct _gaainfo gaainfo;
127
128struct _gaainfo
129{
130@
131#line 114 "gaa.skel"
132};
133
134#ifdef __cplusplus
135extern "C"
136{
137#endif
138
139    int gaa(int argc, char *argv[], gaainfo *gaaval);
140
141    void gaa_help(void);
142
143    int gaa_file(const char *name, gaainfo *gaaval);
144
145#ifdef __cplusplus
146}
147#endif
148
149
150#endif
151@
152#line 135 "gaa.skel"
153
154/* C declarations */
155
156#define GAAERROR(x)    \
157{                   \
158gaa_error = 1;      \
159return x;        \
160}
161
162static char *gaa_current_option;
163static int gaa_error = 0;
164
165/* Generated by gaa */
166
167#include <string.h>
168#include <stdlib.h>
169
170
171#define GAA_OK                       -1
172
173#define GAA_ERROR_NOMATCH            0
174#define GAA_ERROR_NOTENOUGH_ARGS     1
175#define GAA_ERROR_INVALID_ARG        2
176#define GAA_ERROR_UNKNOWN            3
177
178#define GAA_NOT_AN_OPTION       0
179#define GAA_WORD_OPTION         1
180#define GAA_LETTER_OPTION       2
181#define GAA_MULTIPLE_OPTION     3
182
183#define GAA_REST                0
184#define GAA_NB_OPTION           @
185#line 168 "gaa.skel"
186
187#define GAA_CHECK1STR(a,b)      \
188if(a[0] == str[0])              \
189{                               \
190    gaa_current_option = a;     \
191    return b;                   \
192}
193
194#define GAA_CHECKSTR(a,b)                \
195if(strcmp(a,str) == 0)                   \
196{                                        \
197    gaa_current_option = a;              \
198    return b;                            \
199}
200
201#define GAA_TESTMOREARGS                                                  \
202if(!OK)                                                                     \
203{                                  \
204while((gaa_last_non_option != gaa_index) && (gaa_arg_used[gaa_index] == 1)) \
205    gaa_index++;                                                            \
206if(gaa_last_non_option == gaa_index)                                        \
207    return GAA_ERROR_NOTENOUGH_ARGS; \
208}
209
210#define GAA_TESTMOREOPTIONALARGS                                                  \
211if(!OK) \
212{ \
213while((gaa_last_non_option != gaa_index) && (gaa_arg_used[gaa_index] == 1)) \
214    gaa_index++;                                                            \
215if(gaa_last_non_option == gaa_index)                                        \
216    OK = 1; \
217}
218
219#define GAA_FILL_2ARGS(target, func)           \
220target = func(GAAargv[gaa_index]);       \
221gaa_arg_used[gaa_index] = 1;             \
222if(gaa_error == 1)                       \
223{                                        \
224    gaa_error = 0;                       \
225    return GAA_ERROR_INVALID_ARG;        \
226}
227
228
229
230#define GAA_FILL(target, func, num)           \
231if(!OK) \
232{ \
233target = func(GAAargv[gaa_index]);       \
234gaa_arg_used[gaa_index] = 1;             \
235if(gaa_error == 1)                       \
236{                                        \
237    gaa_error = 0;                       \
238    return GAA_ERROR_INVALID_ARG;        \
239} \
240num = 1;  \
241} \
242else \
243{ \
244num = 0; \
245}
246
247#define GAA_LIST_FILL(target, func, type ,num)                      \
248if(!OK) \
249{ \
250num = 0;                                                            \
251target = NULL;                                                      \
252if ( gaa_last_non_option - gaa_index > 0)                           \
253  target = gaa_malloc((gaa_last_non_option - gaa_index) * sizeof(type));\
254for(; gaa_index < gaa_last_non_option; gaa_index++)                 \
255{                                                                   \
256    if(gaa_arg_used[gaa_index] == 0)                                \
257    {                                                               \
258        GAA_FILL_2ARGS(target[num], func);                          \
259        num++;                                                      \
260    }                                                               \
261}                                                                   \
262if(num == 0)                                                        \
263    return GAA_ERROR_NOTENOUGH_ARGS; \
264}
265
266#define GAA_OPTIONALLIST_FILL(target, func, type ,num)                      \
267if(!OK) \
268{ \
269num = 0;                                                            \
270target = NULL;                                                      \
271if ( gaa_last_non_option - gaa_index > 0)                           \
272  target = gaa_malloc((gaa_last_non_option - gaa_index) * sizeof(type));\
273for(; gaa_index < gaa_last_non_option; gaa_index++)                 \
274{                                                                   \
275    if(gaa_arg_used[gaa_index] == 0)                                \
276    {                                                               \
277        GAA_FILL_2ARGS(target[num], func);                                \
278        num++;                                                      \
279    }                                                               \
280} \
281}
282
283#define GAA_OBLIGAT(str)                                            \
284k = 0;                                                              \
285for(i = 0; i < strlen(str); i++)                                    \
286{                                                                   \
287    j = gaa_get_option_num(str + i, GAA_LETTER_OPTION);           \
288    if(j == GAA_ERROR_NOMATCH)                                       \
289    {                                                               \
290        printf("Error: invalid 'obligat' set\n");                  \
291        exit(-1);                                                   \
292    }                                                               \
293    if(opt_list[j] == 1)                                            \
294        k = 1;                                                      \
295}                                                                    \
296if(k == 0)                                                            \
297{                                                                      \
298    if(strlen(str) == 1)                                                \
299        printf("You must give the -%s option\n", str);                     \
300    else                                                                  \
301        printf("You must give at least one option of '%s'\n", str);          \
302    return 0;         \
303}
304
305#define GAA_INCOMP(str)                                                \
306k = 0;                                                              \
307for(i = 0; i < strlen(str); i++)                                    \
308{                                                                   \
309    j = gaa_get_option_num(str + i, GAA_LETTER_OPTION);           \
310    if(j == GAA_ERROR_NOMATCH)                                      \
311    {                                                               \
312        printf("Error: invalid 'obligat' set\n");                  \
313        exit(-1);                                                   \
314    }                                                               \
315    if(opt_list[j] == 1)                                            \
316        k++;                                                      \
317}                   \
318if(k > 1)                                                            \
319{                                                                      \
320    printf("The options '%s' are incompatible\n", str);              \
321    return 0;                                                          \
322}
323
324
325static char **GAAargv;
326static int GAAargc;
327static char *gaa_arg_used;
328static int gaa_processing_file = 0;
329static int inited = 0;
330
331static int gaa_getint(char *arg)
332{
333    int tmp;
334    char a;
335    if(sscanf(arg, "%d%c", &tmp, &a) < 1)
336    {
337        printf("Option %s: '%s' isn't an integer\n", gaa_current_option, arg);
338        GAAERROR(-1);
339    }
340    return tmp;
341}
342
343static char gaa_getchar(char *arg)
344{
345    if(strlen(arg) != 1)
346    {
347        printf("Option %s: '%s' isn't an character\n", gaa_current_option, arg);
348        GAAERROR(-1);
349    }
350    return arg[0];
351}
352
353static char* gaa_getstr(char *arg)
354{
355    return arg;
356}
357static float gaa_getfloat(char *arg)
358{
359    float tmp;
360    char a;
361    if(sscanf(arg, "%f%c", &tmp, &a) < 1)
362    {
363        printf("Option %s: '%s' isn't a float number\n", gaa_current_option, arg);
364        GAAERROR(-1);
365    }
366    return tmp;
367}
368/* option structures */
369@
370#line 349 "gaa.skel"
371static int gaa_is_an_argument(char *str)
372{
373#ifdef GAA_WIN32
374    if(str[0] == '/' && str[1] != 0)
375	return GAA_MULTIPLE_OPTION;
376#endif
377    if(str[0] != '-')
378        return GAA_NOT_AN_OPTION;
379    if(str[1] == 0)
380        return GAA_NOT_AN_OPTION;
381    if(str[1] == '-')
382    {
383        if(str[2] != 0)
384            return GAA_WORD_OPTION;
385        else
386            return GAA_NOT_AN_OPTION;
387    }
388    if(str[2] == 0)
389        return GAA_LETTER_OPTION;
390    else
391        return GAA_MULTIPLE_OPTION;
392}
393
394static int gaa_get_option_num(char *str, int status)
395{
396    switch(status)
397        {
398        case GAA_LETTER_OPTION:
399@        case GAA_MULTIPLE_OPTION:
400#line 375 "gaa.skel"
401@
402#line 277 "gaa.skel"
403        break;
404        case GAA_WORD_OPTION:
405@
406#line 281 "gaa.skel"
407	break;
408        default: break;
409        }
410    return GAA_ERROR_NOMATCH;
411}
412
413static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
414{
415    int OK = 0;
416    int gaa_last_non_option;
417@
418#line 393 "gaa.skel"
419#ifdef GAA_REST_EXISTS
420    struct GAAREST GAAREST_tmp;
421#endif
422
423    opt_list[gaa_num] = 1;
424
425    for(gaa_last_non_option = gaa_index;
426        (gaa_last_non_option != GAAargc) && (gaa_is_an_argument(GAAargv[gaa_last_non_option]) == GAA_NOT_AN_OPTION);
427        gaa_last_non_option++);
428
429    if(gaa_num == GAA_REST)
430    {
431        gaa_index = 1;
432        gaa_last_non_option = GAAargc;
433    }
434
435    switch(gaa_num)
436    {
437@
438#line 413 "gaa.skel"
439    default: break;
440    }
441    return GAA_ERROR_UNKNOWN;
442}
443
444int gaa(int argc, char **argv, gaainfo *gaaval)
445{
446    int tmp1, tmp2;
447    int i, j@;
448    char *opt_list;
449
450    GAAargv = argv;
451    GAAargc = argc;
452
453    opt_list = (char*) gaa_malloc(GAA_NB_OPTION + 1);
454
455    for(i = 0; i < GAA_NB_OPTION + 1; i++)
456        opt_list[i] = 0;
457    /* initialization */
458    if(inited == 0)
459    {
460
461@
462    }
463    inited = 1;
464#line 438 "gaa.skel"
465    gaa_arg_used = NULL;
466
467    if (argc > 0) {
468      gaa_arg_used = gaa_malloc(argc * sizeof(char));
469    }
470
471    for(i = 1; i < argc; i++)
472        gaa_arg_used[i] = 0;
473    for(i = 1; i < argc; i++)
474    {
475        if(gaa_arg_used[i] == 0)
476        {
477            j = 0;
478            tmp1 = gaa_is_an_argument(GAAargv[i]);
479            switch(tmp1)
480            {
481            case GAA_WORD_OPTION:
482                j++;
483            case GAA_LETTER_OPTION:
484                j++;
485                tmp2 = gaa_get_option_num(argv[i]+j, tmp1);
486                if(tmp2 == GAA_ERROR_NOMATCH)
487                {
488                    printf("Invalid option '%s'\n", argv[i]+j);
489                    return 0;
490                }
491                switch(gaa_try(tmp2, i+1, gaaval, opt_list))
492                {
493                case GAA_ERROR_NOTENOUGH_ARGS:
494                    printf("'%s': not enough arguments\n",gaa_current_option);
495                    return 0;
496                case GAA_ERROR_INVALID_ARG:
497                    printf("Invalid arguments\n");
498                    return 0;
499                case GAA_OK:
500                    break;
501                default:
502                    printf("Unknown error\n");
503                }
504                gaa_arg_used[i] = 1;
505                break;
506            case GAA_MULTIPLE_OPTION:
507                for(j = 1; j < strlen(argv[i]); j++)
508                {
509                    tmp2 = gaa_get_option_num(argv[i]+j, tmp1);
510                    if(tmp2 == GAA_ERROR_NOMATCH)
511                    {
512                        printf("Invalid option '%c'\n", *(argv[i]+j));
513                        return 0;
514                    }
515                    switch(gaa_try(tmp2, i+1, gaaval, opt_list))
516                    {
517                    case GAA_ERROR_NOTENOUGH_ARGS:
518                        printf("'%s': not enough arguments\n",gaa_current_option);
519                        return 0;
520                    case GAA_ERROR_INVALID_ARG:
521                        printf("Invalid arguments\n");
522                        return 0;
523                    case GAA_OK:
524                        break;
525                    default:
526                        printf("Unknown error\n");
527                    }
528                }
529                gaa_arg_used[i] = 1;
530                break;
531            default: break;
532            }
533        }
534    }
535if(gaa_processing_file == 0)
536{
537@
538#line 507 "gaa.skel"
539#ifdef GAA_REST_EXISTS
540    switch(gaa_try(GAA_REST, 1, gaaval, opt_list))
541    {
542    case GAA_ERROR_NOTENOUGH_ARGS:
543        printf("Rest: not enough arguments\n");
544        return 0;
545    case GAA_ERROR_INVALID_ARG:
546        printf("Invalid arguments\n");
547        return 0;
548    case GAA_OK:
549        break;
550    default:
551        printf("Unknown error\n");
552    }
553#endif
554}
555    for(i = 1; i < argc; i++)
556    {
557        if(gaa_arg_used[i] == 0)
558        {
559            printf("Too many arguments\n");
560            return 0;
561        }
562    }
563    free(gaa_arg_used);
564    free(opt_list);
565    return -1;
566}
567
568struct gaastrnode
569{
570    char *str;
571    struct gaastrnode *next;
572};
573
574typedef struct gaastrnode gaa_str_node;
575
576static int gaa_internal_get_next_str(FILE *file, gaa_str_node *tmp_str, int argc)
577{
578    int pos_ini;
579    int a;
580    int i = 0, len = 0, newline = 0;
581
582    if(argc == 1) {
583        newline = 1;
584        len = 2;
585    }
586
587    a = fgetc( file);
588    if (a == EOF) return 0;
589
590    while(a == ' ' || a == 9 || a == '\n')
591    {
592        if(a == '\n')
593        {
594            newline=1;
595            len = 2;
596        }
597        a = fgetc( file);
598        if (a == EOF) return 0;
599    }
600
601    pos_ini = ftell(file) - 1;
602
603    while(a != ' ' && a != 9 && a != '\n')
604    {
605
606        len++;
607        a = fgetc( file);
608        if(a==EOF) return 0; //a = ' ';
609    }
610
611    len += 1;
612    tmp_str->str = gaa_malloc((len) * sizeof(char));
613
614    if(newline == 1)
615    {
616        tmp_str->str[0] = '-';
617        tmp_str->str[1] = '-';
618        i = 2;
619    }
620    else
621    {
622        i = 0;
623    }
624
625    fseek(file,pos_ini, SEEK_SET);
626    do
627    {
628        a = fgetc( file);
629
630        if (a == EOF) {
631            i+=2;
632            break;
633        }
634        tmp_str->str[i] = a;
635        i++;
636    }
637    while(a != ' ' && a != 9 && a != '\n' && i < len);
638
639    tmp_str->str[i - 1] = 0;
640
641    fseek(file,- 1, SEEK_CUR);
642/*    printf("%d\n", ftell(file)); */
643
644    return -1;
645}
646
647int gaa_file(const char *name, gaainfo *gaaval)
648{
649    gaa_str_node *first_str, **tmp_str, *tmp_str2;
650    int rval, i;
651    char **argv;
652    int argc = 0;
653    FILE *file;
654
655    gaa_processing_file = 1;
656
657    if((file = fopen(name, "r")) == NULL)
658    {
659        printf("Couldn't open '%s' configuration file for reading\n", name);
660        return 1;
661    }
662
663    tmp_str = &first_str;
664    do
665    {
666        argc++;
667        *tmp_str = gaa_malloc(sizeof(gaa_str_node));
668
669        (*tmp_str)->str = NULL;
670        (*tmp_str)->next = NULL;
671
672        rval = gaa_internal_get_next_str(file, *tmp_str, argc);
673        tmp_str = &((*tmp_str)->next);
674    }
675    while(rval == -1);
676
677    if(rval == 1)
678        return 0;
679
680    argv = gaa_malloc((1 + argc) * sizeof(char*));
681
682    tmp_str2 = first_str;
683    argv[0] = "cfg";
684    for(i = 1; i < argc; i++)
685    {
686        argv[i] = tmp_str2->str;
687        tmp_str2 = tmp_str2->next;
688    }
689
690    rval = gaa(argc, argv, gaaval);
691    gaa_processing_file = 0;
692    return rval;
693}
694@
695
696