tomwalters@0
|
1 /*
|
tomwalters@0
|
2 Copyright (c) Applied Psychology Unit, Medical Research Council. 1988, 1989
|
tomwalters@0
|
3 ===========================================================================
|
tomwalters@0
|
4
|
tomwalters@0
|
5 Permission to use, copy, modify, and distribute this software without fee
|
tomwalters@0
|
6 is hereby granted for research purposes, provided that this copyright
|
tomwalters@0
|
7 notice appears in all copies and in all supporting documentation, and that
|
tomwalters@0
|
8 the software is not redistributed for any fee (except for a nominal shipping
|
tomwalters@0
|
9 charge). Anyone wanting to incorporate all or part of this software in a
|
tomwalters@0
|
10 commercial product must obtain a license from the Medical Research Council.
|
tomwalters@0
|
11
|
tomwalters@0
|
12 The MRC makes no representations about the suitability of this
|
tomwalters@0
|
13 software for any purpose. It is provided "as is" without express or implied
|
tomwalters@0
|
14 warranty.
|
tomwalters@0
|
15
|
tomwalters@0
|
16 THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
tomwalters@0
|
17 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE
|
tomwalters@0
|
18 A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
|
tomwalters@0
|
19 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
tomwalters@0
|
20 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
tomwalters@0
|
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
tomwalters@0
|
22 */
|
tomwalters@0
|
23
|
tomwalters@0
|
24 /* -------------------------------------------------------------------------------
|
tomwalters@0
|
25
|
tomwalters@0
|
26 The Leanest Resource Manager in the West.
|
tomwalters@0
|
27
|
tomwalters@0
|
28 Options may be supplied as defaults (actually in the code), as command line
|
tomwalters@0
|
29 arguments, and in a option file. The default arguments may be overridden by
|
tomwalters@0
|
30 the option-file contents, which may be overridden from the command line.
|
tomwalters@0
|
31
|
tomwalters@0
|
32 Copyright (c), 1989 The Medical Research Council of the United Kingdom.
|
tomwalters@0
|
33
|
tomwalters@0
|
34 Author : Paul Manson
|
tomwalters@0
|
35 Written : March 1st 1989
|
tomwalters@0
|
36
|
tomwalters@0
|
37 Edited :
|
tomwalters@0
|
38
|
tomwalters@0
|
39 2nd March 1989 (Paul Manson) Added the facility of searching the HOME directory
|
tomwalters@0
|
40 for a option file if one is not found in the
|
tomwalters@0
|
41 working directory.
|
tomwalters@0
|
42
|
tomwalters@0
|
43 8th March 1989 (Paul Manson) Enhanced the above by providing a OPTIONPATH
|
tomwalters@0
|
44 search strategy for Unix. Currently MSDOS only
|
tomwalters@0
|
45 searches for a option file in the directory
|
tomwalters@0
|
46 where the program was found.
|
tomwalters@0
|
47
|
tomwalters@0
|
48 8th March 1989 (Paul Manson) Added the ability to refer to options via
|
tomwalters@0
|
49 abbreviations of their names. At present, an abbrev.
|
tomwalters@0
|
50 will match if it is exactly the same as precisely one
|
tomwalters@0
|
51 option, or if it is the same as the first <n> chars
|
tomwalters@0
|
52 of that option (where <n> is the length of the
|
tomwalters@0
|
53 abbrev) and it matches no other option name.
|
tomwalters@0
|
54
|
tomwalters@0
|
55 9th March 1989 (Paul Manson) Added the readopts and writeopts calls, to implement
|
tomwalters@0
|
56 option headers for files. Also altered the form
|
tomwalters@0
|
57 of command line options accepted: See getopts.h for
|
tomwalters@0
|
58 details.
|
tomwalters@0
|
59
|
tomwalters@0
|
60 10th March 1989 (Paul Manson) Added the "help" facility to provide a simple
|
tomwalters@0
|
61 self-documentation facility. Also altered the
|
tomwalters@0
|
62 Option type to put defaults and comments in
|
tomwalters@0
|
63 the code.
|
tomwalters@0
|
64
|
tomwalters@0
|
65 16th March 1989 (Paul Manson) Altered the final argc/argv shuffling in getopts
|
tomwalters@0
|
66 so that argv simply points at the first argument
|
tomwalters@0
|
67 after the options. Also added fileopts.
|
tomwalters@0
|
68
|
tomwalters@0
|
69 29th March 1989 (Paul Manson) Altered ".res" to ".opt" to coincide with the new
|
tomwalters@0
|
70 naming r'egime. Also added the spitOptionsFile call
|
tomwalters@0
|
71 to automatically produce an options file with
|
tomwalters@0
|
72 comments. To enable this facility, compile getopts
|
tomwalters@0
|
73 with -DSPITHELP; to use it, type <prog> -spit. Do
|
tomwalters@0
|
74 NOT distribute a spitting version of getopts! Altered
|
tomwalters@0
|
75 Options-file scanning to permit trailing comments.
|
tomwalters@0
|
76
|
tomwalters@0
|
77 30th March 1989 (Paul Manson) Completely eradicated the blockWriteToFile used by
|
tomwalters@0
|
78 writenopts. This is now done on a non-aligned basis,
|
tomwalters@0
|
79 as this is likely to be quicker and less complex.
|
tomwalters@0
|
80
|
tomwalters@0
|
81 03rd April 1989 (Paul Manson) Added the calll to outputopt.
|
tomwalters@0
|
82
|
tomwalters@0
|
83 06th April 1989 (Paul Manson) Oh Joy! Oh Bliss! The once-much-maligned SPIT option
|
tomwalters@0
|
84 is recieved into decent society, albeit in the guise
|
tomwalters@0
|
85 of an options "editor" called 'update'.
|
tomwalters@0
|
86
|
tomwalters@0
|
87 10th April 1989 (Paul Manson) The 'update' option no longer exit(1)s, but
|
tomwalters@0
|
88 carries on to execute the program. Also changed
|
tomwalters@0
|
89 OptionFileName so that it correctly gets the
|
tomwalters@0
|
90 cwd on the PC.
|
tomwalters@0
|
91
|
tomwalters@0
|
92 11th April 1989 (Paul Manson) Altered the OptionFileName routines to be EITHER
|
tomwalters@0
|
93 for the PC or for Unix.
|
tomwalters@0
|
94
|
tomwalters@0
|
95 26th April 1989 (Paul Manson) Put in a temporary delta to the PC version so that it
|
tomwalters@0
|
96 only looks for option files (and hence only creates
|
tomwalters@0
|
97 option files) in the current directory. This will be
|
tomwalters@0
|
98 abandoned when we determine a better search strategy.
|
tomwalters@0
|
99
|
tomwalters@0
|
100 15th June 1989 (Paul Manson) Altered SilentOption so that it is alterable, but is
|
tomwalters@0
|
101 NOT visible in any way (ie. not printed by help or
|
tomwalters@0
|
102 spit, and not output to headers).
|
tomwalters@0
|
103
|
tomwalters@0
|
104 11th July 1989 (Paul Manson) Altered so that "help" (and "update") only display
|
tomwalters@0
|
105 (or output) the options which were either read in
|
tomwalters@0
|
106 from the options file, or have been subsequently
|
tomwalters@0
|
107 altered on the command line. The current implementation
|
tomwalters@0
|
108 simply checks to see whether the default and current
|
tomwalters@0
|
109 values for a particular option differ (either in value
|
tomwalters@0
|
110 OR address!).
|
tomwalters@0
|
111
|
tomwalters@0
|
112 27th July 1989 (Paul Manson) Altered so that isON == !isOFF, and not the other way
|
tomwalters@0
|
113 around -- this allows "2", "3", etc to masquerade as
|
tomwalters@0
|
114 "1" while only "0" is "off". Also changed so that no
|
tomwalters@0
|
115 quotes are output to file headers.
|
tomwalters@0
|
116
|
tomwalters@0
|
117
|
tomwalters@0
|
118 July 1994 (MAA) Allowed spaces in strings, by adding double-quotes
|
tomwalters@0
|
119 to the arguments. Bit of a hack, though.
|
tomwalters@0
|
120 ------------------------------------------------------------------------------- */
|
tomwalters@0
|
121
|
tomwalters@0
|
122 #include "options.h"
|
tomwalters@0
|
123 #include <stdio.h>
|
tomwalters@0
|
124 #include <string.h>
|
tomwalters@0
|
125 #if defined( NeXT)
|
tomwalters@0
|
126 #include <stdlib.h>
|
tomwalters@0
|
127 #else
|
tomwalters@0
|
128 #include <malloc.h>
|
tomwalters@0
|
129 #endif
|
tomwalters@0
|
130 #include <ctype.h>
|
tomwalters@0
|
131
|
tomwalters@0
|
132 #if !defined( lint )
|
tomwalters@0
|
133 static char *sccs_id = "@(#)options.c 1.14 Paul Manson (MRC-APU) 5/2/89";
|
tomwalters@0
|
134 #endif
|
tomwalters@0
|
135
|
tomwalters@0
|
136 char defversion[64] = "not set yet" , *versionstr = defversion ;
|
tomwalters@0
|
137
|
tomwalters@0
|
138 #if defined( PC )
|
tomwalters@0
|
139 #include <direct.h>
|
tomwalters@0
|
140 #define DOT '.'
|
tomwalters@0
|
141 #define BACKSLASH_CHAR '\\'
|
tomwalters@0
|
142 #define SLASH_CHARACTER '/'
|
tomwalters@0
|
143 #define OPTION_FILE_PREFIX ""
|
tomwalters@0
|
144 #define OPTION_FILE_SUFFIX ".opt"
|
tomwalters@0
|
145 #else
|
tomwalters@0
|
146 #ifndef THINK_C
|
tomwalters@0
|
147 #include <sys/types.h>
|
tomwalters@0
|
148 #include <sys/stat.h>
|
tomwalters@0
|
149 #endif
|
tomwalters@0
|
150 #define OPTION_FILE_PREFIX "."
|
tomwalters@0
|
151 #define OPTION_FILE_SUFFIX "rc"
|
tomwalters@0
|
152 #define OPTION_PATH "OPTIONSPATH"
|
tomwalters@0
|
153 /* Environment variable for path */
|
tomwalters@0
|
154 #define DEFAULT_OPTION_PATH "."
|
tomwalters@0
|
155 /* Path is first . then ~ (ie home) */
|
tomwalters@0
|
156 #endif
|
tomwalters@0
|
157
|
tomwalters@0
|
158 #define MAX_LINE_LENGTH (256)
|
tomwalters@0
|
159 #define MAX_NAME_LENGTH (128)
|
tomwalters@0
|
160 #define FALSE (0)
|
tomwalters@0
|
161 #define TRUE (1)
|
tomwalters@0
|
162 #define HYPHEN_CHARACTER '-'
|
tomwalters@0
|
163 #define BLANK_CHARACTER ' '
|
tomwalters@0
|
164 #define TAB_CHARACTER '\t'
|
tomwalters@0
|
165 #define NEWLINE_CHARACTER '\n'
|
tomwalters@0
|
166 #define DOUBLE_QUOTE_CHAR '\"'
|
tomwalters@0
|
167 #define ERROR_RESULT (1234)
|
tomwalters@0
|
168 #define EQUALS_CHARACTER '='
|
tomwalters@0
|
169 #define COMMENT_CHARACTER '#'
|
tomwalters@0
|
170 #define NULL_CHARACTER '\000'
|
tomwalters@0
|
171 #define CARRIAGE_RETURN '\r'
|
tomwalters@0
|
172
|
tomwalters@0
|
173 /* Options-specific definitions for "ON", "OFF" and "NULL" */
|
tomwalters@0
|
174
|
tomwalters@0
|
175 #define ON_STRING (ON_OPTION)
|
tomwalters@0
|
176 #define ON_ALIAS "1"
|
tomwalters@0
|
177
|
tomwalters@0
|
178 #define OFF_STRING (OFF_OPTION)
|
tomwalters@0
|
179 #define OFF_ALIAS "0"
|
tomwalters@0
|
180
|
tomwalters@0
|
181 #define NULL_STRING (NULL_OPTION)
|
tomwalters@0
|
182 #define NULL_ALIAS "null"
|
tomwalters@0
|
183
|
tomwalters@0
|
184 #define NOT_USED "Not_used"
|
tomwalters@0
|
185
|
tomwalters@0
|
186 /* For the search_path and Ambiguity procedures */
|
tomwalters@0
|
187
|
tomwalters@0
|
188 #define LINE_CHARS 200
|
tomwalters@0
|
189 #define AMBIGUOUS (-2)
|
tomwalters@0
|
190 #define NO_MATCH (-1)
|
tomwalters@0
|
191 #define DEFAULT_TOGGLE_VALUE (ON_STRING)
|
tomwalters@0
|
192
|
tomwalters@0
|
193 /* For the readopts and writeopts procedures */
|
tomwalters@0
|
194
|
tomwalters@0
|
195 #define OPTION_HEADER_SIZE ( sizeof ( head_string_start ) - 1 + size_digits + 1 )
|
tomwalters@0
|
196 #define OPTION_HEADER_HEADER "header_bytes="
|
tomwalters@0
|
197 #define OPTION_HEADER_DIGITS (7)
|
tomwalters@0
|
198
|
tomwalters@0
|
199 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
|
tomwalters@0
|
200
|
tomwalters@0
|
201 static char OptionHeaderHeader[] = OPTION_HEADER_HEADER;
|
tomwalters@0
|
202 static char LineFeedArray[] = "\n";
|
tomwalters@0
|
203 static char EqualsArray[] = "="; /* Was " = " */
|
tomwalters@0
|
204 static char QuotesArray[] = "\"";
|
tomwalters@0
|
205
|
tomwalters@0
|
206 /* For the OnLine Help Facility */
|
tomwalters@0
|
207
|
tomwalters@0
|
208 #define HELP_STRING "help"
|
tomwalters@0
|
209 #define UPDATE_STRING "update"
|
tomwalters@0
|
210 #define ALL_STRING "all"
|
tomwalters@0
|
211
|
tomwalters@0
|
212 static int helpOnAllRequired = FALSE;
|
tomwalters@0
|
213 static int helpOnOneRequired = FALSE;
|
tomwalters@0
|
214 static int helpOnOneLocation = 0;
|
tomwalters@0
|
215 static int updateAllRequired = FALSE;
|
tomwalters@0
|
216
|
tomwalters@0
|
217 extern void exit();
|
tomwalters@0
|
218 static int thereWasAnOptionsFile = FALSE;
|
tomwalters@0
|
219 static char *theOptionFileName = NULL;
|
tomwalters@0
|
220
|
tomwalters@0
|
221
|
tomwalters@0
|
222
|
tomwalters@0
|
223
|
tomwalters@0
|
224 #ifndef PC
|
tomwalters@0
|
225 /* -----------------------------------------------------------------------
|
tomwalters@0
|
226
|
tomwalters@0
|
227 search_path( file, path )
|
tomwalters@0
|
228 =========================
|
tomwalters@0
|
229
|
tomwalters@0
|
230 jwh - 4th jan 1987
|
tomwalters@0
|
231
|
tomwalters@0
|
232 searches through string path for file and returns full file name if it
|
tomwalters@0
|
233 finds it. Returns NULL if file is not found. Path is specified in normal
|
tomwalters@0
|
234 path format i.e. "dir1:dir2:dir3...". Works for "~" and "~/dir.." -
|
tomwalters@0
|
235 substitutes HOME for "~". ~ only works for current user!!
|
tomwalters@0
|
236
|
tomwalters@0
|
237 ----------------------------------------------------------------------- */
|
tomwalters@0
|
238
|
tomwalters@0
|
239
|
tomwalters@0
|
240 static char *search_path( file, path )
|
tomwalters@0
|
241 char *file, *path ;
|
tomwalters@0
|
242 {
|
tomwalters@0
|
243 #ifdef THINK_C
|
tomwalters@0
|
244 return ( file ) ;
|
tomwalters@0
|
245 #else
|
tomwalters@0
|
246 char file_name[ LINE_CHARS ] ;
|
tomwalters@0
|
247 int len_next ;
|
tomwalters@0
|
248 struct stat buf ;
|
tomwalters@0
|
249 extern getenv();
|
tomwalters@0
|
250 char *home_directory = (char *)getenv("HOME");
|
tomwalters@0
|
251
|
tomwalters@0
|
252 if( file[ 0 ] == '/' || file[ 0 ] == '.' && file[ 1 ] == '/' )
|
tomwalters@0
|
253 return ( strcpy( malloc((unsigned)(strlen(file) + 1)), file) );
|
tomwalters@0
|
254
|
tomwalters@0
|
255 do
|
tomwalters@0
|
256 {
|
tomwalters@0
|
257 len_next = ( strchr( path, ':' ) == NULL ) ?
|
tomwalters@0
|
258 strlen( path ) : strchr( path, ':' ) - path ;
|
tomwalters@0
|
259
|
tomwalters@0
|
260 if( *path == '~' )
|
tomwalters@0
|
261 {
|
tomwalters@0
|
262 (void) strcpy( file_name, home_directory ) ;
|
tomwalters@0
|
263 (void) strncpy( file_name + strlen( home_directory ), path+1,
|
tomwalters@0
|
264 len_next-1 ) ;
|
tomwalters@0
|
265 (void) sprintf( file_name + strlen( home_directory ) + len_next - 1 ,
|
tomwalters@0
|
266 "/%s", file ) ;
|
tomwalters@0
|
267 }
|
tomwalters@0
|
268 else
|
tomwalters@0
|
269 {
|
tomwalters@0
|
270 (void) strncpy( file_name, path, len_next ) ;
|
tomwalters@0
|
271 (void) sprintf( file_name + len_next , "/%s", file ) ;
|
tomwalters@0
|
272 }
|
tomwalters@0
|
273
|
tomwalters@0
|
274 if( stat( file_name, &buf ) >= 0 && ( buf.st_mode & S_IFDIR ) == 0 )
|
tomwalters@0
|
275 return ( strcpy( malloc((unsigned)(strlen(file_name) + 1)), file_name) );
|
tomwalters@0
|
276
|
tomwalters@0
|
277 path = path + len_next + 1 ;
|
tomwalters@0
|
278 }
|
tomwalters@0
|
279 while( path[ -1 ] != '\0' ) ;
|
tomwalters@0
|
280
|
tomwalters@0
|
281 /* return( NULL ) ; */ return( file ); /* If PATH is NULL, return FILE */
|
tomwalters@0
|
282 #endif
|
tomwalters@0
|
283 }
|
tomwalters@0
|
284
|
tomwalters@0
|
285 /* ---------------------------------------------------------------------------------
|
tomwalters@0
|
286
|
tomwalters@0
|
287 Return the Option File Name, given the Name of the Application (Unix Version)
|
tomwalters@0
|
288
|
tomwalters@0
|
289 Edited:
|
tomwalters@0
|
290
|
tomwalters@0
|
291 --------------------------------------------------------------------------------- */
|
tomwalters@0
|
292 char *UnixOptionFileName(appn)
|
tomwalters@0
|
293 char *appn ;
|
tomwalters@0
|
294 {
|
tomwalters@0
|
295 char *temp;
|
tomwalters@0
|
296
|
tomwalters@0
|
297 temp = malloc((unsigned) (strlen(appn) + strlen(OPTION_FILE_SUFFIX) +
|
tomwalters@0
|
298 strlen(OPTION_FILE_PREFIX) + 1));
|
tomwalters@0
|
299
|
tomwalters@0
|
300 temp = strcpy(temp,OPTION_FILE_PREFIX);
|
tomwalters@0
|
301 temp = strcat(temp,appn);
|
tomwalters@0
|
302 temp = strcat(temp,OPTION_FILE_SUFFIX);
|
tomwalters@0
|
303
|
tomwalters@0
|
304
|
tomwalters@0
|
305 return (temp);
|
tomwalters@0
|
306 }
|
tomwalters@0
|
307 #endif /* Unix Option File Stuff */
|
tomwalters@0
|
308
|
tomwalters@0
|
309 #if defined( PC )
|
tomwalters@0
|
310
|
tomwalters@0
|
311 /* ---------------------------------------------------------------------------------
|
tomwalters@0
|
312
|
tomwalters@0
|
313 Return the Option File Name, given the Name of the Application (PC Version)
|
tomwalters@0
|
314
|
tomwalters@0
|
315 Edited:
|
tomwalters@0
|
316
|
tomwalters@0
|
317 --------------------------------------------------------------------------------- */
|
tomwalters@0
|
318 char *PCOptionFileName(appn, onlyLocal)
|
tomwalters@0
|
319 char *appn ;
|
tomwalters@0
|
320 int onlyLocal;
|
tomwalters@0
|
321 {
|
tomwalters@0
|
322 char *temp;
|
tomwalters@0
|
323 int i ;
|
tomwalters@0
|
324 char *temp2, *lastPart;
|
tomwalters@0
|
325
|
tomwalters@0
|
326
|
tomwalters@0
|
327 temp = malloc((unsigned) (strlen(appn) + strlen(OPTION_FILE_SUFFIX) +
|
tomwalters@0
|
328 strlen(OPTION_FILE_PREFIX) + 1));
|
tomwalters@0
|
329
|
tomwalters@0
|
330 temp = strcpy(temp, appn);
|
tomwalters@0
|
331
|
tomwalters@0
|
332 for (i = 0; temp[i] != NULL_CHARACTER; i++)
|
tomwalters@0
|
333 if (temp[i] == BACKSLASH_CHAR)
|
tomwalters@0
|
334 temp[i] = SLASH_CHARACTER;
|
tomwalters@0
|
335
|
tomwalters@0
|
336 /* Strip Back to the Application Name */
|
tomwalters@0
|
337 if ((lastPart = strrchr(temp, SLASH_CHARACTER)) == NULL)
|
tomwalters@0
|
338 lastPart = temp;
|
tomwalters@0
|
339 else
|
tomwalters@0
|
340 lastPart++; /* Skip over the actual "/" */
|
tomwalters@0
|
341
|
tomwalters@0
|
342 /* lastPart points to the tail name of the path */
|
tomwalters@0
|
343
|
tomwalters@0
|
344 if ((temp2 = strchr(lastPart,DOT)) == NULL)
|
tomwalters@0
|
345 temp = strcat(temp,OPTION_FILE_SUFFIX);
|
tomwalters@0
|
346 else
|
tomwalters@0
|
347 temp2 = strcpy(temp2, OPTION_FILE_SUFFIX);
|
tomwalters@0
|
348
|
tomwalters@0
|
349 if (onlyLocal) /* Remove the full path to give only a local name */
|
tomwalters@0
|
350 return( lastPart);
|
tomwalters@0
|
351 else
|
tomwalters@0
|
352 return (temp);
|
tomwalters@0
|
353 }
|
tomwalters@0
|
354 #endif /* PC Version of OptionFileName */
|
tomwalters@0
|
355
|
tomwalters@0
|
356
|
tomwalters@0
|
357 /* ---------------------------------------------------------------------------------
|
tomwalters@0
|
358
|
tomwalters@0
|
359 Check that there is no ambiguity in the (possibly abbreviated) <name>. If there is
|
tomwalters@0
|
360 no match whatever, return NO_MATCH. If there is a single exact match, or a single
|
tomwalters@0
|
361 abbreviating match, return the index of the matched option; otherwise return
|
tomwalters@0
|
362 AMBIGUOUS.
|
tomwalters@0
|
363
|
tomwalters@0
|
364 --------------------------------------------------------------------------------- */
|
tomwalters@0
|
365 int Ambiguity(options, numOptions, name)
|
tomwalters@0
|
366 Option options[] ;
|
tomwalters@0
|
367 int numOptions;
|
tomwalters@0
|
368 char *name ;
|
tomwalters@0
|
369 {
|
tomwalters@0
|
370 int i, matched, matchedExactly, matchedWhere, moreThanOneInexactMatch;
|
tomwalters@0
|
371
|
tomwalters@0
|
372 matched = FALSE;
|
tomwalters@0
|
373 matchedExactly = FALSE;
|
tomwalters@0
|
374 moreThanOneInexactMatch = FALSE;
|
tomwalters@0
|
375
|
tomwalters@0
|
376 for (i = 0; i < numOptions; i++)
|
tomwalters@0
|
377 if (options[i].classification != OutputOption &&
|
tomwalters@0
|
378 strncmp(name, options[i].name, strlen(name)) == 0) {
|
tomwalters@0
|
379 if (matched) {
|
tomwalters@0
|
380 if (matchedExactly) {
|
tomwalters@0
|
381 if (strcmp(name, options[i].name) == 0) {
|
tomwalters@0
|
382 /* TWO Exact Matches */
|
tomwalters@0
|
383 return AMBIGUOUS;
|
tomwalters@0
|
384 }
|
tomwalters@0
|
385 }
|
tomwalters@0
|
386 else {
|
tomwalters@0
|
387 if (strcmp(name, options[i].name) == 0) {
|
tomwalters@0
|
388 /* THIS is an exact match */
|
tomwalters@0
|
389 matchedExactly = TRUE;
|
tomwalters@0
|
390 matchedWhere = i;
|
tomwalters@0
|
391 }
|
tomwalters@0
|
392 else {
|
tomwalters@0
|
393 /* There are two inexact matches ... if there are no exact ones we
|
tomwalters@0
|
394 have AMBIGUITY */
|
tomwalters@0
|
395 moreThanOneInexactMatch = TRUE;
|
tomwalters@0
|
396 }
|
tomwalters@0
|
397 }
|
tomwalters@0
|
398 }
|
tomwalters@0
|
399 else {
|
tomwalters@0
|
400 if (strcmp(name, options[i].name) == 0) {
|
tomwalters@0
|
401 /* This is an exact match */
|
tomwalters@0
|
402 matchedExactly = TRUE;
|
tomwalters@0
|
403 }
|
tomwalters@0
|
404 matched = TRUE;
|
tomwalters@0
|
405 matchedWhere = i ;
|
tomwalters@0
|
406 }
|
tomwalters@0
|
407 }
|
tomwalters@0
|
408
|
tomwalters@0
|
409 if (moreThanOneInexactMatch)
|
tomwalters@0
|
410 return (AMBIGUOUS);
|
tomwalters@0
|
411 else {
|
tomwalters@0
|
412 if (matched)
|
tomwalters@0
|
413 return (matchedWhere);
|
tomwalters@0
|
414 else
|
tomwalters@0
|
415 return (NO_MATCH);
|
tomwalters@0
|
416 }
|
tomwalters@0
|
417
|
tomwalters@0
|
418 }
|
tomwalters@0
|
419
|
tomwalters@0
|
420
|
tomwalters@0
|
421 /* ---------------------------------------------------------------------------------
|
tomwalters@0
|
422
|
tomwalters@0
|
423 Search for the named option in the list of options. If it is found, return its
|
tomwalters@0
|
424 location (index) in the options array. Otherwise, return NO_MATCH.
|
tomwalters@0
|
425
|
tomwalters@0
|
426 --------------------------------------------------------------------------------- */
|
tomwalters@0
|
427 int LookUp(options, numOptions, name)
|
tomwalters@0
|
428 Option options[] ;
|
tomwalters@0
|
429 int numOptions;
|
tomwalters@0
|
430 char *name ;
|
tomwalters@0
|
431 {
|
tomwalters@0
|
432 int i;
|
tomwalters@0
|
433
|
tomwalters@0
|
434 for (i = 0; i < numOptions; i++)
|
tomwalters@0
|
435 if (options[i].classification != OutputOption && strcmp(name, options[i].name) == 0) {
|
tomwalters@0
|
436 return (i);
|
tomwalters@0
|
437 }
|
tomwalters@0
|
438
|
tomwalters@0
|
439 return (NO_MATCH);
|
tomwalters@0
|
440
|
tomwalters@0
|
441 }
|
tomwalters@0
|
442
|
tomwalters@0
|
443 extern helpRoutine *onLineHelpHandler;
|
tomwalters@0
|
444 extern void updateOptionsFile();
|
tomwalters@0
|
445
|
tomwalters@0
|
446 /* ---------------------------------------------------------------------------------
|
tomwalters@0
|
447
|
tomwalters@0
|
448 Search for the named option in the list of options. If it is found, set its
|
tomwalters@0
|
449 new value as indicated and return TRUE. If not, return either FALSE or AMBIGUOUS.
|
tomwalters@0
|
450
|
tomwalters@0
|
451 Edited:
|
tomwalters@0
|
452
|
tomwalters@0
|
453 8th March 1989 (Paul Manson) Changed the call to LookUp to call Ambiguity instead,
|
tomwalters@0
|
454 thus achieving the matching of abbreviated options.
|
tomwalters@0
|
455
|
tomwalters@0
|
456 15th March 1989 (Paul Manson) Reinstated the call to LookUp in the case that
|
tomwalters@0
|
457 abbreviations (and hence ambiguity) are/is not
|
tomwalters@0
|
458 permitted (ie. in option Header Files).
|
tomwalters@0
|
459
|
tomwalters@0
|
460 --------------------------------------------------------------------------------- */
|
tomwalters@0
|
461 int LookUpAndStore(options, numOptions, name, value, permitAbbrevs, programName)
|
tomwalters@0
|
462 Option options[] ;
|
tomwalters@0
|
463 int numOptions ;
|
tomwalters@0
|
464 char *name, *value;
|
tomwalters@0
|
465 int permitAbbrevs;
|
tomwalters@0
|
466 char *programName ;
|
tomwalters@0
|
467 {
|
tomwalters@0
|
468 int loc ;
|
tomwalters@0
|
469 char *temp;
|
tomwalters@0
|
470
|
tomwalters@0
|
471 /* Account for specific references to the "help" option, with different
|
tomwalters@0
|
472 treatment of the "help=all" command */
|
tomwalters@0
|
473 if (strcmp(name, HELP_STRING) == 0) {
|
tomwalters@0
|
474 /* Check whether it is asking for ALL help */
|
tomwalters@0
|
475 if (strcmp(value, ALL_STRING) == 0) {
|
tomwalters@0
|
476 helpOnAllRequired = TRUE;
|
tomwalters@0
|
477 helpOnOneRequired = FALSE;
|
tomwalters@0
|
478 (*onLineHelpHandler)(options, numOptions, programName);
|
tomwalters@0
|
479 exit(0);
|
tomwalters@0
|
480 }
|
tomwalters@0
|
481 /* Check for other specific kinds of help request */
|
tomwalters@0
|
482 /* else if (strcmp(value, _STRING) == 0) { */
|
tomwalters@0
|
483
|
tomwalters@0
|
484
|
tomwalters@0
|
485 else {
|
tomwalters@0
|
486 /* Expand the (possibly abbreviated) option name */
|
tomwalters@0
|
487 if ((permitAbbrevs && ((loc = Ambiguity(options, numOptions, value)) >= 0)) ||
|
tomwalters@0
|
488 (!permitAbbrevs && ((loc = LookUp(options, numOptions, value)) >= 0))) {
|
tomwalters@0
|
489 helpOnOneRequired = TRUE;
|
tomwalters@0
|
490 helpOnAllRequired = FALSE;
|
tomwalters@0
|
491 helpOnOneLocation = loc ;
|
tomwalters@0
|
492 (*onLineHelpHandler)(options, numOptions, programName);
|
tomwalters@0
|
493 exit(0);
|
tomwalters@0
|
494 }
|
tomwalters@0
|
495 else {
|
tomwalters@0
|
496 if (loc == AMBIGUOUS) {
|
tomwalters@0
|
497 (void) fprintf(stderr, "WARNING: The option name %s is AMBIGUOUS; please be more specific.\n", value);
|
tomwalters@0
|
498 exit(1);
|
tomwalters@0
|
499 }
|
tomwalters@0
|
500 else {
|
tomwalters@0
|
501 (void) fprintf(stderr, "WARNING: The %s program does not have an option named %s.\n",
|
tomwalters@0
|
502 programName, value);
|
tomwalters@0
|
503 exit(1);
|
tomwalters@0
|
504 }
|
tomwalters@0
|
505 }
|
tomwalters@0
|
506 }
|
tomwalters@0
|
507 }
|
tomwalters@0
|
508 else if (strcmp(name, UPDATE_STRING) == 0) {
|
tomwalters@0
|
509 /* Check whether it is asking for ALL updated */
|
tomwalters@0
|
510 if (strcmp(value, ALL_STRING) == 0) {
|
tomwalters@0
|
511 updateAllRequired = TRUE ;
|
tomwalters@0
|
512 updateOptionsFile(options, numOptions, programName, theOptionFileName);
|
tomwalters@0
|
513 updateAllRequired = FALSE;
|
tomwalters@0
|
514 helpOnAllRequired = TRUE ;
|
tomwalters@0
|
515 helpOnOneRequired = FALSE;
|
tomwalters@0
|
516 return (TRUE);
|
tomwalters@0
|
517 }
|
tomwalters@0
|
518 else {
|
tomwalters@0
|
519 /* At present there is no use for a specific update call */
|
tomwalters@0
|
520 (void) fprintf(stderr, "options: The update option may not be altered!\n");
|
tomwalters@0
|
521 exit(1);
|
tomwalters@0
|
522 }
|
tomwalters@0
|
523 }
|
tomwalters@0
|
524 else if ((permitAbbrevs && ((loc = Ambiguity(options, numOptions, name)) >= 0)) ||
|
tomwalters@0
|
525 (!permitAbbrevs && ((loc = LookUp(options, numOptions, name)) >= 0))) {
|
tomwalters@0
|
526 /* It is a conventional "LookUpAndStore" operation */
|
tomwalters@0
|
527 temp = malloc((unsigned)(strlen(value) + 1));
|
tomwalters@0
|
528 temp = strcpy(temp, value);
|
tomwalters@0
|
529 *(options[loc].value) = temp;
|
tomwalters@0
|
530 return (TRUE);
|
tomwalters@0
|
531 }
|
tomwalters@0
|
532 else {
|
tomwalters@0
|
533 if (loc == AMBIGUOUS) {
|
tomwalters@0
|
534 #if defined( PC )
|
tomwalters@0
|
535 (void) fprintf(stderr,
|
tomwalters@0
|
536 "ERROR: The name %s is AMBIGUOUS, and the value %s has not been assigned to any option\n", name, value);
|
tomwalters@0
|
537 exit(1);
|
tomwalters@0
|
538 #else
|
tomwalters@0
|
539 (void) fprintf(stderr,
|
tomwalters@0
|
540 "WARNING: The name %s is AMBIGUOUS, and the value %s has not been assigned to any option\n", name, value);
|
tomwalters@0
|
541 return (AMBIGUOUS);
|
tomwalters@0
|
542 #endif
|
tomwalters@0
|
543 }
|
tomwalters@0
|
544 else
|
tomwalters@0
|
545 return (FALSE);
|
tomwalters@0
|
546 }
|
tomwalters@0
|
547
|
tomwalters@0
|
548
|
tomwalters@0
|
549 }
|
tomwalters@0
|
550
|
tomwalters@0
|
551
|
tomwalters@0
|
552 /* ---------------------------------------------------------------------------------
|
tomwalters@0
|
553
|
tomwalters@0
|
554 Skip Blanks and Tabs. Stop at a printable character or a newline or null.
|
tomwalters@0
|
555
|
tomwalters@0
|
556 --------------------------------------------------------------------------------- */
|
tomwalters@0
|
557 char *skipBlanks (ptr)
|
tomwalters@0
|
558 char *ptr;
|
tomwalters@0
|
559 {
|
tomwalters@0
|
560 while ((*ptr == BLANK_CHARACTER) || (*ptr == TAB_CHARACTER)) ptr++;
|
tomwalters@0
|
561
|
tomwalters@0
|
562 return (ptr);
|
tomwalters@0
|
563 }
|
tomwalters@0
|
564
|
tomwalters@0
|
565
|
tomwalters@0
|
566 /* ---------------------------------------------------------------------------------
|
tomwalters@0
|
567
|
tomwalters@0
|
568 Ensure that the next character is an '='. If it is, return a pointer to the first
|
tomwalters@0
|
569 character after the '='; otherwise, return NULL.
|
tomwalters@0
|
570
|
tomwalters@0
|
571 --------------------------------------------------------------------------------- */
|
tomwalters@0
|
572 char *skipEquals (ptr)
|
tomwalters@0
|
573 char *ptr;
|
tomwalters@0
|
574 {
|
tomwalters@0
|
575 if (ptr[0] == EQUALS_CHARACTER)
|
tomwalters@0
|
576 return (++ptr);
|
tomwalters@0
|
577 else
|
tomwalters@0
|
578 return (NULL);
|
tomwalters@0
|
579 }
|
tomwalters@0
|
580
|
tomwalters@0
|
581
|
tomwalters@0
|
582 /* ---------------------------------------------------------------------------------
|
tomwalters@0
|
583
|
tomwalters@0
|
584 Read a name (ie. a token, a contiguous sequence of nonblank characters, or a
|
tomwalters@0
|
585 quoted string) from the string pointed to by ptr, and copy it the buffer pointed
|
tomwalters@0
|
586 to by <name>. If successful, return a pointer to the character after the token;
|
tomwalters@0
|
587 otherwise, return NULL.
|
tomwalters@0
|
588
|
tomwalters@0
|
589 --------------------------------------------------------------------------------- */
|
tomwalters@0
|
590 char *getName (ptr, name)
|
tomwalters@0
|
591 char *ptr, *name;
|
tomwalters@0
|
592 {
|
tomwalters@0
|
593 char *temp, *i, *namePtr;
|
tomwalters@0
|
594 char stopChar;
|
tomwalters@0
|
595
|
tomwalters@0
|
596 if (ptr[0] == DOUBLE_QUOTE_CHAR) {
|
tomwalters@0
|
597 ptr++;
|
tomwalters@0
|
598 stopChar = DOUBLE_QUOTE_CHAR;
|
tomwalters@0
|
599 }
|
tomwalters@0
|
600 else
|
tomwalters@0
|
601 stopChar = BLANK_CHARACTER;
|
tomwalters@0
|
602
|
tomwalters@0
|
603 temp = ptr;
|
tomwalters@0
|
604
|
tomwalters@0
|
605 while (*temp != NULL_CHARACTER &&
|
tomwalters@0
|
606 *temp != NEWLINE_CHARACTER &&
|
tomwalters@0
|
607 *temp != CARRIAGE_RETURN &&
|
tomwalters@0
|
608 ((stopChar == DOUBLE_QUOTE_CHAR && *temp != stopChar) ||
|
tomwalters@0
|
609 (stopChar == BLANK_CHARACTER &&
|
tomwalters@0
|
610 (*temp != stopChar && *temp != TAB_CHARACTER && *temp != EQUALS_CHARACTER))))
|
tomwalters@0
|
611 temp++;
|
tomwalters@0
|
612
|
tomwalters@0
|
613 if (stopChar == DOUBLE_QUOTE_CHAR && *temp != DOUBLE_QUOTE_CHAR) {
|
tomwalters@0
|
614 (void) fprintf(stderr, "options: Improperly closed quoted string %s\n", --ptr);
|
tomwalters@0
|
615 return (NULL);
|
tomwalters@0
|
616 }
|
tomwalters@0
|
617
|
tomwalters@0
|
618 namePtr = name;
|
tomwalters@0
|
619
|
tomwalters@0
|
620 for (i = ptr; i < temp; )
|
tomwalters@0
|
621 *namePtr++ = *i++;
|
tomwalters@0
|
622
|
tomwalters@0
|
623 *namePtr = NULL_CHARACTER;
|
tomwalters@0
|
624
|
tomwalters@0
|
625 if (stopChar == DOUBLE_QUOTE_CHAR)
|
tomwalters@0
|
626 temp++;
|
tomwalters@0
|
627
|
tomwalters@0
|
628
|
tomwalters@0
|
629 return (temp);
|
tomwalters@0
|
630
|
tomwalters@0
|
631 }
|
tomwalters@0
|
632
|
tomwalters@0
|
633
|
tomwalters@0
|
634 /* ------------------------------------------------------------------------------
|
tomwalters@0
|
635
|
tomwalters@0
|
636 Read lines from the specified file, updating option settings as appropriate.
|
tomwalters@0
|
637
|
tomwalters@0
|
638 Edits: 29th March 1989 (Paul Manson) Altered so that trailing comments allowed.
|
tomwalters@0
|
639
|
tomwalters@0
|
640 ------------------------------------------------------------------------------ */
|
tomwalters@0
|
641 void processOptionFile (options, numOptions, OptionFile, theOptionFileName,
|
tomwalters@0
|
642 limitedChars, checkOptions, programName)
|
tomwalters@0
|
643 Option options[] ;
|
tomwalters@0
|
644 int numOptions ;
|
tomwalters@0
|
645 FILE *OptionFile ;
|
tomwalters@0
|
646 char *theOptionFileName;
|
tomwalters@0
|
647 int limitedChars ;
|
tomwalters@0
|
648 int checkOptions ;
|
tomwalters@0
|
649 char *programName ;
|
tomwalters@0
|
650 {
|
tomwalters@0
|
651 int result ;
|
tomwalters@0
|
652 char name[MAX_NAME_LENGTH] ;
|
tomwalters@0
|
653 char value[MAX_NAME_LENGTH] ;
|
tomwalters@0
|
654 char *line, *linePtr;
|
tomwalters@0
|
655 int maxCharsToRead ;
|
tomwalters@0
|
656 int totalCharsRead ;
|
tomwalters@0
|
657
|
tomwalters@0
|
658 result = EOF;
|
tomwalters@0
|
659 totalCharsRead = 0 ;
|
tomwalters@0
|
660 line = malloc((unsigned) MAX_LINE_LENGTH + 1);
|
tomwalters@0
|
661
|
tomwalters@0
|
662 maxCharsToRead = ((limitedChars) ? (min(MAX_LINE_LENGTH, limitedChars)) :
|
tomwalters@0
|
663 MAX_LINE_LENGTH);
|
tomwalters@0
|
664
|
tomwalters@0
|
665 while (maxCharsToRead > 0 && ((line = fgets(line, maxCharsToRead + 1,
|
tomwalters@0
|
666 OptionFile)) != NULL)) {
|
tomwalters@0
|
667
|
tomwalters@0
|
668 if (line[0] == NULL_CHARACTER)
|
tomwalters@0
|
669 break; /* In the case of a Option Header */
|
tomwalters@0
|
670 else
|
tomwalters@0
|
671 if (limitedChars) {
|
tomwalters@0
|
672 totalCharsRead += strlen(line);
|
tomwalters@0
|
673 maxCharsToRead = min(MAX_LINE_LENGTH, limitedChars - totalCharsRead);
|
tomwalters@0
|
674 }
|
tomwalters@0
|
675
|
tomwalters@0
|
676 linePtr = skipBlanks(line);
|
tomwalters@0
|
677
|
tomwalters@0
|
678 /* Check for Comments and Blank Lines */
|
tomwalters@0
|
679 if ((linePtr[0] == COMMENT_CHARACTER) ||
|
tomwalters@0
|
680 (linePtr[0] == NEWLINE_CHARACTER) ||
|
tomwalters@0
|
681 (linePtr[0] == CARRIAGE_RETURN ) ||
|
tomwalters@0
|
682 (linePtr[0] == NULL_CHARACTER))
|
tomwalters@0
|
683 continue;
|
tomwalters@0
|
684
|
tomwalters@0
|
685 if ((linePtr = getName(linePtr, name)) == NULL) {
|
tomwalters@0
|
686 (void) fprintf(stderr, "options: Missing or Invalid name\n");
|
tomwalters@0
|
687 result = ERROR_RESULT;
|
tomwalters@0
|
688 break;
|
tomwalters@0
|
689 }
|
tomwalters@0
|
690 linePtr = skipBlanks(linePtr);
|
tomwalters@0
|
691 if ((linePtr = skipEquals(linePtr)) == NULL) {
|
tomwalters@0
|
692 (void) fprintf(stderr, "options: Expected an '=' after the name %s\n", name);
|
tomwalters@0
|
693 result = ERROR_RESULT;
|
tomwalters@0
|
694 break;
|
tomwalters@0
|
695 }
|
tomwalters@0
|
696 linePtr = skipBlanks(linePtr);
|
tomwalters@0
|
697 if ((linePtr = getName(linePtr, value)) == NULL) {
|
tomwalters@0
|
698 (void) fprintf(stderr,
|
tomwalters@0
|
699 "options: Missing or Invalid value; name is %s\n", name);
|
tomwalters@0
|
700 result = ERROR_RESULT;
|
tomwalters@0
|
701 break;
|
tomwalters@0
|
702 }
|
tomwalters@0
|
703 linePtr = skipBlanks(linePtr);
|
tomwalters@0
|
704 if ((*linePtr != NEWLINE_CHARACTER) &&
|
tomwalters@0
|
705 (*linePtr != NULL_CHARACTER) &&
|
tomwalters@0
|
706 (*linePtr != COMMENT_CHARACTER) &&
|
tomwalters@0
|
707 (*linePtr != CARRIAGE_RETURN)) {
|
tomwalters@0
|
708 (void) fprintf(stderr,
|
tomwalters@0
|
709 "options: Detected Trailing Garbage in the line %s = %s\n",
|
tomwalters@0
|
710 name, value);
|
tomwalters@0
|
711 result = ERROR_RESULT;
|
tomwalters@0
|
712 break;
|
tomwalters@0
|
713 }
|
tomwalters@0
|
714
|
tomwalters@0
|
715 if (!LookUpAndStore(options, numOptions, name, value, checkOptions, programName) &&
|
tomwalters@0
|
716 checkOptions) {
|
tomwalters@0
|
717 (void) fprintf(stderr, "options: Could not find Option Called %s\n",
|
tomwalters@0
|
718 name);
|
tomwalters@0
|
719 result = ERROR_RESULT;
|
tomwalters@0
|
720 break;
|
tomwalters@0
|
721 }
|
tomwalters@0
|
722
|
tomwalters@0
|
723 }
|
tomwalters@0
|
724
|
tomwalters@0
|
725 if (result != EOF) {
|
tomwalters@0
|
726 (void) fprintf(stderr,"options: Error reading the Option File %s\n",
|
tomwalters@0
|
727 theOptionFileName);
|
tomwalters@0
|
728 (void) fprintf(stderr,"options: Remainder of File is as follows;\n");
|
tomwalters@0
|
729 (void) fputs(line, stderr);
|
tomwalters@0
|
730 while ((line = fgets(line, MAX_LINE_LENGTH, OptionFile)) != NULL)
|
tomwalters@0
|
731 (void) fputs(line, stderr);
|
tomwalters@0
|
732 exit(1);
|
tomwalters@0
|
733 }
|
tomwalters@0
|
734 }
|
tomwalters@0
|
735
|
tomwalters@0
|
736
|
tomwalters@0
|
737 /* ------------------------------------------------------------------------------
|
tomwalters@0
|
738
|
tomwalters@0
|
739 OnLine Help Facility. This is simply the default handler which is to be called
|
tomwalters@0
|
740 if the user specifies no replacement handler.
|
tomwalters@0
|
741
|
tomwalters@0
|
742 ------------------------------------------------------------------------------ */
|
tomwalters@0
|
743 static void defaultHelpHandler(options, numOptions, progName)
|
tomwalters@0
|
744 Option options[] ;
|
tomwalters@0
|
745 int numOptions;
|
tomwalters@0
|
746 char *progName ;
|
tomwalters@0
|
747 {
|
tomwalters@0
|
748 register int help, res;
|
tomwalters@0
|
749
|
tomwalters@0
|
750 if (helpOnOneRequired) {
|
tomwalters@0
|
751 res = helpOnOneLocation;
|
tomwalters@0
|
752 (void) fprintf(stdout, "%-13s %-9s %-9s %s\n", options[res].name,
|
tomwalters@0
|
753 ((*(options[res].value) == NULL) ? ("") : (*(options[res].value))),
|
tomwalters@0
|
754 ((options[res].defaultValue == NULL) ? ("") : (options[res].defaultValue)),
|
tomwalters@0
|
755 ((options[res].comment == NULL) ? ("") : (options[res].comment)));
|
tomwalters@0
|
756 return;
|
tomwalters@0
|
757 }
|
tomwalters@0
|
758
|
tomwalters@0
|
759 help = -1;
|
tomwalters@0
|
760 for (res = 0; res < numOptions; res++)
|
tomwalters@0
|
761 if (strcmp(options[res].name, HELP_STRING) == 0) {
|
tomwalters@0
|
762 help = res;
|
tomwalters@0
|
763 break ;
|
tomwalters@0
|
764 };
|
tomwalters@0
|
765
|
tomwalters@0
|
766
|
tomwalters@0
|
767 /************* Print head of help menu *****************/
|
tomwalters@0
|
768 if (help < 0) {
|
tomwalters@0
|
769 (void) fprintf(stdout, "The Rotter who wrote the `%s' program hasn't provided any \n",
|
tomwalters@0
|
770 progName);
|
tomwalters@0
|
771 (void) fprintf(stdout, "form of on-line 'help' documentation, tsk tsk!\n\n");
|
tomwalters@0
|
772 (void) fprintf(stdout,
|
tomwalters@0
|
773 "We can, however, provide you with the list of available options:\n\n");
|
tomwalters@0
|
774 }
|
tomwalters@0
|
775 else {
|
tomwalters@0
|
776
|
tomwalters@0
|
777 (void)fprintf(stdout,"%s\n", versionstr);
|
tomwalters@0
|
778 (void) fprintf(stdout,
|
tomwalters@0
|
779 "Usage: %s [options] %s\n\n", progName, options[help].comment);
|
tomwalters@0
|
780 }
|
tomwalters@0
|
781
|
tomwalters@0
|
782 (void) fprintf(stdout, "Option Name Current Default Comment\n");
|
tomwalters@0
|
783 (void) fprintf(stdout, "----------- ------- ------- -------\n");
|
tomwalters@0
|
784
|
tomwalters@0
|
785 for (res = numOptions-1 ; res >= 0 ; res-- )
|
tomwalters@0
|
786 if (options[res].classification < OutputOption &&
|
tomwalters@0
|
787 (!thereWasAnOptionsFile || helpOnAllRequired ||
|
tomwalters@0
|
788 strcmp(*(options[res].value), options[res].defaultValue) != 0 ||
|
tomwalters@0
|
789 *(options[res].value) != options[res].defaultValue))
|
tomwalters@0
|
790 (void) fprintf(stdout, "%-13s %-9s %-9s %s\n", options[res].name,
|
tomwalters@0
|
791 ((*(options[res].value) == NULL) ? ("") : (*(options[res].value))),
|
tomwalters@0
|
792 ((options[res].defaultValue == NULL) ? ("") : (options[res].defaultValue)),
|
tomwalters@0
|
793 ((options[res].comment == NULL) ? ("") : (options[res].comment)));
|
tomwalters@0
|
794
|
tomwalters@0
|
795 (void) fprintf(stdout, "\n");
|
tomwalters@0
|
796 return;
|
tomwalters@0
|
797 }
|
tomwalters@0
|
798
|
tomwalters@0
|
799 /* ----- Declare the handlerHolder variable ----- */
|
tomwalters@0
|
800
|
tomwalters@0
|
801 static helpRoutine *onLineHelpHandler = defaultHelpHandler;
|
tomwalters@0
|
802
|
tomwalters@0
|
803
|
tomwalters@0
|
804 /* ------------------------------------------------------------------------------
|
tomwalters@0
|
805
|
tomwalters@0
|
806 Spit out the options to a file (with the appropriate option file name).
|
tomwalters@0
|
807
|
tomwalters@0
|
808 Edits: 29th March 1989 (Paul Manson). For the sake of IBM/PC users, this routine
|
tomwalters@0
|
809 will now spit lines with CR/LF pairs.
|
tomwalters@0
|
810 06th April 1989 (Paul Manson). This routine is no-longer conditionally
|
tomwalters@0
|
811 compiled, but is now more widely accepted.
|
tomwalters@0
|
812
|
tomwalters@0
|
813 ------------------------------------------------------------------------------ */
|
tomwalters@0
|
814
|
tomwalters@0
|
815 void updateOptionsFile(options, numOptions, programName, resFileName)
|
tomwalters@0
|
816 Option options[] ;
|
tomwalters@0
|
817 int numOptions ;
|
tomwalters@0
|
818 char *programName;
|
tomwalters@0
|
819 char *resFileName;
|
tomwalters@0
|
820 {
|
tomwalters@0
|
821 int res ;
|
tomwalters@0
|
822 FILE *fptr;
|
tomwalters@0
|
823
|
tomwalters@0
|
824 if ((fptr = fopen(resFileName, "w")) == NULL) {
|
tomwalters@0
|
825 (void) fprintf(stderr, "Unable to Update Options File called %s.\n", resFileName);
|
tomwalters@0
|
826 exit(1);
|
tomwalters@0
|
827 }
|
tomwalters@0
|
828
|
tomwalters@0
|
829 #if defined( PC ) || defined( THINK_C )
|
tomwalters@0
|
830 (void) fprintf(fptr ,"# %s\n", versionstr);
|
tomwalters@0
|
831 (void) fprintf(fptr, "#\r\n# Options file for the %s program.\r\n#\r\n\r\n", programName);
|
tomwalters@0
|
832 (void) fprintf(fptr, "#Option Name Current Default Comment\r\n");
|
tomwalters@0
|
833 (void) fprintf(fptr, "#----------- ------- ------- -------\r\n\r\n");
|
tomwalters@0
|
834 #else
|
tomwalters@0
|
835 (void) fprintf(fptr ,"# %s\n", versionstr);
|
tomwalters@0
|
836 (void) fprintf(fptr, "#\n# Options file for the %s program.\n#\n\n", programName);
|
tomwalters@0
|
837 (void) fprintf(fptr, "#Option Name Current Default Comment\n");
|
tomwalters@0
|
838 (void) fprintf(fptr, "#----------- ------- ------- -------\n\n");
|
tomwalters@0
|
839 #endif
|
tomwalters@0
|
840
|
tomwalters@0
|
841 for (res = numOptions-1; res >=0 ; res-- )
|
tomwalters@0
|
842 if (options[res].classification < OutputOption && *(options[res].value) != NULL &&
|
tomwalters@0
|
843 (updateAllRequired ||
|
tomwalters@0
|
844 strcmp(*(options[res].value), options[res].defaultValue) != 0 ||
|
tomwalters@0
|
845 *(options[res].value) != options[res].defaultValue)) {
|
tomwalters@0
|
846 #if defined( PC )
|
tomwalters@0
|
847 (void) fprintf(fptr, "%-13s = %-9s # %-9s %s\r\n", options[res].name,
|
tomwalters@0
|
848 ((*(options[res].value) == NULL) ? ("") : (*(options[res].value))),
|
tomwalters@0
|
849 ((options[res].defaultValue == NULL) ? ("") : (options[res].defaultValue)),
|
tomwalters@0
|
850 ((options[res].comment == NULL) ? ("") : (options[res].comment)));
|
tomwalters@0
|
851 #else
|
tomwalters@0
|
852 (void) fprintf(fptr, "%-13s = %-9s # %-9s %s\n", options[res].name,
|
tomwalters@0
|
853 ((*(options[res].value) == NULL) ? ("") : (*(options[res].value))),
|
tomwalters@0
|
854 ((options[res].defaultValue == NULL) ? ("") : (options[res].defaultValue)),
|
tomwalters@0
|
855 ((options[res].comment == NULL) ? ("") : (options[res].comment)));
|
tomwalters@0
|
856 #endif
|
tomwalters@0
|
857 }
|
tomwalters@0
|
858
|
tomwalters@0
|
859 if (fclose(fptr) == EOF) {
|
tomwalters@0
|
860 (void) fprintf(stderr, "options: fclose failed on the options file %s.\n", resFileName);
|
tomwalters@0
|
861 exit(1);
|
tomwalters@0
|
862 }
|
tomwalters@0
|
863
|
tomwalters@0
|
864 thereWasAnOptionsFile = TRUE; /* Cos there is one now! */
|
tomwalters@0
|
865
|
tomwalters@0
|
866 return;
|
tomwalters@0
|
867 }
|
tomwalters@0
|
868
|
tomwalters@0
|
869
|
tomwalters@0
|
870 /* ------------------------------------------------------------------------------
|
tomwalters@0
|
871
|
tomwalters@0
|
872 Process the option file and then the command line options supplied.
|
tomwalters@0
|
873
|
tomwalters@0
|
874 Edited:
|
tomwalters@0
|
875
|
tomwalters@0
|
876 2nd March 1989 (Paul Manson). Changed the calls to OptionFileName (ie.
|
tomwalters@0
|
877 added a <prefix> argument) to facilitate
|
tomwalters@0
|
878 searching of HOME (etc) directories. Note
|
tomwalters@0
|
879 that this is IGNORED for IBM/PCs.
|
tomwalters@0
|
880
|
tomwalters@0
|
881 8th March 1989 (Paul Manson). Ignore the above, as OPTIONSPATH is now
|
tomwalters@0
|
882 used (in conjunction with search_path) to
|
tomwalters@0
|
883 enable proper paths for Unix.
|
tomwalters@0
|
884
|
tomwalters@0
|
885 10th March 1989 (Paul Manson). Added the "help" facility and the default
|
tomwalters@0
|
886 and comment stuff.
|
tomwalters@0
|
887
|
tomwalters@0
|
888 16th March 1989 (Paul Manson). Altered the final argc/argv shuffling so that
|
tomwalters@0
|
889 argv simply points at the first argument after
|
tomwalters@0
|
890 the options.
|
tomwalters@0
|
891
|
tomwalters@0
|
892 July 1994 (MAA). Mended to allow spaces in command-line strings.
|
tomwalters@0
|
893
|
tomwalters@0
|
894 ------------------------------------------------------------------------------ */
|
tomwalters@0
|
895
|
tomwalters@0
|
896
|
tomwalters@0
|
897
|
tomwalters@0
|
898
|
tomwalters@0
|
899 /* Assign the default options */
|
tomwalters@0
|
900
|
tomwalters@0
|
901 void default_nopts( options, numOptions )
|
tomwalters@0
|
902 Option options[] ;
|
tomwalters@0
|
903 int numOptions ;
|
tomwalters@0
|
904 {
|
tomwalters@0
|
905 int i ;
|
tomwalters@0
|
906
|
tomwalters@0
|
907 for (i = 0; i < numOptions; i++)
|
tomwalters@0
|
908 *(options[i].value) = options[i].defaultValue ;
|
tomwalters@0
|
909 }
|
tomwalters@0
|
910
|
tomwalters@0
|
911
|
tomwalters@0
|
912
|
tomwalters@0
|
913 /****************************************************************************
|
tomwalters@0
|
914 * Assign options from the rc file.
|
tomwalters@0
|
915 *
|
tomwalters@0
|
916 * The option file is called ".genxxxrc", where the "xxx" is determined
|
tomwalters@0
|
917 * by the name of the application, (which is in argv[0]).
|
tomwalters@0
|
918 * Here "rc" stands for "resource control".
|
tomwalters@0
|
919 * The file-name is assigned to a string ptr "theOptionFileName".
|
tomwalters@0
|
920 * On Unix, the path for the file-name is determined as follows:
|
tomwalters@0
|
921 * if environment variable OPTION_PATH is set, then use this path.
|
tomwalters@0
|
922 * else the default path is:
|
tomwalters@0
|
923 * `.' (the current directory)
|
tomwalters@0
|
924 * `~' (the users home directory)
|
tomwalters@0
|
925 * The DEFAULT_OPTION_PATH for the option file is defined "." (see above).
|
tomwalters@0
|
926 * This means look first in the current directory, and failing that in the
|
tomwalters@0
|
927 * users home directory.
|
tomwalters@0
|
928 * But these defaults can be overridden by setting an environment variable,
|
tomwalters@0
|
929 * which is defined as OPTIONSPATH (see above). Thus the user could set a
|
tomwalters@0
|
930 * new default path for option files by, eg:
|
tomwalters@0
|
931 * setenv OPTIONSPATH ".:~/rcbin"
|
tomwalters@0
|
932 * This would look first in the current directory, and failing that in a
|
tomwalters@0
|
933 * directory ~/rcbin
|
tomwalters@0
|
934 *****************************************************************************/
|
tomwalters@0
|
935
|
tomwalters@0
|
936 void rcfile_nopts( options, numOptions, file )
|
tomwalters@0
|
937 Option options[] ;
|
tomwalters@0
|
938 int numOptions ;
|
tomwalters@0
|
939 char *file ;
|
tomwalters@0
|
940 {
|
tomwalters@0
|
941 FILE *OptionFile ;
|
tomwalters@0
|
942 char *OptionPathPtr ;
|
tomwalters@0
|
943
|
tomwalters@0
|
944
|
tomwalters@0
|
945 #if defined( PC )
|
tomwalters@0
|
946 if (((OptionFile = fopen(theOptionFileName =
|
tomwalters@0
|
947 PCOptionFileName( file, TRUE ), "r")) != NULL)) {
|
tomwalters@0
|
948 /* -------------------------------------------------------------------------------------
|
tomwalters@0
|
949 Removed temporarily so the PC version ONLY examines and creates option files
|
tomwalters@0
|
950 in the cwd. This will be changed when we determine a better strategy for
|
tomwalters@0
|
951 PC directory PATH searches.
|
tomwalters@0
|
952
|
tomwalters@0
|
953 ((OptionFile = fopen(theOptionFileName =
|
tomwalters@0
|
954 PCOptionFileName( file, FALSE), "r")) != NULL)) {
|
tomwalters@0
|
955 ---------------------------------------------------------------------------------------*/
|
tomwalters@0
|
956 #else
|
tomwalters@0
|
957 if ((OptionPathPtr = (char *)getenv(OPTION_PATH)) == NULL)
|
tomwalters@0
|
958 OptionPathPtr = DEFAULT_OPTION_PATH;
|
tomwalters@0
|
959
|
tomwalters@0
|
960 if ((OptionFile = fopen(theOptionFileName =
|
tomwalters@0
|
961 search_path(UnixOptionFileName( file ),
|
tomwalters@0
|
962 OptionPathPtr), "r")) != NULL) {
|
tomwalters@0
|
963 #endif
|
tomwalters@0
|
964
|
tomwalters@0
|
965 /* Process the Option File */
|
tomwalters@0
|
966
|
tomwalters@0
|
967 (void) processOptionFile(options, numOptions, OptionFile,
|
tomwalters@0
|
968 theOptionFileName, FALSE, TRUE, file ) ;
|
tomwalters@0
|
969 (void) fclose(OptionFile);
|
tomwalters@0
|
970
|
tomwalters@0
|
971 thereWasAnOptionsFile = TRUE;
|
tomwalters@0
|
972
|
tomwalters@0
|
973 }
|
tomwalters@0
|
974 }
|
tomwalters@0
|
975
|
tomwalters@0
|
976
|
tomwalters@0
|
977 /* Assign options from the command line */
|
tomwalters@0
|
978
|
tomwalters@0
|
979 void cmd_line_nopts( options, numOptions, argc, argv )
|
tomwalters@0
|
980 Option options[] ;
|
tomwalters@0
|
981 int numOptions ;
|
tomwalters@0
|
982 int *argc ;
|
tomwalters@0
|
983 char ***argv ;
|
tomwalters@0
|
984 {
|
tomwalters@0
|
985 int i, currentArg ;
|
tomwalters@0
|
986 int finalArg, wasAHyphen ;
|
tomwalters@0
|
987 char name[MAX_NAME_LENGTH] ;
|
tomwalters@0
|
988 char value[MAX_NAME_LENGTH] ;
|
tomwalters@0
|
989 char *line, *linePtr;
|
tomwalters@0
|
990 char *tempstring; /* MAA 23-4-1994 */
|
tomwalters@0
|
991 char *tempstring2; /* MAA 23-4-1994 */
|
tomwalters@0
|
992 int count=0;
|
tomwalters@0
|
993
|
tomwalters@0
|
994
|
tomwalters@0
|
995 /* MAA: next 3 lines */
|
tomwalters@0
|
996 linePtr = (char *) calloc((size_t) MAX_NAME_LENGTH, (size_t) sizeof(char));
|
tomwalters@0
|
997 tempstring = (char *) calloc((size_t) MAX_NAME_LENGTH, (size_t) sizeof(char));
|
tomwalters@0
|
998 tempstring2 = (char *) calloc((size_t) MAX_NAME_LENGTH, (size_t) sizeof(char));
|
tomwalters@0
|
999
|
tomwalters@0
|
1000
|
tomwalters@0
|
1001 finalArg = currentArg = 1; /* Ignore the Program Name */
|
tomwalters@0
|
1002 line = malloc((unsigned) MAX_LINE_LENGTH);
|
tomwalters@0
|
1003
|
tomwalters@0
|
1004 while (currentArg < *argc) {
|
tomwalters@0
|
1005 wasAHyphen = FALSE;
|
tomwalters@0
|
1006 linePtr = strcpy(line, (*argv)[currentArg]);
|
tomwalters@0
|
1007 if (linePtr[0] == HYPHEN_CHARACTER) {
|
tomwalters@0
|
1008 wasAHyphen = TRUE;
|
tomwalters@0
|
1009 linePtr++; /* Skip any leading hyphen */
|
tomwalters@0
|
1010 }
|
tomwalters@0
|
1011
|
tomwalters@0
|
1012 /* MAA: force doublequotes onto beg & end . A rather big hack ...*/
|
tomwalters@0
|
1013 if (strchr(linePtr, BLANK_CHARACTER) != NULL){
|
tomwalters@0
|
1014 strncpy(tempstring, linePtr, (int) strcspn(linePtr, "="));
|
tomwalters@0
|
1015 strcat(tempstring, "=\"");
|
tomwalters@0
|
1016 tempstring2 = (char *) strrchr(linePtr, EQUALS_CHARACTER);
|
tomwalters@0
|
1017 tempstring2++;
|
tomwalters@0
|
1018 strcat(tempstring, tempstring2);
|
tomwalters@0
|
1019 strcat(tempstring, "\"");
|
tomwalters@0
|
1020 linePtr=tempstring;}
|
tomwalters@0
|
1021
|
tomwalters@0
|
1022
|
tomwalters@0
|
1023 if ((linePtr = getName(linePtr, name)) == NULL) {
|
tomwalters@0
|
1024 break;
|
tomwalters@0
|
1025 }
|
tomwalters@0
|
1026
|
tomwalters@0
|
1027 if ((linePtr = skipEquals(linePtr)) == NULL) {
|
tomwalters@0
|
1028 if (!wasAHyphen) {
|
tomwalters@0
|
1029 break; /* Don't interpret <name> <value> as being options */
|
tomwalters@0
|
1030 }
|
tomwalters@0
|
1031 if (strcmp(name, HELP_STRING) == 0) {
|
tomwalters@0
|
1032 #ifdef PC
|
tomwalters@0
|
1033 if (strncmp((*argv)[0]+strlen((*argv)[0])-strlen("gen.exe"), "gen", strlen("gen")) == 0)
|
tomwalters@0
|
1034 #else
|
tomwalters@0
|
1035 if (strcmp((*argv)[0], "gen") == 0)
|
tomwalters@0
|
1036 #endif
|
tomwalters@0
|
1037 /* Special case of gen -help */
|
tomwalters@0
|
1038 usageHelp();
|
tomwalters@0
|
1039 else
|
tomwalters@0
|
1040 /* Case of gen??? -help */
|
tomwalters@0
|
1041 (*onLineHelpHandler)(options, numOptions, (*argv)[0]);
|
tomwalters@0
|
1042 exit(0);
|
tomwalters@0
|
1043 }
|
tomwalters@0
|
1044
|
tomwalters@0
|
1045 if (strcmp(name, UPDATE_STRING) == 0) {
|
tomwalters@0
|
1046 /* Do the Update and Then Goto the Top of the Loop Again */
|
tomwalters@0
|
1047 updateOptionsFile(options, numOptions, (*argv)[0], theOptionFileName);
|
tomwalters@0
|
1048 finalArg = ++currentArg;
|
tomwalters@0
|
1049 continue;
|
tomwalters@0
|
1050 }
|
tomwalters@0
|
1051
|
tomwalters@0
|
1052 (void) strcpy(value, DEFAULT_TOGGLE_VALUE);
|
tomwalters@0
|
1053 }
|
tomwalters@0
|
1054 else {
|
tomwalters@0
|
1055 if ((linePtr = getName(linePtr, value)) == NULL) {
|
tomwalters@0
|
1056 break;
|
tomwalters@0
|
1057 }
|
tomwalters@0
|
1058 }
|
tomwalters@0
|
1059
|
tomwalters@0
|
1060 if(!LookUpAndStore(options, numOptions, name, value, TRUE, (*argv)[0])) {
|
tomwalters@0
|
1061 (void) fprintf(stderr,"options: Could not find an Option called %s\n", name);
|
tomwalters@0
|
1062 exit(1);
|
tomwalters@0
|
1063 }
|
tomwalters@0
|
1064
|
tomwalters@0
|
1065 finalArg = ++currentArg;
|
tomwalters@0
|
1066 }
|
tomwalters@0
|
1067
|
tomwalters@0
|
1068 /* Reset the Command Line argc and argv */
|
tomwalters@0
|
1069 /* The Original Version actually cut the options out of the argv array (by
|
tomwalters@0
|
1070 shifting the remaining arguments left), but the new version simply lets
|
tomwalters@0
|
1071 argv point to the next argument to be processed.
|
tomwalters@0
|
1072
|
tomwalters@0
|
1073 if (finalArg > 1) {
|
tomwalters@0
|
1074 for (i = finalArg; i < *argc; i++)
|
tomwalters@0
|
1075 (*argv)[i - finalArg + 1] = (*argv)[i];
|
tomwalters@0
|
1076 *argc = *argc - finalArg + 1;
|
tomwalters@0
|
1077 }
|
tomwalters@0
|
1078
|
tomwalters@0
|
1079 */
|
tomwalters@0
|
1080
|
tomwalters@0
|
1081 *argv+= finalArg;
|
tomwalters@0
|
1082 *argc = *argc - finalArg;
|
tomwalters@0
|
1083
|
tomwalters@0
|
1084 return;
|
tomwalters@0
|
1085 }
|
tomwalters@0
|
1086
|
tomwalters@0
|
1087
|
tomwalters@0
|
1088
|
tomwalters@0
|
1089 /* Assign options using defaults, then the rc file, then the command line */
|
tomwalters@0
|
1090
|
tomwalters@0
|
1091 void getnopts (options, numOptions, argc, argv)
|
tomwalters@0
|
1092 Option options[] ;
|
tomwalters@0
|
1093 int numOptions ;
|
tomwalters@0
|
1094 int *argc ;
|
tomwalters@0
|
1095 char ***argv ;
|
tomwalters@0
|
1096 {
|
tomwalters@0
|
1097 default_nopts( options, numOptions ) ;
|
tomwalters@0
|
1098 rcfile_nopts( options, numOptions, (*argv)[0] ) ;
|
tomwalters@0
|
1099 cmd_line_nopts( options, numOptions, argc, argv ) ;
|
tomwalters@0
|
1100 }
|
tomwalters@0
|
1101
|
tomwalters@0
|
1102
|
tomwalters@0
|
1103
|
tomwalters@0
|
1104 /* -------------------------------------------------------------------------------
|
tomwalters@0
|
1105
|
tomwalters@0
|
1106 Read an option header from the specified file into the given options array.
|
tomwalters@0
|
1107
|
tomwalters@0
|
1108 ------------------------------------------------------------------------------- */
|
tomwalters@0
|
1109 void readnopts(options, numOptions, filePointer)
|
tomwalters@0
|
1110 Option options[] ;
|
tomwalters@0
|
1111 int numOptions;
|
tomwalters@0
|
1112 FILE *filePointer ;
|
tomwalters@0
|
1113 {
|
tomwalters@0
|
1114 long filePosition ;
|
tomwalters@0
|
1115 char first[200] ;
|
tomwalters@0
|
1116 int headerLength ;
|
tomwalters@0
|
1117
|
tomwalters@0
|
1118 filePosition = ftell(filePointer); /* Save the Original Position */
|
tomwalters@0
|
1119
|
tomwalters@0
|
1120 /* Read the first line of the first block, or as much of it as possible */
|
tomwalters@0
|
1121
|
tomwalters@0
|
1122 if ((!fread(first, 1, strlen(OptionHeaderHeader) + OPTION_HEADER_DIGITS
|
tomwalters@0
|
1123 + strlen(LineFeedArray), filePointer)) ||
|
tomwalters@0
|
1124 (strncmp(first, OptionHeaderHeader, strlen(OptionHeaderHeader)) != 0)) {
|
tomwalters@0
|
1125 /* Assume that this is NOT a option header */
|
tomwalters@0
|
1126 if (fseek(filePointer, filePosition, 0)) {
|
tomwalters@0
|
1127 (void) fprintf(stderr, "options: Error fseeking Option Header File\n");
|
tomwalters@0
|
1128 exit(1);
|
tomwalters@0
|
1129 }
|
tomwalters@0
|
1130 return;
|
tomwalters@0
|
1131 }
|
tomwalters@0
|
1132
|
tomwalters@0
|
1133 /* Extract the Header Length in Bytes */
|
tomwalters@0
|
1134
|
tomwalters@0
|
1135 headerLength = atoi(first + strlen(OptionHeaderHeader));
|
tomwalters@0
|
1136
|
tomwalters@0
|
1137 /* Now, process the stuff. Need to "seek" past the first line before
|
tomwalters@0
|
1138 attempting to read anything, and shorten the headerLength accordingly */
|
tomwalters@0
|
1139
|
tomwalters@0
|
1140 (void) processOptionFile(options, numOptions, filePointer,
|
tomwalters@0
|
1141 "Unknown Option File",
|
tomwalters@0
|
1142 (headerLength - strlen(OptionHeaderHeader) -
|
tomwalters@0
|
1143 OPTION_HEADER_DIGITS - strlen(LineFeedArray)),
|
tomwalters@0
|
1144 FALSE, "???");
|
tomwalters@0
|
1145
|
tomwalters@0
|
1146 /* Make sure that the file pointer is set to the data area */
|
tomwalters@0
|
1147
|
tomwalters@0
|
1148 if (fseek(filePointer, filePosition + headerLength, 0)) {
|
tomwalters@0
|
1149 (void) fprintf(stderr, "options: Error fseeking Option Header File\n");
|
tomwalters@0
|
1150 exit(1);
|
tomwalters@0
|
1151 }
|
tomwalters@0
|
1152
|
tomwalters@0
|
1153 }
|
tomwalters@0
|
1154
|
tomwalters@0
|
1155
|
tomwalters@0
|
1156 /* -------------------------------------------------------------------------------
|
tomwalters@0
|
1157
|
tomwalters@0
|
1158 Count the number of bytes which will be written by writenopts, given the
|
tomwalters@0
|
1159 options array.
|
tomwalters@0
|
1160
|
tomwalters@0
|
1161 ------------------------------------------------------------------------------- */
|
tomwalters@0
|
1162 static int countBytesToWrite( options, numOptions )
|
tomwalters@0
|
1163 Option options[] ;
|
tomwalters@0
|
1164 int numOptions;
|
tomwalters@0
|
1165 {
|
tomwalters@0
|
1166 int sum, i;
|
tomwalters@0
|
1167
|
tomwalters@0
|
1168 sum = 0;
|
tomwalters@0
|
1169
|
tomwalters@0
|
1170 for (i = 0; i < numOptions; i++)
|
tomwalters@0
|
1171 if((options[i].classification == OutputOption ||
|
tomwalters@0
|
1172 options[i].classification == InOutOption) &&
|
tomwalters@0
|
1173 *(options[i].value) != NULL &&
|
tomwalters@0
|
1174 strcmp(*(options[i].value), NULL_STRING) != 0)
|
tomwalters@0
|
1175 sum += strlen(options[i].name) + strlen(EqualsArray) +
|
tomwalters@0
|
1176 strlen(*(options[i].value)) + strlen(LineFeedArray); /* + (2 * strlen(QuotesArray)); */
|
tomwalters@0
|
1177
|
tomwalters@0
|
1178 return (sum);
|
tomwalters@0
|
1179 }
|
tomwalters@0
|
1180
|
tomwalters@0
|
1181 /* -------------------------------------------------------------------------------
|
tomwalters@0
|
1182
|
tomwalters@0
|
1183 The descendent of the lost and lamented blockCopyStrToFile... writes a string
|
tomwalters@0
|
1184 to the indicated file.
|
tomwalters@0
|
1185
|
tomwalters@0
|
1186 ------------------------------------------------------------------------------- */
|
tomwalters@0
|
1187 static void WriteStringToFile(str, filePtr)
|
tomwalters@0
|
1188 char *str;
|
tomwalters@0
|
1189 FILE *filePtr;
|
tomwalters@0
|
1190 {
|
tomwalters@0
|
1191 if (!fwrite(str, 1, strlen(str), filePtr)) {
|
tomwalters@0
|
1192 (void) fprintf(stderr, "WriteStringToFile: Error printing %s to file.\n", str);
|
tomwalters@0
|
1193 exit(1);
|
tomwalters@0
|
1194 }
|
tomwalters@0
|
1195
|
tomwalters@0
|
1196 return;
|
tomwalters@0
|
1197 }
|
tomwalters@0
|
1198
|
tomwalters@0
|
1199
|
tomwalters@0
|
1200 /* -------------------------------------------------------------------------------
|
tomwalters@0
|
1201
|
tomwalters@0
|
1202 Write an option header to the specified file from the information contained
|
tomwalters@0
|
1203 in the given options array. Remove the comments to get debugging info.
|
tomwalters@0
|
1204
|
tomwalters@0
|
1205 ------------------------------------------------------------------------------- */
|
tomwalters@0
|
1206 void writenopts(options, numOptions, filePointer)
|
tomwalters@0
|
1207 Option options[] ;
|
tomwalters@0
|
1208 int numOptions;
|
tomwalters@0
|
1209 FILE *filePointer ;
|
tomwalters@0
|
1210 {
|
tomwalters@0
|
1211 /*int bytesWritten ;*/
|
tomwalters@0
|
1212 int i ;
|
tomwalters@0
|
1213 long filePosition ;
|
tomwalters@0
|
1214 int bytesToWrite ;
|
tomwalters@0
|
1215 int oddHeaderLength ;
|
tomwalters@0
|
1216 char DigitString[OPTION_HEADER_DIGITS + 2];
|
tomwalters@0
|
1217
|
tomwalters@0
|
1218 filePosition = ftell(filePointer);
|
tomwalters@0
|
1219
|
tomwalters@0
|
1220 bytesToWrite = countBytesToWrite(options, numOptions) +
|
tomwalters@0
|
1221 strlen(OptionHeaderHeader) + OPTION_HEADER_DIGITS +
|
tomwalters@0
|
1222 strlen(LineFeedArray) + 1;
|
tomwalters@0
|
1223
|
tomwalters@0
|
1224 if (oddHeaderLength = (bytesToWrite % 2))
|
tomwalters@0
|
1225 bytesToWrite++;
|
tomwalters@0
|
1226
|
tomwalters@0
|
1227 (void) WriteStringToFile(OptionHeaderHeader, filePointer);
|
tomwalters@0
|
1228
|
tomwalters@0
|
1229 (void) sprintf(DigitString, "%0*d", OPTION_HEADER_DIGITS, bytesToWrite);
|
tomwalters@0
|
1230
|
tomwalters@0
|
1231 /*(void) printf("bytesToWrite is %i.\n", bytesToWrite);*/
|
tomwalters@0
|
1232
|
tomwalters@0
|
1233 (void) WriteStringToFile(DigitString, filePointer);
|
tomwalters@0
|
1234
|
tomwalters@0
|
1235 (void) WriteStringToFile(LineFeedArray, filePointer);
|
tomwalters@0
|
1236
|
tomwalters@0
|
1237 /* Copy all of the Options */
|
tomwalters@0
|
1238
|
tomwalters@0
|
1239 for (i = 0; i < numOptions; i++) {
|
tomwalters@0
|
1240
|
tomwalters@0
|
1241 if((options[i].classification == OutputOption ||
|
tomwalters@0
|
1242 options[i].classification == InOutOption) &&
|
tomwalters@0
|
1243 *(options[i].value) != NULL &&
|
tomwalters@0
|
1244 strcmp(*(options[i].value), NULL_STRING) != 0) {
|
tomwalters@0
|
1245
|
tomwalters@0
|
1246 (void) WriteStringToFile(options[i].name, filePointer);
|
tomwalters@0
|
1247
|
tomwalters@0
|
1248 (void) WriteStringToFile(EqualsArray, filePointer);
|
tomwalters@0
|
1249
|
tomwalters@0
|
1250 /* (void) WriteStringToFile(QuotesArray, filePointer); */
|
tomwalters@0
|
1251
|
tomwalters@0
|
1252 (void) WriteStringToFile(*(options[i].value), filePointer);
|
tomwalters@0
|
1253
|
tomwalters@0
|
1254 /* (void) WriteStringToFile(QuotesArray, filePointer); */
|
tomwalters@0
|
1255
|
tomwalters@0
|
1256 (void) WriteStringToFile(LineFeedArray, filePointer);
|
tomwalters@0
|
1257 }
|
tomwalters@0
|
1258 }
|
tomwalters@0
|
1259
|
tomwalters@0
|
1260 if (fputc(NULL_CHARACTER, filePointer) == EOF) {
|
tomwalters@0
|
1261 (void) fprintf(stderr, "writenopts: Error doing fputc of the last NULL character.\n");
|
tomwalters@0
|
1262 exit(1);
|
tomwalters@0
|
1263 }
|
tomwalters@0
|
1264
|
tomwalters@0
|
1265 if (oddHeaderLength && fputc(NULL_CHARACTER, filePointer) == EOF) {
|
tomwalters@0
|
1266 (void) fprintf(stderr, "writenopts: Error doing fputc of the odd-pad NULL character.\n");
|
tomwalters@0
|
1267 exit(1);
|
tomwalters@0
|
1268 }
|
tomwalters@0
|
1269
|
tomwalters@0
|
1270 if (fflush(filePointer)) {
|
tomwalters@0
|
1271 (void) fprintf(stderr, "options: Error while flushing the option header\n");
|
tomwalters@0
|
1272 exit(1);
|
tomwalters@0
|
1273 }
|
tomwalters@0
|
1274
|
tomwalters@0
|
1275 /* seek the fileptr to after the last byte of the header */
|
tomwalters@0
|
1276
|
tomwalters@0
|
1277 if (filePointer != stdout) {
|
tomwalters@0
|
1278 if (fseek(filePointer, filePosition + (long)bytesToWrite, 0)) {
|
tomwalters@0
|
1279 (void) fprintf(stderr, "options: Error fseeking Option Header File\n");
|
tomwalters@0
|
1280 exit(1);
|
tomwalters@0
|
1281 }
|
tomwalters@0
|
1282 }
|
tomwalters@0
|
1283
|
tomwalters@0
|
1284 }
|
tomwalters@0
|
1285
|
tomwalters@0
|
1286
|
tomwalters@0
|
1287 /* ----------------------------------------------------------------------------
|
tomwalters@0
|
1288
|
tomwalters@0
|
1289 A Little Routine to Count the Options in a Options Array .... This MUST
|
tomwalters@0
|
1290 Be NULL-Terminated ...... OR ELSE!
|
tomwalters@0
|
1291
|
tomwalters@0
|
1292 ---------------------------------------------------------------------------- */
|
tomwalters@0
|
1293
|
tomwalters@0
|
1294 static int countOptions(options)
|
tomwalters@0
|
1295 Option options[];
|
tomwalters@0
|
1296 {
|
tomwalters@0
|
1297 int numoptions;
|
tomwalters@0
|
1298
|
tomwalters@0
|
1299 for (numoptions = 0;
|
tomwalters@0
|
1300 options[numoptions].name != NULL; /* DEATH TO ALL WHO TREAD HERE! */
|
tomwalters@0
|
1301 numoptions++);
|
tomwalters@0
|
1302
|
tomwalters@0
|
1303 return (numoptions);
|
tomwalters@0
|
1304
|
tomwalters@0
|
1305 }
|
tomwalters@0
|
1306
|
tomwalters@0
|
1307
|
tomwalters@0
|
1308 /* -------------------------------------------------------------------------------
|
tomwalters@0
|
1309
|
tomwalters@0
|
1310 The Counting version of getnopts -- you MUST null-terminate the options array.
|
tomwalters@0
|
1311
|
tomwalters@0
|
1312 ------------------------------------------------------------------------------- */
|
tomwalters@0
|
1313
|
tomwalters@0
|
1314 void getopts (options, argc, argv)
|
tomwalters@0
|
1315 Option options[] ;
|
tomwalters@0
|
1316 int *argc ;
|
tomwalters@0
|
1317 char ***argv ;
|
tomwalters@0
|
1318 {
|
tomwalters@0
|
1319 (void) getnopts(options, countOptions(options), argc, argv);
|
tomwalters@0
|
1320 }
|
tomwalters@0
|
1321
|
tomwalters@0
|
1322
|
tomwalters@0
|
1323 void cmd_line_opts(options, argc, argv)
|
tomwalters@0
|
1324 Option options[] ;
|
tomwalters@0
|
1325 int *argc ;
|
tomwalters@0
|
1326 char ***argv ;
|
tomwalters@0
|
1327 {
|
tomwalters@0
|
1328 (void) cmd_line_nopts( options, countOptions(options), argc, argv ) ;
|
tomwalters@0
|
1329 }
|
tomwalters@0
|
1330
|
tomwalters@0
|
1331
|
tomwalters@0
|
1332
|
tomwalters@0
|
1333 /* -------------------------------------------------------------------------------
|
tomwalters@0
|
1334
|
tomwalters@0
|
1335 The Counting version of readnopts -- you MUST null-terminate the options array.
|
tomwalters@0
|
1336
|
tomwalters@0
|
1337 ------------------------------------------------------------------------------- */
|
tomwalters@0
|
1338 void readopts(options, filePointer)
|
tomwalters@0
|
1339 Option options[] ;
|
tomwalters@0
|
1340 FILE *filePointer ;
|
tomwalters@0
|
1341 {
|
tomwalters@0
|
1342 (void) readnopts(options, countOptions(options), filePointer);
|
tomwalters@0
|
1343 }
|
tomwalters@0
|
1344
|
tomwalters@0
|
1345 /* -------------------------------------------------------------------------------
|
tomwalters@0
|
1346
|
tomwalters@0
|
1347 The Counting version of writenopts -- you MUST null-terminate the options array.
|
tomwalters@0
|
1348
|
tomwalters@0
|
1349 ------------------------------------------------------------------------------- */
|
tomwalters@0
|
1350 void writeopts(options, filePointer)
|
tomwalters@0
|
1351 Option options[] ;
|
tomwalters@0
|
1352 FILE *filePointer ;
|
tomwalters@0
|
1353 {
|
tomwalters@0
|
1354 (void) writenopts(options, countOptions(options), filePointer);
|
tomwalters@0
|
1355 }
|
tomwalters@0
|
1356
|
tomwalters@0
|
1357
|
tomwalters@0
|
1358 /* -------------------------------------------------------------------------------
|
tomwalters@0
|
1359
|
tomwalters@0
|
1360 Packaging for convenience -- Guaranteed to be Listeria-free!
|
tomwalters@0
|
1361
|
tomwalters@0
|
1362 ------------------------------------------------------------------------------- */
|
tomwalters@0
|
1363
|
tomwalters@0
|
1364 FILE *fileopts( res, argc, argv )
|
tomwalters@0
|
1365 Option *res ;
|
tomwalters@0
|
1366 int *argc ;
|
tomwalters@0
|
1367 char **argv[];
|
tomwalters@0
|
1368 {
|
tomwalters@0
|
1369 FILE *ifp ;
|
tomwalters@0
|
1370 int numOptions;
|
tomwalters@0
|
1371 #if defined( PC )
|
tomwalters@0
|
1372 char *progName ;
|
tomwalters@0
|
1373
|
tomwalters@0
|
1374 progName = (*argv)[0];
|
tomwalters@0
|
1375 #endif
|
tomwalters@0
|
1376
|
tomwalters@0
|
1377 numOptions = countOptions(res);
|
tomwalters@0
|
1378
|
tomwalters@0
|
1379 getnopts( res, numOptions, argc, argv ) ;
|
tomwalters@0
|
1380
|
tomwalters@0
|
1381 if( *argc > 0 ) {
|
tomwalters@0
|
1382 if((ifp = fopen( **argv, "r" )) == NULL) {
|
tomwalters@0
|
1383 (void) fprintf(stderr, "Unable to open the file %s.\n", **argv);
|
tomwalters@0
|
1384 exit(1);
|
tomwalters@0
|
1385 }
|
tomwalters@0
|
1386 }
|
tomwalters@0
|
1387 else
|
tomwalters@0
|
1388 #if defined( PC )
|
tomwalters@0
|
1389 {
|
tomwalters@0
|
1390 /* PCs cannot take binmode files through standard input */
|
tomwalters@0
|
1391 (void) (*onLineHelpHandler)( res, numOptions, progName );
|
tomwalters@0
|
1392 exit(1);
|
tomwalters@0
|
1393 }
|
tomwalters@0
|
1394 #else
|
tomwalters@0
|
1395 ifp = stdin ;
|
tomwalters@0
|
1396 #endif
|
tomwalters@0
|
1397
|
tomwalters@0
|
1398 (*argv)++ ;
|
tomwalters@0
|
1399 (*argc)-- ;
|
tomwalters@0
|
1400
|
tomwalters@0
|
1401 readopts( res, ifp ) ;
|
tomwalters@0
|
1402
|
tomwalters@0
|
1403 return( ifp ) ;
|
tomwalters@0
|
1404
|
tomwalters@0
|
1405 }
|
tomwalters@0
|
1406
|
tomwalters@0
|
1407
|
tomwalters@0
|
1408 /* -------------------------------------------------------------------------------
|
tomwalters@0
|
1409
|
tomwalters@0
|
1410 Packaging for convenience -- Guaranteed to be Listeria-free!
|
tomwalters@0
|
1411
|
tomwalters@0
|
1412 ------------------------------------------------------------------------------- */
|
tomwalters@0
|
1413 FILE *optoutput(str)
|
tomwalters@0
|
1414 char *str;
|
tomwalters@0
|
1415 {
|
tomwalters@0
|
1416 FILE *f;
|
tomwalters@0
|
1417
|
tomwalters@0
|
1418 if (str == NULL)
|
tomwalters@0
|
1419 return (NULL);
|
tomwalters@0
|
1420 else if (str == DEFAULT_TOGGLE_VALUE)
|
tomwalters@0
|
1421 return (stdout);
|
tomwalters@0
|
1422
|
tomwalters@0
|
1423 if ((f = fopen(str, "w")) == NULL) {
|
tomwalters@0
|
1424 (void) fprintf(stderr, "options: Could not open the file %s for output.\n", str);
|
tomwalters@0
|
1425 exit(1);
|
tomwalters@0
|
1426 }
|
tomwalters@0
|
1427 return (f);
|
tomwalters@0
|
1428 }
|
tomwalters@0
|
1429
|
tomwalters@0
|
1430
|
tomwalters@0
|
1431 /* -------------------------------------------------------------------------------
|
tomwalters@0
|
1432
|
tomwalters@0
|
1433 OnLine Help from the user program.
|
tomwalters@0
|
1434
|
tomwalters@0
|
1435 ------------------------------------------------------------------------------- */
|
tomwalters@0
|
1436 void helpnopts(res, numRes, name)
|
tomwalters@0
|
1437 Option res[];
|
tomwalters@0
|
1438 int numRes;
|
tomwalters@0
|
1439 char *name ;
|
tomwalters@0
|
1440 {
|
tomwalters@0
|
1441 (void) (*onLineHelpHandler)(res, numRes, name);
|
tomwalters@0
|
1442 }
|
tomwalters@0
|
1443
|
tomwalters@0
|
1444 /* -------------------------------------------------------------------------------
|
tomwalters@0
|
1445
|
tomwalters@0
|
1446 OnLine Help from the user program. (counting version)
|
tomwalters@0
|
1447
|
tomwalters@0
|
1448 ------------------------------------------------------------------------------- */
|
tomwalters@0
|
1449 void helpopts(res, name)
|
tomwalters@0
|
1450 Option res[];
|
tomwalters@0
|
1451 char *name ;
|
tomwalters@0
|
1452 {
|
tomwalters@0
|
1453 #ifdef PC
|
tomwalters@0
|
1454 if (strncmp(name+strlen(name)-strlen("gen.exe"), "gen", strlen("gen")) == 0)
|
tomwalters@0
|
1455 #else
|
tomwalters@0
|
1456 if (strcmp(name, "gen") == 0)
|
tomwalters@0
|
1457 #endif
|
tomwalters@0
|
1458 /* Special case of gen */
|
tomwalters@0
|
1459 usageHelp();
|
tomwalters@0
|
1460 else
|
tomwalters@0
|
1461 /* Case of gen??? */
|
tomwalters@0
|
1462 (void) (*onLineHelpHandler)(res, countOptions(res), name);
|
tomwalters@0
|
1463 }
|
tomwalters@0
|
1464
|
tomwalters@0
|
1465
|
tomwalters@0
|
1466 /* ---------------------------------------------------------------------------------
|
tomwalters@0
|
1467
|
tomwalters@0
|
1468 Allows an application program to install its very own helpHandler routine to
|
tomwalters@0
|
1469 override the default help-message handler. The behaviour of such a routine is
|
tomwalters@0
|
1470 implicitly trusted by <options>, so you should only install your own handler
|
tomwalters@0
|
1471 when you are quite familiar with the Options structure format. This routine
|
tomwalters@0
|
1472 returns the address of the previously installed handler (which is initially the
|
tomwalters@0
|
1473 default handler) so that this may be reinstated at a later point.
|
tomwalters@0
|
1474
|
tomwalters@0
|
1475 ---------------------------------------------------------------------------------- */
|
tomwalters@0
|
1476
|
tomwalters@0
|
1477 helpRoutine *helpOptsHandler(aHelpRoutine)
|
tomwalters@0
|
1478 helpRoutine *aHelpRoutine;
|
tomwalters@0
|
1479 {
|
tomwalters@0
|
1480 helpRoutine *temp;
|
tomwalters@0
|
1481
|
tomwalters@0
|
1482 temp = onLineHelpHandler;
|
tomwalters@0
|
1483
|
tomwalters@0
|
1484 onLineHelpHandler = aHelpRoutine;
|
tomwalters@0
|
1485
|
tomwalters@0
|
1486 return (temp);
|
tomwalters@0
|
1487 }
|
tomwalters@0
|
1488
|
tomwalters@0
|
1489
|
tomwalters@0
|
1490 /* ---------------------------------------------------------------------------------
|
tomwalters@0
|
1491
|
tomwalters@0
|
1492 A convenience call which returns TRUE (1) if the optionStr is what options thinks
|
tomwalters@0
|
1493 of as "ON", "YES", "TRUE", or "1".... This merely allows us to hide the actual
|
tomwalters@0
|
1494 implementation of "ON" from the application programs.
|
tomwalters@0
|
1495
|
tomwalters@0
|
1496 --------------------------------------------------------------------------------- */
|
tomwalters@0
|
1497
|
tomwalters@0
|
1498 int isOFF(optionStr)
|
tomwalters@0
|
1499 char *optionStr;
|
tomwalters@0
|
1500 {
|
tomwalters@0
|
1501 return (strcmp(OFF_STRING, optionStr) == 0 ||
|
tomwalters@0
|
1502 strcmp(OFF_ALIAS , optionStr) == 0 ||
|
tomwalters@0
|
1503 strcmp(NOT_USED , optionStr) == 0);
|
tomwalters@0
|
1504 }
|
tomwalters@0
|
1505
|
tomwalters@0
|
1506
|
tomwalters@0
|
1507 /* ---------------------------------------------------------------------------------
|
tomwalters@0
|
1508
|
tomwalters@0
|
1509 A convenience call which returns TRUE (1) if the optionStr is what options thinks
|
tomwalters@0
|
1510 of as "NULL", "NONE", nothing, zip, etc... This merely allows us to hide the actual
|
tomwalters@0
|
1511 implementation of "NULL" from the application programs.
|
tomwalters@0
|
1512
|
tomwalters@0
|
1513 --------------------------------------------------------------------------------- */
|
tomwalters@0
|
1514
|
tomwalters@0
|
1515 int isNULL(optionStr)
|
tomwalters@0
|
1516 char *optionStr;
|
tomwalters@0
|
1517 {
|
tomwalters@0
|
1518 return (optionStr == NULL ||
|
tomwalters@0
|
1519 strcmp(NULL_STRING, optionStr) == 0 ||
|
tomwalters@0
|
1520 strcmp(NULL_ALIAS , optionStr) == 0);
|
tomwalters@0
|
1521 }
|
tomwalters@0
|
1522
|
tomwalters@0
|
1523
|
tomwalters@0
|
1524 /* ---------------------------------------------------------------------------------
|
tomwalters@0
|
1525
|
tomwalters@0
|
1526 A routine to reduce the load on the application programmer by providing a simple
|
tomwalters@0
|
1527 boolean check for string equality WITHOUT CASE SIGNIFICANCE. This allows applications
|
tomwalters@0
|
1528 to leave case and typing problems within "options" reliably.
|
tomwalters@0
|
1529
|
tomwalters@0
|
1530 --------------------------------------------------------------------------------- */
|
tomwalters@0
|
1531
|
tomwalters@0
|
1532 static char *stringToLowerCase(str)
|
tomwalters@0
|
1533 char *str;
|
tomwalters@0
|
1534 {
|
tomwalters@0
|
1535 register int i;
|
tomwalters@0
|
1536
|
tomwalters@0
|
1537 if (str == NULL)
|
tomwalters@0
|
1538 return (str);
|
tomwalters@0
|
1539 else {
|
tomwalters@0
|
1540 for (i = 0; str[i] != NULL_CHARACTER; i++)
|
tomwalters@0
|
1541 if (isupper((char) str[i]))
|
tomwalters@0
|
1542 str[i] = (char) tolower((char) str[i]);
|
tomwalters@0
|
1543 return (str);
|
tomwalters@0
|
1544 }
|
tomwalters@0
|
1545 }
|
tomwalters@0
|
1546
|
tomwalters@0
|
1547 extern int OptionStringsEqual(str1, str2)
|
tomwalters@0
|
1548 char *str1, *str2;
|
tomwalters@0
|
1549 {
|
tomwalters@0
|
1550 /* This routine copies the strings into two local buffers, converts them to
|
tomwalters@0
|
1551 lower case, and then compares them for equality. This local copy ensures
|
tomwalters@0
|
1552 that they are automatically deallocated on function return */
|
tomwalters@0
|
1553
|
tomwalters@0
|
1554 #define MAX_COPY_LENGTH (256)
|
tomwalters@0
|
1555
|
tomwalters@0
|
1556 char lc1[MAX_COPY_LENGTH], lc2[MAX_COPY_LENGTH];
|
tomwalters@0
|
1557
|
tomwalters@0
|
1558 if (strlen(str1) < MAX_COPY_LENGTH &&
|
tomwalters@0
|
1559 strlen(str2) < MAX_COPY_LENGTH)
|
tomwalters@0
|
1560 return (strcmp(stringToLowerCase(strcpy(lc1, str1)),
|
tomwalters@0
|
1561 stringToLowerCase(strcpy(lc2, str2))) == 0);
|
tomwalters@0
|
1562 else {
|
tomwalters@0
|
1563 (void) fprintf(stderr, "options: OptionStringsEqual() could not compare the strings %s and %s becaues one was more that %i characters long.\n", str1, str2, MAX_COPY_LENGTH);
|
tomwalters@0
|
1564 exit(1);
|
tomwalters@0
|
1565 }
|
tomwalters@0
|
1566 }
|
tomwalters@0
|
1567
|
tomwalters@0
|
1568
|
tomwalters@0
|
1569
|
tomwalters@0
|
1570 /* Print general usage information in response to: gen -help */
|
tomwalters@0
|
1571 usageHelp()
|
tomwalters@0
|
1572 {
|
tomwalters@0
|
1573 (void)fprintf(stdout,"%s\n\n", versionstr);
|
tomwalters@0
|
1574
|
tomwalters@0
|
1575 (void) fprintf(stdout, "Usage: genXXX [options] [file_name]\n");
|
tomwalters@0
|
1576 (void) fprintf(stdout, " where XXX is one of the following abbreviations:\n\n\
|
tomwalters@0
|
1577 wav waveform \n\
|
tomwalters@0
|
1578 bmm basilar membrane motion \n\
|
tomwalters@0
|
1579 nap neural activity pattern \n\
|
tomwalters@0
|
1580 sai stabilized auditory image \n\
|
tomwalters@0
|
1581 spl spiral version of auditory image \n\
|
tomwalters@0
|
1582 sgm spectrogram \n\
|
tomwalters@0
|
1583 cgm cochleogram " ) ;
|
tomwalters@0
|
1584 (void) fprintf(stdout, "\n\
|
tomwalters@0
|
1585 asa auditory spectral analysis \n\
|
tomwalters@0
|
1586 epn excitation pattern \n\n");
|
tomwalters@0
|
1587
|
tomwalters@0
|
1588 (void) fprintf(stdout, " [file_name] is a headerless wave file (2-byte binary integers).\n");
|
tomwalters@0
|
1589 (void) fprintf(stdout, " [options] are parameters, options and swtiches that control\n");
|
tomwalters@0
|
1590 (void) fprintf(stdout, " the AIM instructions and the AIM tools.\n\n");
|
tomwalters@0
|
1591
|
tomwalters@0
|
1592 (void) fprintf(stdout, " Help with options: genXXX [-help | -help=all | -help=option]\n");
|
tomwalters@0
|
1593 #if !defined( PC )
|
tomwalters@0
|
1594 (void) fprintf(stdout, " Path for options file, (.genXXXrc) = . (or setenv OPTIONSPATH)\n\n");
|
tomwalters@0
|
1595 #endif
|
tomwalters@0
|
1596
|
tomwalters@0
|
1597 (void) fprintf(stdout, "Processes Applied by AIM and Routes Through the Model: \n\n\
|
tomwalters@0
|
1598 Process Auditory Speech Spectra \n\
|
tomwalters@0
|
1599 -------------------------------- -------- ------ ------- \n\
|
tomwalters@0
|
1600 Display input wave genwav genwav genwav \n\
|
tomwalters@0
|
1601 Auditory filtering (gtf/tlf) genbmm \n\
|
tomwalters@0
|
1602 Compression and rectification gensgm genasa " ) ;
|
tomwalters@0
|
1603
|
tomwalters@0
|
1604 (void) fprintf(stdout, "\n\
|
tomwalters@0
|
1605 Neural encoding (2D-AT/haircell) gennap \n\
|
tomwalters@0
|
1606 Temporal integration (LP filter) gencgm genepn \n\
|
tomwalters@0
|
1607 Strobed temporal integration gensai \n\
|
tomwalters@0
|
1608 Spiral mapping of auditory image genspl \n\n");
|
tomwalters@0
|
1609
|
tomwalters@0
|
1610 (void) fprintf(stdout, "Output: genXXX output=on file_name \n");
|
tomwalters@0
|
1611 (void) fprintf(stdout, " output is written to file: file_name.XXX \n");
|
tomwalters@0
|
1612
|
tomwalters@0
|
1613 (void) fprintf(stdout, "\n\
|
tomwalters@0
|
1614 The format for 2-dimensional output format is by columns, with the \n\
|
tomwalters@0
|
1615 lowest channel first in each column (bmm, nap, sgm, cgm, asa, epn).\n\
|
tomwalters@0
|
1616 The format for auditory image output is by rows, for each image frame \n\
|
tomwalters@0
|
1617 in succession, with the row of the lowest channel first (sai, spl).\n\n");
|
tomwalters@0
|
1618
|
tomwalters@0
|
1619 (void) fprintf(stdout, "The Auditory Image Model was developed at the Applied Psychology Unit\n");
|
tomwalters@0
|
1620 (void) fprintf(stdout, "of the Medical Research Council, 15 Chaucer Road, Cambridge, U.K.\n\n");
|
tomwalters@0
|
1621
|
tomwalters@0
|
1622 (void) fprintf(stdout, "Copyright(c) Applied Psychology Unit, Medical Research Council, 1988-1995.\n");
|
tomwalters@0
|
1623
|
tomwalters@0
|
1624 }
|