1 /*
2 Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7 
8 Redistributions of source code must retain the above copyright notice, this list of
9 conditions and the following disclaimer. Redistributions in binary form must reproduce
10 the above copyright notice, this list of conditions and the following disclaimer
11 in the documentation and/or other materials provided with the distribution.
12 
13 Neither the name of the Johns Hopkins University nor the names of its contributors
14 may be used to endorse or promote products derived from this software without specific
15 prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES
19 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
20 SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
22 TO, PROCUREMENT OF SUBSTITUTE  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26 DAMAGE.
27 */
28 
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <assert.h>
34 #include "CmdLineParser.h"
35 
36 
37 #ifdef _WIN32
strcasecmp(char * c1,char * c2)38 int strcasecmp(char* c1,char* c2){return _stricmp(c1,c2);}
39 #endif
40 
cmdLineReadable(const char * name)41 cmdLineReadable::cmdLineReadable(const char* name)
42 {
43 	set=false;
44 	this->name=new char[strlen(name)+1];
45 	strcpy(this->name,name);
46 }
~cmdLineReadable(void)47 cmdLineReadable::~cmdLineReadable(void)
48 {
49 	if(name) delete[] name;
50 	name=NULL;
51 }
read(char **,int)52 int cmdLineReadable::read(char**,int){
53 	set=true;
54 	return 0;
55 }
writeValue(char * str)56 void cmdLineReadable::writeValue(char* str)
57 {
58 	str[0] = 0;
59 }
60 
61 ////////////////
62 // cmdLineInt //
63 ////////////////
cmdLineInt(const char * name)64 cmdLineInt::cmdLineInt(const char* name) : cmdLineReadable(name) {value=0;}
cmdLineInt(const char * name,const int & v)65 cmdLineInt::cmdLineInt(const char* name,const int& v) : cmdLineReadable(name) {value=v;}
read(char ** argv,int argc)66 int cmdLineInt::read(char** argv,int argc){
67 	if(argc>0){
68 		value=atoi(argv[0]);
69 		set=true;
70 		return 1;
71 	}
72 	else{return 0;}
73 }
writeValue(char * str)74 void cmdLineInt::writeValue(char* str)
75 {
76 	sprintf(str,"%d",value);
77 }
78 
79 //////////////////
80 // cmdLineFloat //
81 //////////////////
cmdLineFloat(const char * name)82 cmdLineFloat::cmdLineFloat(const char* name) : cmdLineReadable(name) {value=0;}
cmdLineFloat(const char * name,const float & v)83 cmdLineFloat::cmdLineFloat(const char* name, const float& v) : cmdLineReadable(name) {value=v;}
read(char ** argv,int argc)84 int cmdLineFloat::read(char** argv,int argc){
85 	if(argc>0){
86 		value=(float)atof(argv[0]);
87 		set=true;
88 		return 1;
89 	}
90 	else{return 0;}
91 }
writeValue(char * str)92 void cmdLineFloat::writeValue(char* str)
93 {
94 	sprintf(str,"%f",value);
95 }
96 
97 ///////////////////
98 // cmdLineString //
99 ///////////////////
cmdLineString(const char * name)100 cmdLineString::cmdLineString(const char* name) : cmdLineReadable(name) {value=NULL;}
~cmdLineString(void)101 cmdLineString::~cmdLineString(void)
102 {
103 	if(value)	delete[] value;
104 	value=NULL;
105 }
read(char ** argv,int argc)106 int cmdLineString::read(char** argv,int argc){
107 	if(argc>0)
108 	{
109 		value=new char[strlen(argv[0])+1];
110 		strcpy(value,argv[0]);
111 		set=true;
112 		return 1;
113 	}
114 	else{return 0;}
115 }
writeValue(char * str)116 void cmdLineString::writeValue(char* str)
117 {
118 	sprintf(str,"%s",value);
119 }
120 
121 ////////////////////
122 // cmdLineStrings //
123 ////////////////////
cmdLineStrings(const char * name,int Dim)124 cmdLineStrings::cmdLineStrings(const char* name,int Dim) : cmdLineReadable(name)
125 {
126 	this->Dim=Dim;
127 	values=new char*[Dim];
128 	for(int i=0;i<Dim;i++)	values[i]=NULL;
129 }
~cmdLineStrings(void)130 cmdLineStrings::~cmdLineStrings(void)
131 {
132 	for(int i=0;i<Dim;i++)
133 	{
134 		if(values[i])	delete[] values[i];
135 		values[i]=NULL;
136 	}
137 	delete[] values;
138 	values=NULL;
139 }
read(char ** argv,int argc)140 int cmdLineStrings::read(char** argv,int argc)
141 {
142 	if(argc>=Dim)
143 	{
144 		for(int i=0;i<Dim;i++)
145 		{
146 			values[i]=new char[strlen(argv[i])+1];
147 			strcpy(values[i],argv[i]);
148 		}
149 		set=true;
150 		return Dim;
151 	}
152 	else	return 0;
153 }
writeValue(char * str)154 void cmdLineStrings::writeValue(char* str)
155 {
156 	char* temp=str;
157 	for(int i=0;i<Dim;i++)
158 	{
159 		sprintf(temp,"%s ",values[i]);
160 		temp=str+strlen(str);
161 	}
162 }
163 
164 
GetFileExtension(char * fileName)165 char* GetFileExtension(char* fileName){
166 	char* fileNameCopy;
167 	char* ext=NULL;
168 	char* temp;
169 
170 	fileNameCopy=new char[strlen(fileName)+1];
171 	assert(fileNameCopy);
172 	strcpy(fileNameCopy,fileName);
173 	temp=strtok(fileNameCopy,".");
174 	while(temp!=NULL)
175 	{
176 		if(ext!=NULL){delete[] ext;}
177 		ext=new char[strlen(temp)+1];
178 		assert(ext);
179 		strcpy(ext,temp);
180 		temp=strtok(NULL,".");
181 	}
182 	delete[] fileNameCopy;
183 	return ext;
184 }
GetLocalFileName(char * fileName)185 char* GetLocalFileName(char* fileName){
186 	char* fileNameCopy;
187 	char* name=NULL;
188 	char* temp;
189 
190 	fileNameCopy=new char[strlen(fileName)+1];
191 	assert(fileNameCopy);
192 	strcpy(fileNameCopy,fileName);
193 	temp=strtok(fileNameCopy,"\\");
194 	while(temp!=NULL){
195 		if(name!=NULL){delete[] name;}
196 		name=new char[strlen(temp)+1];
197 		assert(name);
198 		strcpy(name,temp);
199 		temp=strtok(NULL,"\\");
200 	}
201 	delete[] fileNameCopy;
202 	return name;
203 }
204 
cmdLineParse(int argc,char ** argv,int num,cmdLineReadable ** readable,int dumpError)205 void cmdLineParse(int argc, char **argv,int num,cmdLineReadable** readable,int dumpError)
206 {
207 	int i,j;
208 	while (argc > 0)
209 	{
210 		if (argv[0][0] == '-' && argv[0][1]=='-')
211 		{
212 			for(i=0;i<num;i++)
213 			{
214 				if (!strcmp(&argv[0][2],readable[i]->name))
215 				{
216 					argv++, argc--;
217 					j=readable[i]->read(argv,argc);
218 					argv+=j,argc-=j;
219 					break;
220 				}
221 			}
222 			if(i==num){
223 				if(dumpError)
224 				{
225 					fprintf(stderr, "invalid option: %s\n",*argv);
226 					fprintf(stderr, "possible options are:\n");
227 					for(i=0;i<num;i++)	fprintf(stderr, "  %s\n",readable[i]->name);
228 				}
229 				argv++, argc--;
230 			}
231 		}
232 		else
233 		{
234 			if(dumpError)
235 			{
236 				fprintf(stderr, "invalid option: %s\n", *argv);
237 				fprintf(stderr, "  options must start with a \'--\'\n");
238 			}
239 			argv++, argc--;
240 		}
241 	}
242 }
ReadWords(const char * fileName,int & cnt)243 char** ReadWords(const char* fileName,int& cnt)
244 {
245 	char** names;
246 	char temp[500];
247 	FILE* fp;
248 
249 	fp=fopen(fileName,"r");
250 	if(!fp){return NULL;}
251 	cnt=0;
252 	while(fscanf(fp," %s ",temp)==1){cnt++;}
253 	fclose(fp);
254 
255 	names=new char*[cnt];
256 	if(!names){return NULL;}
257 
258 	fp=fopen(fileName,"r");
259 	if(!fp){
260 		delete[] names;
261 		cnt=0;
262 		return NULL;
263 	}
264 	cnt=0;
265 	while(fscanf(fp," %s ",temp)==1){
266 		names[cnt]=new char[strlen(temp)+1];
267 		if(!names){
268 			for(int j=0;j<cnt;j++){delete[] names[j];}
269 			delete[] names;
270 			cnt=0;
271 			fclose(fp);
272 			return NULL;
273 		}
274 		strcpy(names[cnt],temp);
275 		cnt++;
276 	}
277 	fclose(fp);
278 	return names;
279 }
280