]> www.fi.muni.cz Git - evince.git/blob - pdf/goo/parseargs.c
new widget: table with labels displaying properties of PDFs
[evince.git] / pdf / goo / parseargs.c
1 /*
2  * parseargs.h
3  *
4  * Command line argument parser.
5  *
6  * Copyright 1996-2002 Glyph & Cog, LLC
7  */
8
9 #include <locale.h>
10 #include <stdio.h>
11 #include <stddef.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <ctype.h>
15 #include "parseargs.h"
16
17 static ArgDesc *findArg(ArgDesc *args, char *arg);
18 static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]);
19
20 GBool parseArgs(ArgDesc *args, int *argc, char *argv[]) {
21   ArgDesc *arg;
22   int i, j;
23   GBool ok;
24
25   ok = gTrue;
26   i = 1;
27   while (i < *argc) {
28     if (!strcmp(argv[i], "--")) {
29       --*argc;
30       for (j = i; j < *argc; ++j)
31         argv[j] = argv[j+1];
32       break;
33     } else if ((arg = findArg(args, argv[i]))) {
34       if (!grabArg(arg, i, argc, argv))
35         ok = gFalse;
36     } else {
37       ++i;
38     }
39   }
40   return ok;
41 }
42
43 void printUsage(char *program, char *otherArgs, ArgDesc *args) {
44   ArgDesc *arg;
45   char *typ;
46   int w, w1;
47
48   w = 0;
49   for (arg = args; arg->arg; ++arg) {
50     if ((w1 = strlen(arg->arg)) > w)
51       w = w1;
52   }
53
54   fprintf(stderr, "Usage: %s [options]", program);
55   if (otherArgs)
56     fprintf(stderr, " %s", otherArgs);
57   fprintf(stderr, "\n");
58
59   for (arg = args; arg->arg; ++arg) {
60     fprintf(stderr, "  %s", arg->arg);
61     w1 = 9 + w - strlen(arg->arg);
62     switch (arg->kind) {
63     case argInt:
64     case argIntDummy:
65       typ = " <int>";
66       break;
67     case argFP:
68     case argFPDummy:
69       typ = " <fp>";
70       break;
71     case argString:
72     case argStringDummy:
73       typ = " <string>";
74       break;
75     case argFlag:
76     case argFlagDummy:
77     default:
78       typ = "";
79       break;
80     }
81     fprintf(stderr, "%-*s", w1, typ);
82     if (arg->usage)
83       fprintf(stderr, ": %s", arg->usage);
84     fprintf(stderr, "\n");
85   }
86 }
87
88 static ArgDesc *findArg(ArgDesc *args, char *arg) {
89   ArgDesc *p;
90
91   for (p = args; p->arg; ++p) {
92     if (p->kind < argFlagDummy && !strcmp(p->arg, arg))
93       return p;
94   }
95   return NULL;
96 }
97
98 static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]) {
99   int n;
100   int j;
101   GBool ok;
102
103   ok = gTrue;
104   n = 0;
105   switch (arg->kind) {
106   case argFlag:
107     *(GBool *)arg->val = gTrue;
108     n = 1;
109     break;
110   case argInt:
111     if (i + 1 < *argc && isInt(argv[i+1])) {
112       *(int *)arg->val = atoi(argv[i+1]);
113       n = 2;
114     } else {
115       ok = gFalse;
116       n = 1;
117     }
118     break;
119   case argFP:
120     if (i + 1 < *argc && isFP(argv[i+1])) {
121       {
122         char *theLocale = setlocale(LC_NUMERIC, "C");
123         *(double *)arg->val = atof(argv[i+1]);
124         setlocale(LC_NUMERIC, theLocale);
125       }
126       n = 2;
127     } else {
128       ok = gFalse;
129       n = 1;
130     }
131     break;
132   case argString:
133     if (i + 1 < *argc) {
134       strncpy((char *)arg->val, argv[i+1], arg->size - 1);
135       ((char *)arg->val)[arg->size - 1] = '\0';
136       n = 2;
137     } else {
138       ok = gFalse;
139       n = 1;
140     }
141     break;
142   default:
143     fprintf(stderr, "Internal error in arg table\n");
144     n = 1;
145     break;
146   }
147   if (n > 0) {
148     *argc -= n;
149     for (j = i; j < *argc; ++j)
150       argv[j] = argv[j+n];
151   }
152   return ok;
153 }
154
155 GBool isInt(char *s) {
156   if (*s == '-' || *s == '+')
157     ++s;
158   while (isdigit(*s))
159     ++s;
160   if (*s)
161     return gFalse;
162   return gTrue;
163 }
164
165 GBool isFP(char *s) {
166   int n;
167
168   if (*s == '-' || *s == '+')
169     ++s;
170   n = 0;
171   while (isdigit(*s)) {
172     ++s;
173     ++n;
174   }
175   if (*s == '.')
176     ++s;
177   while (isdigit(*s)) {
178     ++s;
179     ++n;
180   }
181   if (n > 0 && (*s == 'e' || *s == 'E')) {
182     ++s;
183     if (*s == '-' || *s == '+')
184       ++s;
185     n = 0;
186     if (!isdigit(*s))
187       return gFalse;
188     do {
189       ++s;
190     } while (isdigit(*s));
191   }
192   if (*s)
193     return gFalse;
194   return gTrue;
195 }