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