1 /*
2    File: options.c
3    Defines flags and parameters of the datastructure generator
4 
5    Copyright (C) 2008 Marc Seutter
6 
7    This program is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 
20    CVS ID: "$Id: options.c,v 1.8 2008/06/28 13:03:45 marcs Exp $"
21 */
22 
23 /* global includes */
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 
28 /* Conditional inclusion to define MAXPATHLEN */
29 #ifndef WIN32
30 #include <sys/param.h>
31 #endif
32 #ifndef MAXPATHLEN
33 #define MAXPATHLEN 256
34 #endif
35 
36 /* libdcg includes */
37 #include <dcg.h>
38 #include <dcg_error.h>
39 #include <dcg_string.h>
40 
41 /* local includes */
42 #include "dcg_code.h"
43 #include "options.h"
44 
45 /* Define VERSION INCPATH and LIBPATH if configure did not do this */
46 #ifndef VERSION
47 #define VERSION "2.14"
48 #endif
49 #ifndef INCPATH
50 #define INCPATH "/home/marcs/include"
51 #endif
52 #ifndef LIBPATH
53 #define LIBPATH "/home/marcs/lib"
54 #endif
55 
56 /* Exported flags */
57 int coding_flag;
58 int saving_flag;
59 int loading_flag;
60 int xformer_flag;
61 int code_transput;
62 int code_rdup;
63 int code_extra_tags;
64 int code_pretty_print;
65 
66 /* Exported parameters and search paths */
67 string_list ex_names;
68 string_list include_path;
69 string xformer_ptype;
70 string xformer_pname;
71 string basic_types;
72 
73 /* Local flags */
74 static int report_version;
75 
76 /*
77    Initialize the options and default search paths
78 */
init_options()79 void init_options ()
80 	{ /* Flags */
81 	  full_verbose = 0;
82 	  verbose = 0;
83 	  debug = 0;
84 	  coding_flag = 1;
85 	  saving_flag = 0;
86 	  loading_flag = 0;
87 	  xformer_flag = 0;
88 	  report_version = 0;
89 	  code_transput = 1;
90 	  code_rdup = 1;
91 	  code_pretty_print = 1;
92 	  code_extra_tags = 0;
93 
94 	  /* Default search paths */
95 	  ex_names = new_string_list ();
96 	  include_path = new_string_list ();
97 	  app_string_list (include_path, new_string (INCPATH));
98 	  app_string_list (include_path, new_string ("."));
99 	  xformer_ptype = NULL;
100 	  xformer_pname = new_string ("xformp");
101 	  basic_types = new_string ("dcg");
102 	};
103 
try_report_version()104 void try_report_version ()
105 	{ if (verbose || report_version)
106 	     wlog ("This is DCG, C version %s, (C) M.Seutter", VERSION);
107 	};
108 
109 /*
110    Comment the usage
111 */
usage()112 static void usage ()
113 	{ error ("Usage: dcg [option...] file[.dcg]");
114 	  error ("where option may be any of the following:");
115 	  error ("   -n: do not code");
116 	  error ("   -v: verbose execution");
117 	  error ("   -s: save internal datastructures");
118 	  error ("   -l: load internal datastructures");
119 	  error ("   -x: generate transformer");
120 	  error ("   -V: give version of dcg");
121 	  error ("   -xt: generate an extra file coding enums and tags only");
122 	  error ("   -nxp: do not code transput routines");
123 	  error ("   -npp: do not code pretty print routines");
124 	  error ("   -nrd: do not code rdup routines");
125 	  error ("   -e name: exclude routine (transformer only)");
126 	  error ("   -I path: add path to include search paths");
127 	  error ("   -xp string: specify transformer parameter type");
128 	  error ("   -xn string: specify transformer routine name");
129 	  error ("   -fv: full verbose execution");
130 	  error ("   -bt name: use name to locate basic system types");
131 	  error ("   -il: output location of mimirs include files");
132 	  error ("   -ll: output location of mimirs library files");
133 	  error ("   -h: show this help");
134 #ifdef DEBUG
135 	  error ("   -d: turn on debugging (when configured)");
136 #endif
137 	  exit (0);
138 	};
139 
syntax_error(char * msg)140 static void syntax_error (char *msg)
141 	{ error ("Syntax error: %s", msg);
142 	  usage ();
143 	};
144 
skip_args(int nr,int pos,int * argc,char ** argv)145 static void skip_args (int nr, int pos, int *argc, char **argv)
146 	{ int i;
147 	  for (i=pos; i < *argc - nr; i++)
148 	     argv[i] = argv[i+nr];
149 	  *argc -= nr;
150 	};
151 
scan_options(int * argc,char ** argv)152 void scan_options (int *argc, char **argv)
153 	{ int i = 0;
154 	  skip_args (1, i, argc, argv);		/* skip command_name */
155 	  while (i < *argc)
156 	     { char *arg = argv[i];
157 	       if (streq (arg, "-n"))
158 		  { coding_flag = 0;
159 		    skip_args (1, i, argc, argv);
160 		  }
161 	       else if (streq (arg, "-v"))
162 		  { verbose = 1;
163 		    skip_args (1, i, argc, argv);
164 		  }
165 	       else if (streq (arg, "-s"))
166 		  { saving_flag = 1;
167 		    skip_args (1, i, argc, argv);
168 		  }
169 	       else if (streq (arg, "-l"))
170 		  { loading_flag = 1;
171 		    skip_args (1, i, argc, argv);
172 		  }
173 	       else if (streq (arg, "-x"))
174 		  { xformer_flag = 1;
175 		    coding_flag = 0;
176 		    skip_args (1, i, argc, argv);
177 		  }
178 	       else if (streq (arg, "-xt"))
179 	          { code_extra_tags = 1;
180 		    skip_args (1, i, argc, argv);
181 		  }
182 	       else if (streq (arg, "-nxp"))
183 		  { code_transput = 0;
184 		    skip_args (1, i, argc, argv);
185 		  }
186 	       else if (streq (arg, "-npp"))
187 		  { code_pretty_print = 0;
188 		    skip_args (1, i, argc, argv);
189 		  }
190 	       else if (streq (arg, "-nrd"))
191 		  { code_rdup = 0;
192 		    skip_args (1, i, argc, argv);
193 		  }
194 	       else if (streq (arg, "-e"))
195 		  { skip_args (1, i, argc, argv);
196 		    if (i < *argc)
197 		       { app_string_list (ex_names, new_string (argv[i]));
198 			 skip_args (1, i, argc, argv);
199 		       }
200 		    else syntax_error ("missing routine name");
201 		  }
202 	       else if (streq (arg, "-xp"))
203 		  { skip_args (1, i, argc, argv);
204 		    if (i < *argc)
205 		       { xformer_ptype = new_string (argv[i]);
206 			 skip_args (1, i, argc, argv);
207 		       }
208 		    else syntax_error ("missing transformer parameter type");
209 		  }
210 	       else if (streq (arg, "-xn"))
211 		  { skip_args (1, i, argc, argv);
212 		    if (i < *argc)
213 		       { xformer_pname = new_string (argv[i]);
214 			 skip_args (1, i, argc, argv);
215 		       }
216 		    else
217 		       syntax_error ("missing transformer routine name prefix");
218 	          }
219 	       else if (streq (arg, "-bt"))
220 		  { skip_args (1, i, argc, argv);
221 		    if (i < *argc)
222 		       { basic_types = new_string (argv[i]);
223 			 skip_args (1, i, argc, argv);
224 		       }
225 		    else syntax_error ("missing basic types name");
226 		  }
227 	       else if ((arg[0] == '-') && (arg[1] == 'I'))
228 		  { if (arg[2]) ins_string_list (include_path, 0, new_string (arg + 2));
229 		    else
230 		       { skip_args (1, i, argc, argv);
231 		         if (i < *argc)
232 		            ins_string_list (include_path, 0, new_string (argv[i]));
233 		         else syntax_error ("missing include path");
234 		       };
235 		    skip_args (1, i, argc, argv);
236 		  }
237 	       else if (streq (arg, "-V"))
238 		  { report_version = 1;
239 		    skip_args (1, i, argc, argv);
240 		  }
241 	       else if (streq (arg, "-d"))
242 		  { debug = 1;
243 		    skip_args (1, i, argc, argv);
244 		  }
245 	       else if (streq (arg, "-fv"))
246 		  { full_verbose = 1;
247 		    verbose = 1;
248 		    skip_args (1, i, argc, argv);
249 		  }
250 	       else if (streq (arg, "-il"))
251 		  { fprintf (stdout, "%s\n", INCPATH);
252 		    exit (0);
253 		  }
254 	       else if (streq (arg, "-ll"))
255 		  { fprintf (stdout, "%s\n", LIBPATH);
256 		    exit (0);
257 		  }
258 	       else if (streq (arg, "-h")) usage ();
259 	       else if (arg[0] == '-') syntax_error ("unknown option");
260 	       else i++;
261 	     }
262 	};
263 
scan_basename(int argc,char ** argv,char * basename)264 void scan_basename (int argc, char **argv, char *basename)
265 	{ int len;
266 	  if (argc == 0)
267 	     { if (report_version) try_report_version ();
268 	       else syntax_error ("missing argument");
269 	       exit (0);
270 	     }
271 	  else if (argc > 2) syntax_error ("too many arguments");
272 	  len = strlen (argv[0]);
273 	  if (len > MAXPATHLEN-4) syntax_error ("too long argument");
274 	  strcpy (basename, argv[0]);
275 	  if (len < 3) return;
276 	  if (strcmp (basename + len - 4, ".dcg") == 0)
277 	     basename [len - 4] = '\0';
278 	};
279