CoMD
A Mini-app for Co-Design of Classical Molecular Dynamics.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
cmdLineParser.c
Go to the documentation of this file.
1 /// \file
2 /// A parser for command line arguments.
3 ///
4 /// A general purpose command line parser that uses getopt_long() to parse
5 /// the command line.
6 ///
7 /// \author Sriram Swaminarayan
8 /// \date July 24, 2007
9 
10 #include "cmdLineParser.h"
11 
12 #include <stdio.h>
13 #include <getopt.h>
14 #include <string.h>
15 
16 #include "mytype.h"
17 #include "memUtils.h"
18 
19 #define nextOption(o) ((MyOption*) o->next)
20 
21 typedef struct MyOptionSt
22 {
23  char* help;
24  char* longArg;
25  unsigned char shortArg[2];
26  int argFlag;
27  char type;
28  int sz;
29  void* ptr;
30  void* next;
31 } MyOption;
32 
33 static int longest = 1;
34 static MyOption* myargs=NULL;
35 
36 static char* dupString(const char* s)
37 {
38  char* d;
39  if ( ! s ) s = "";
40  d = (char*)comdCalloc((strlen(s)+1),sizeof(char));
41  strcpy(d, s);
42  return d;
43 }
44 
46  const char* longOption, const char shortOption,
47  int has_arg, const char type, void* dataPtr, int dataSize, const char* help)
48 {
49  static int iBase=129;
50  MyOption* o = (MyOption*)comdCalloc(1, sizeof(MyOption));
51  o->help = dupString(help);
52  o->longArg = dupString(longOption);
53  if(shortOption) o->shortArg[0] = (unsigned char)shortOption;
54  else
55  {
56  o->shortArg[0] = iBase;
57  iBase++;
58  }
59  o->argFlag = has_arg;
60  o->type = type;
61  o->ptr = dataPtr;
62  o->sz = dataSize;
63  if(longOption) longest = (longest>strlen(longOption)?longest:strlen(longOption));
64  return o;
65 }
66 
68 {
69  MyOption* r;
70  if(!o) return NULL;
71  r = nextOption(o);
72  if(o->longArg)free(o->longArg);
73  if(o->help)free(o->help);
74  free(o);
75  return r;
76 }
77 
79 {
80  if ( ! o) return o;
81  while(nextOption(o)) o = nextOption(o);
82  return o;
83 }
84 
85 static MyOption* findOption(MyOption* o, unsigned char shortArg)
86 {
87  while(o)
88  {
89  if (o->shortArg[0] == shortArg) return o;
90  o = nextOption(o);
91  }
92  return o;
93 }
94 
95 
96 int addArg(const char* longOption, const char shortOption,
97  int has_arg, const char type, void* dataPtr, int dataSize,
98  const char* help)
99 {
100  MyOption* o;
101  MyOption* p;
102  o = myOptionAlloc(longOption,shortOption,has_arg,type,dataPtr,dataSize, help);
103  if ( ! o ) return 1;
104  if ( ! myargs) myargs = o;
105  else
106  {
107  p = lastOption(myargs);
108  p->next = (void *)o;
109  }
110  return 0;
111 }
112 
113 
114 void freeArgs()
115 {
116  while(myargs)
117  {
118  myargs = myOptionFree(myargs);
119  }
120  return;
121 }
122 
123 void printArgs()
124 {
125  MyOption* o = myargs;
126  char s[4096];
127  unsigned char *shortArg;
128  fprintf(screenOut,"\n"
129  " Arguments are: \n");
130  sprintf(s," --%%-%ds",longest);
131  while(o)
132  {
133  if(o->shortArg[0]<0xFF) shortArg = o->shortArg;
134  else shortArg = (unsigned char *) "---";
135  fprintf(screenOut,s,o->longArg);
136  fprintf(screenOut," -%c arg=%1d type=%c %s\n",shortArg[0],o->argFlag,o->type,o->help);
137  o = nextOption(o);
138 
139  }
140  fprintf(screenOut,"\n\n");
141  return;
142 }
143 
144 void processArgs(int argc, char** argv)
145 {
146  MyOption* o;
147  int n=0;
148  int i;
149  struct option* opts;
150  char* sArgs;
151  int c;
152 
153  if ( ! myargs) return;
154  o = myargs;
155  while(o)
156  {n++,o=nextOption(o);}
157 
158  o = myargs;
159  sArgs= (char*)comdCalloc(2*(n+2),sizeof(char));
160  opts = (struct option*)comdCalloc(n,sizeof(struct option));
161  for (i=0; i<n; i++)
162  {
163  opts[i].name = o->longArg;
164  opts[i].has_arg = o->argFlag;
165  opts[i].flag = 0;
166  opts[i].val = o->shortArg[0];
167 
168  strcat(sArgs,(char*) o->shortArg);
169  if(o->argFlag) strcat(sArgs,":");
170  o = nextOption(o);
171  }
172 
173  while(1)
174  {
175 
176  int option_index = 0;
177 
178  c = getopt_long (argc, argv, sArgs, opts, &option_index);
179  if ( c == -1) break;
180  o = findOption(myargs,c);
181  if ( ! o )
182  {
183  fprintf(screenOut,"\n\n"
184  " invalid switch : -%c in getopt()\n"
185  "\n\n",
186  c);
187  break;
188  }
189  if(! o->argFlag)
190  {
191  int* i = (int*)o->ptr;
192  *i = 1;
193  }
194  else
195  {
196  switch(o->type)
197  {
198  case 'i':
199  sscanf(optarg,"%d",(int*)o->ptr);
200  break;
201  case 'f':
202  sscanf(optarg,"%f",(float*)o->ptr);
203  break;
204  case 'd':
205  sscanf(optarg,"%lf",(double*)o->ptr);
206  break;
207  case 's':
208  strncpy((char*)o->ptr,(char*)optarg,o->sz);
209  ((char*)o->ptr)[o->sz-1] = '\0';
210  break;
211  case 'c':
212  sscanf(optarg,"%c",(char*)o->ptr);
213  break;
214  default:
215  fprintf(screenOut,"\n\n"
216  " invalid type : %c in getopt()\n"
217  " valid values are 'e', 'z'. 'i','d','f','s', and 'c'\n"
218  "\n\n",
219  c);
220  }
221  }
222  }
223 
224  free(opts);
225  free(sArgs);
226 
227  return;
228 }