fix crashes reported by Debian Cylab Mayhem Team
[swftools.git] / lib / args.h
blobc0350e4a0ecc88d6d07c55d18f7393150da61bb8
1 /* args.h
2 Routines to simplify argument handling
4 Part of the swftools package.
6 Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
22 #ifndef __args_h__
23 #define __args_h__
25 #ifndef NO_ARGPARSER
27 extern int args_callback_option(char*,char*);
28 extern int args_callback_longoption(char*,char*);
29 extern int args_callback_command(char*,char*);
30 extern void args_callback_usage(char*name);
32 //int argn;
33 //char**argv;
35 static void processargs(int argn2,char**argv2)
37 int t;
38 if(argn2==1)
40 args_callback_usage(argv2[0]);
41 exit(1);
43 for(t=1;t<argn2;t++)
45 char*next;
46 if(t<argn2-1) next=argv2[t+1];
47 else next=0;
49 if(argv2[t][0]=='-' && argv2[t][1])
51 if(argv2[t][1]=='-')
53 if(!strcmp(&argv2[t][2],"help"))
55 args_callback_usage(argv2[0]);
56 exit(1);
58 t+=args_callback_longoption(&argv2[t][2],next);
60 else
62 if(strchr("?h",argv2[t][1]))
64 args_callback_usage(argv2[0]);
65 exit(1);
67 if(argv2[t][1]) // this might be something like e.g. -xvf
69 char buf[2];
70 int s=1;
71 int ret;
72 buf[1]=0;
73 do{
74 if(argv2[t][s+1]) {
75 buf[0] = argv2[t][s];
76 ret = args_callback_option(buf,&argv2[t][s+1]);
78 else {
79 t+= args_callback_option(&argv2[t][s], next);
80 break;
82 s++;
83 } while(!ret);
87 else
89 int num = args_callback_command(argv2[t],next);
90 if(num>2) {
91 fprintf(stderr, "internal error in command line parsing\n");
92 exit(1);
94 t+=num;
99 struct options_t
101 const char*shortoption;
102 const char*longoption;
105 static int args_long2shortoption(struct options_t*options, char*name, char*val)
107 char*equal = strchr(name,'=');
108 if (equal) {
109 *equal = 0;
110 equal++;
112 while(options->shortoption) {
113 if(!strcmp(options->longoption, name)) {
114 char*tmp = (char*)malloc(strlen(options->shortoption)
115 +(equal?strlen(equal)+2:2));
116 strcpy(tmp, options->shortoption);
117 if(equal) {
118 //strcpy(&tmp[strlen(tmp)], equal);
119 int ret = args_callback_option(tmp, equal);
120 if(!ret) {
121 fprintf(stderr, "Warning: Option --%s takes no parameter.\n", name);
123 return 0;
125 return args_callback_option(tmp,val);
127 options++;
129 fprintf(stderr, "Unknown option: --%s\n", name);
130 exit(1);
133 #endif
135 /* check whether the value t is in a given range.
136 examples: 3 is in range 1-10: true
137 7 is in range 2-4,6,8-10: false
138 9 is in range 1,2,3-12: true
140 static char is_in_range(int t, char*irange)
142 char*pos = irange;
143 char*digits;
144 int num;
145 char range = 0;
146 int last=0;
147 char tmp;
149 if(!irange) // no range resembles (-OO,OO)
150 return 1;
152 while(*pos)
154 while(*pos == ' ' || *pos == '\r' || *pos == '\n' || *pos == '\t')
155 pos++;
157 digits = pos;
158 while(*digits>='0' && *digits<='9')
159 digits++;
160 if(digits == pos) {
161 fprintf(stderr, "Error: \"%s\" is not a valid format (digit expected)\n",irange);
162 exit(1);
165 tmp=*digits;*digits=0;
166 num = atoi(pos);
167 *digits=tmp;
168 pos = digits;
170 while(*pos == ' ' || *pos == '\r' || *pos == '\n' || *pos == '\t')
171 pos++;
173 if(range && last<=t && num>=t)
174 return 1;
175 if(range) {
176 range = 0;
177 if(*pos)
178 pos ++;
179 continue;
182 if(*pos=='-')
184 if(range) {
185 fprintf(stderr, "Error: \"%s\" is not a valid format (too many '-'s)\n",irange);
186 exit(1);
188 last = num;
189 range = 1;
190 if(*pos)
191 pos ++;
192 continue;
194 else
196 /* if it isn't a '-', we assume it is a seperator like
197 ',', ';', ':', whatever. */
198 if(t == num)
199 return 1;
200 if(*pos)
201 pos ++;
202 continue;
205 if(range && last<=t)
206 return 1;
207 return 0;
210 static char* filename2template(char*filename, int*startindex)
212 int l = strlen(filename);
213 char*newname = (char*)malloc(l+5);
214 /* first look whether the file is already numbered */
215 while(1) {
216 l--;
217 if(l<0 || strchr("0123456789", filename[l]))
218 break;
220 if(l>=0) {
221 int lastdigit=l;
222 int firstdigit=l;
223 while(firstdigit && strchr("0123456789", filename[firstdigit-1]))
224 firstdigit--;
225 *startindex = atoi(filename+firstdigit);
226 memcpy(newname, filename, firstdigit);
227 sprintf(newname+firstdigit, "%%%dd", lastdigit+1-firstdigit);
228 strcat(newname+firstdigit, filename+lastdigit+1);
229 return newname;
231 /* if it isn't, try to paste a %d between filename and extension */
232 char*dot = strrchr(filename, '.');
233 if(dot) {
234 int pos = dot-filename;
235 memcpy(newname, filename, pos);
236 newname[pos++] = '.';
237 newname[pos++] = '%';
238 newname[pos++] = 'd';
239 strcpy(newname+pos, dot);
240 *startindex = 1;
241 return newname;
243 /* if that didn't work either, just append the number at the end */
244 strcpy(newname, filename);
245 strcat(newname, ".%d");
246 *startindex = 1;
247 return newname;
250 #endif //__args_h__