annotate tools/options.c @ 0:5242703e91d3 tip

Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author tomwalters
date Fri, 20 May 2011 15:19:45 +0100
parents
children
rev   line source
tomwalters@0 1
tomwalters@0 2 #include <stdio.h>
tomwalters@0 3 #include <math.h>
tomwalters@0 4 #include "options.h"
tomwalters@0 5 #include "strmatch.h"
tomwalters@0 6 #include "units.h"
tomwalters@0 7
tomwalters@0 8
tomwalters@0 9 /*
tomwalters@0 10 Defaults for i/o parameters.
tomwalters@0 11 These are declared externally in options.h so they may be overridden by
tomwalters@0 12 option assignment.
tomwalters@0 13 */
tomwalters@0 14
tomwalters@0 15 int LINE_LENGTH = 256 ; /* max length of line for ascii data. */
tomwalters@0 16 int FIELDWIDTH = 0 ; /* field width for printf. */
tomwalters@0 17 /* (FIELDWIDTH=0 sets no extra fieldwidth. */
tomwalters@0 18 /* Positive integer fieldwidth sets right-justified */
tomwalters@0 19 /* columns, negative integer fieldwidth sets left- */
tomwalters@0 20 /* justified columns). */
tomwalters@0 21 int PRECISION = 3 ; /* precision (num decimal places) for printf, */
tomwalters@0 22 /* (PRECISION=0 sets integer output). */
tomwalters@0 23
tomwalters@0 24
tomwalters@0 25
tomwalters@0 26 /*
tomwalters@0 27 Return a file pointer to a file `name' opened to read.
tomwalters@0 28 If `name' is `-' then return stdin.
tomwalters@0 29 If file `name' is not found return null pointer.
tomwalters@0 30 */
tomwalters@0 31
tomwalters@0 32 FILE *fropen( name )
tomwalters@0 33 char *name ;
tomwalters@0 34 {
tomwalters@0 35 FILE *fopen() ;
tomwalters@0 36
tomwalters@0 37 if ( isstr( name, "-" ) ) return stdin ;
tomwalters@0 38 else return ( fopen( name, "r" ) ) ;
tomwalters@0 39 }
tomwalters@0 40
tomwalters@0 41
tomwalters@0 42 /*
tomwalters@0 43 Generic options handler and file opener.
tomwalters@0 44 Return a file pointer to an opened file, either stdin (if no args remained on
tomwalters@0 45 command line after scanning) or the first name left on the command line.
tomwalters@0 46 */
tomwalters@0 47
tomwalters@0 48 FILE *openopts( option, argc, argv )
tomwalters@0 49 Options *option ;
tomwalters@0 50 int argc ;
tomwalters@0 51 char *argv[] ;
tomwalters@0 52 {
tomwalters@0 53 FILE *fp ;
tomwalters@0 54 int i ;
tomwalters@0 55
tomwalters@0 56 if ( ( i = getopts( option, argc, argv ) ) == 0 )
tomwalters@0 57 return stdin ;
tomwalters@0 58 if ( ( fp = fropen( argv[argc-i] ) ) == (FILE *)0 ) {
tomwalters@0 59 fprintf(stderr, "%s: can't open %s\n", argv[0], argv[argc-i] ) ;
tomwalters@0 60 exit( 1 ) ;
tomwalters@0 61 }
tomwalters@0 62 return ( fp ) ;
tomwalters@0 63 }
tomwalters@0 64
tomwalters@0 65
tomwalters@0 66 /*
tomwalters@0 67 Options handler and two file opener.
tomwalters@0 68 If one file is on command line after scanning options, then the first file
tomwalters@0 69 fp1 is assumed to be the stdin. Otherwise two files are expected.
tomwalters@0 70 Return 0 if incorrect number of files, otherwise return 1.
tomwalters@0 71 (Note: fp1 and fp2 are pts to file ptrs, so pass them as &fp1, &fp2 if
tomwalters@0 72 originally declared as file ptrs).
tomwalters@0 73 */
tomwalters@0 74
tomwalters@0 75 open2opts( option, argc, argv, fp1, fp2 )
tomwalters@0 76 Options *option ;
tomwalters@0 77 int argc ;
tomwalters@0 78 char *argv[] ;
tomwalters@0 79 FILE **fp1 ;
tomwalters@0 80 FILE **fp2 ;
tomwalters@0 81 {
tomwalters@0 82 switch ( getopts( option, argc, argv ) ) {
tomwalters@0 83
tomwalters@0 84 case 1 :
tomwalters@0 85 *fp1 = stdin;
tomwalters@0 86 if ( ( *fp2 = fropen( argv[argc-1] ) ) == (FILE *)0 ) {
tomwalters@0 87 fprintf( stderr,"%s: can't open %s\n", argv[0], argv[argc-1] ) ;
tomwalters@0 88 exit( 1 ) ;
tomwalters@0 89 }
tomwalters@0 90 break ;
tomwalters@0 91 case 2 :
tomwalters@0 92 if ( ( *fp1 = fropen( argv[argc-2] ) ) == (FILE *)0 ) {
tomwalters@0 93 fprintf( stderr,"%s: can't open %s\n", argv[0], argv[argc-2] ) ;
tomwalters@0 94 exit( 1 ) ;
tomwalters@0 95 }
tomwalters@0 96 if ( ( *fp2 = fropen( argv[argc-1] ) ) == (FILE *)0 ) {
tomwalters@0 97 fprintf( stderr,"%s: can't open %s\n", argv[0], argv[argc-1] ) ;
tomwalters@0 98 exit( 1 ) ;
tomwalters@0 99 }
tomwalters@0 100 break ;
tomwalters@0 101 default :
tomwalters@0 102 return ( 0 ) ;
tomwalters@0 103 }
tomwalters@0 104 return ( 1 ) ;
tomwalters@0 105 }
tomwalters@0 106
tomwalters@0 107
tomwalters@0 108
tomwalters@0 109 /*
tomwalters@0 110 Build an options table.
tomwalters@0 111 First assign all the option values with the defaults given in the table.
tomwalters@0 112 Then scan the command line for arguments to overwrite corresponding vals.
tomwalters@0 113
tomwalters@0 114 Argument syntax is one of the following three types (or combinations).
tomwalters@0 115 Each syntax must contain either a leading '-' char or an embedded '=' char,
tomwalters@0 116 to distinguish arguments from possible filenames.
tomwalters@0 117
tomwalters@0 118
tomwalters@0 119 1) -<name> FLAG_SYNTAX
tomwalters@0 120 2) -<name>[=]<value> ARG_SYNTAX
tomwalters@0 121 3) [-]<name>=<value> EQ_SYNTAX
tomwalters@0 122
tomwalters@0 123 FLAG_SYNTAX takes no value. (The returned value is the empty string).
tomwalters@0 124
tomwalters@0 125 ARG_SYNTAX takes a value after an optional '=' char.
tomwalters@0 126 If the '=' char is not found, then the <value> is whatever follows the
tomwalters@0 127 longest matching <name> string. Otherwise the <value> is whatever follows
tomwalters@0 128 the '=' char. (The value is not allowed to be empty).
tomwalters@0 129
tomwalters@0 130 EQ_SYNTAX takes a value which is whatever follows the '=' char.
tomwalters@0 131 (The value is not allowed to be empty).
tomwalters@0 132
tomwalters@0 133 It is assumed that all args remaining on the command line after an arg with
tomwalters@0 134 invalid syntax must be filenames. These remain unscanned.
tomwalters@0 135 Return argc, the number of args remaining unscanned on the command line,
tomwalters@0 136 (argc=0 if no args left).
tomwalters@0 137 To scan the remainder of the command line, and (eg) print the filenames:-
tomwalters@0 138
tomwalters@0 139 if ( ( i = getopts( option, argc, argv, ) ) == 0 )
tomwalters@0 140 printf("stdin\n" );
tomwalters@0 141 else
tomwalters@0 142 for ( ; i>0 ; i--)
tomwalters@0 143 printf("[%s]\n", argv[argc-i] );
tomwalters@0 144
tomwalters@0 145 */
tomwalters@0 146
tomwalters@0 147
tomwalters@0 148 int getopts( option, argc, argv )
tomwalters@0 149 Options *option ;
tomwalters@0 150 int argc ;
tomwalters@0 151 char *argv[] ;
tomwalters@0 152 {
tomwalters@0 153 char *prog, *val ;
tomwalters@0 154 int i, n, index[64], span[64] ;
tomwalters@0 155
tomwalters@0 156 /* Assign option vals using the defaults */
tomwalters@0 157
tomwalters@0 158 for (i=0 ; option[i].name != (char *)0 ; i++)
tomwalters@0 159 *(option[i].val) = option[i].dflt ;
tomwalters@0 160
tomwalters@0 161 /* Overwrite option vals with corresponding vals found on command line */
tomwalters@0 162
tomwalters@0 163 prog = *argv ;
tomwalters@0 164 while ( --argc > 0 && ++argv ) {
tomwalters@0 165
tomwalters@0 166 /* find list of options all with longest matching name span */
tomwalters@0 167 /* returning if none, with argc args remaining */
tomwalters@0 168 if ( ( n = whichopt( option, *argv, index, span ) ) == 0 )
tomwalters@0 169 return ( argc ) ;
tomwalters@0 170
tomwalters@0 171 /* check arg syntax, returning if invalid with argc args remaining */
tomwalters@0 172 for ( i=0 ; i<n && ( val = checksyntax( *argv, span[i], option[index[i]].type ) ) == (char *)0 ; i++ )
tomwalters@0 173 ;
tomwalters@0 174 if ( val == (char *)0 )
tomwalters@0 175 return ( argc ) ;
tomwalters@0 176
tomwalters@0 177 /* if whichopt was ambiguous, yet an arg is valid, then its an */
tomwalters@0 178 /* ambiguous option, (and not a possible filename). */
tomwalters@0 179 if ( n > 1 ) {
tomwalters@0 180 fprintf(stderr,"%s: ambiguous option [%s]\n", prog, *argv ) ;
tomwalters@0 181 exit ( 1 ) ;
tomwalters@0 182 }
tomwalters@0 183
tomwalters@0 184 /* do operation */
tomwalters@0 185 operate( option, *index, val ) ;
tomwalters@0 186 side_effect( option, *index ) ;
tomwalters@0 187
tomwalters@0 188 }
tomwalters@0 189 return argc ;
tomwalters@0 190 }
tomwalters@0 191
tomwalters@0 192
tomwalters@0 193 /*
tomwalters@0 194 Find the default value of the first option whose name unambiguously matches
tomwalters@0 195 `s' (possibly abbreviated).
tomwalters@0 196 Return a ptr to the default value of the matching option.
tomwalters@0 197 Otherwise return the null ptr if a matching name is not found or is ambiguous.
tomwalters@0 198 */
tomwalters@0 199
tomwalters@0 200 char *optdflt( option, s )
tomwalters@0 201 Options *option ;
tomwalters@0 202 char *s ;
tomwalters@0 203 {
tomwalters@0 204 int i ;
tomwalters@0 205
tomwalters@0 206 if ( ( i = optindex( option, s ) ) < 0 )
tomwalters@0 207 return ( (char *)0 ) ;
tomwalters@0 208 return ( option[i].dflt ) ;
tomwalters@0 209 }
tomwalters@0 210
tomwalters@0 211 /*
tomwalters@0 212 Find the option whose name unambiguously matches `s' (possibly abbreviated).
tomwalters@0 213 Return the option list index of the matching option.
tomwalters@0 214 Otherwise return -1 if a matching name is not found, or -2 if the name is
tomwalters@0 215 ambiguous.
tomwalters@0 216 */
tomwalters@0 217
tomwalters@0 218 int optindex( option, s )
tomwalters@0 219 Options *option ;
tomwalters@0 220 char *s ;
tomwalters@0 221 {
tomwalters@0 222 int i, n, index[64], span[64] ;
tomwalters@0 223
tomwalters@0 224 if ( ( n = whichopt( option, s, index, span ) ) == 0 )
tomwalters@0 225 return (-1) ; /* option not found */
tomwalters@0 226 if ( n > 1 )
tomwalters@0 227 return (-2) ; /* option name ambiguous */
tomwalters@0 228 return ( *index ) ;
tomwalters@0 229 }
tomwalters@0 230
tomwalters@0 231
tomwalters@0 232 /*
tomwalters@0 233 Find the option whose name has the longest matching span with the head of `s'
tomwalters@0 234 (the argument string, possibly abbreviated or with trailing value parts).
tomwalters@0 235 Pass the option list index of the matching option back via arg `index'.
tomwalters@0 236 Pass the length of the matching span back via arg `span'.
tomwalters@0 237 Return the number of options found which have an equal longest matching span.
tomwalters@0 238 (Any `-' at the head of `s' is skipped before matching).
tomwalters@0 239 If there is an exact match (ie the longest matching span equals the length of
tomwalters@0 240 the option name) then return an unambiguous match.
tomwalters@0 241 */
tomwalters@0 242
tomwalters@0 243 int whichopt( option, s, index, span )
tomwalters@0 244 Options *option ;
tomwalters@0 245 char *s ;
tomwalters@0 246 int *index, *span ;
tomwalters@0 247 {
tomwalters@0 248 int i, j, n = 0, jmax = 0 ;
tomwalters@0 249
tomwalters@0 250 if ( *s == '-' ) s++ ; /* Skip leading hyphen */
tomwalters@0 251
tomwalters@0 252 for ( i = 0 ; option[i].name != (char *)0 ; i++ ) {
tomwalters@0 253
tomwalters@0 254 if ( ( j = streqspn( s, option[i].name ) ) > jmax ) {
tomwalters@0 255 jmax = j ; /* a new longest matching span */
tomwalters@0 256 n = 0 ;
tomwalters@0 257 index[n] = i ;
tomwalters@0 258 span[n++] = j ;
tomwalters@0 259 }
tomwalters@0 260 else if ( j > 0 && j == jmax ) { /* ambiguous name with same matching span */
tomwalters@0 261 index[n] = i ;
tomwalters@0 262 span[n++] = j ;
tomwalters@0 263 }
tomwalters@0 264 }
tomwalters@0 265
tomwalters@0 266 for ( i = 0 ; i < n ; i++ ) /* check for an exact match */
tomwalters@0 267 if ( span[i] == strlen( option[index[i]].name ) ) {
tomwalters@0 268 index[0] = index[i] ;
tomwalters@0 269 span[0] = span[i] ;
tomwalters@0 270 return 1 ;
tomwalters@0 271 }
tomwalters@0 272
tomwalters@0 273 return n ;
tomwalters@0 274 }
tomwalters@0 275
tomwalters@0 276
tomwalters@0 277 /*
tomwalters@0 278 Check arg syntax and return a pointer to the value part, (or a pointer to the
tomwalters@0 279 terminating null if the value part is empty).
tomwalters@0 280 Return a NULL pointer if the syntax is invalid. It is assumed then that the
tomwalters@0 281 current arg (and all remaining) is a filename.
tomwalters@0 282 Print a warning if the syntax is an error rather than a possible filename,
tomwalters@0 283 (the filename will not be found in this case).
tomwalters@0 284
tomwalters@0 285 The check is arranged so that different option syntax types can be OR'd.
tomwalters@0 286 */
tomwalters@0 287
tomwalters@0 288 char *checksyntax( s, span, type )
tomwalters@0 289 char *s ;
tomwalters@0 290 int span, type ;
tomwalters@0 291 {
tomwalters@0 292 int i ;
tomwalters@0 293 char *v, *val = (char *)0 ;
tomwalters@0 294
tomwalters@0 295 if ( bitset( type, FLAG_SYNTAX ) ) { /* -<name> */
tomwalters@0 296 if ( *s == '-' && *(v = s+1 + span) == '\0' )
tomwalters@0 297 val = v ;
tomwalters@0 298 }
tomwalters@0 299
tomwalters@0 300 if ( bitset( type, ARG_SYNTAX ) ) { /* -<name>[=]<value> */
tomwalters@0 301 if ( *s == '-' ) {
tomwalters@0 302 if ( *(v = s+1 + span) == '=' ) v++ ;
tomwalters@0 303 if ( *v != '\0' ) val = v ;
tomwalters@0 304 }
tomwalters@0 305 }
tomwalters@0 306
tomwalters@0 307 if ( bitset( type, EQ_SYNTAX ) ) { /* [-]<name>=<value> */
tomwalters@0 308 if ( *s == '-' ) s++ ;
tomwalters@0 309 if ( *(v = s + span) == '=' && *++v != '\0' )
tomwalters@0 310 val = v ;
tomwalters@0 311 }
tomwalters@0 312
tomwalters@0 313 return ( val ) ;
tomwalters@0 314 }
tomwalters@0 315
tomwalters@0 316
tomwalters@0 317 /*
tomwalters@0 318 Return 1 if string s a possible option, (ie. a string which is not a <number>,
tomwalters@0 319 and contains either an embedded '=' or a leading '-').
tomwalters@0 320 Otherwise return 0.
tomwalters@0 321 */
tomwalters@0 322
tomwalters@0 323 int isopt( s )
tomwalters@0 324 char *s ;
tomwalters@0 325 {
tomwalters@0 326 if ( isnumber( s ) ) return 0 ;
tomwalters@0 327 if ( *s == '-' ) return 1 ;
tomwalters@0 328 if ( strchr( s, '=' ) != (char *)0 ) return 1 ;
tomwalters@0 329 return 0 ;
tomwalters@0 330 }
tomwalters@0 331
tomwalters@0 332
tomwalters@0 333 operate( option, i, val )
tomwalters@0 334 Options *option ;
tomwalters@0 335 int i ;
tomwalters@0 336 char *val ;
tomwalters@0 337 {
tomwalters@0 338 if ( bitset( option[i].type, LATCH ) ) /* LATCH */
tomwalters@0 339 *(option[i].val) = val ;
tomwalters@0 340
tomwalters@0 341 else if ( bitset( option[i].type, AND ) ) /* AND */
tomwalters@0 342 *(option[i].val) = offstr ;
tomwalters@0 343
tomwalters@0 344 else if ( bitset( option[i].type, OR ) ) /* OR */
tomwalters@0 345 *(option[i].val) = onstr ;
tomwalters@0 346
tomwalters@0 347 else if ( bitset( option[i].type, TOGGLE ) ) { /* TOGGLE */
tomwalters@0 348 if ( isempty( val ) ) {
tomwalters@0 349 if ( ison( *(option[i].val) ) )
tomwalters@0 350 *(option[i].val) = offstr ;
tomwalters@0 351 else
tomwalters@0 352 *(option[i].val) = onstr ;
tomwalters@0 353 }
tomwalters@0 354 else *(option[i].val) = val ;
tomwalters@0 355 }
tomwalters@0 356 }
tomwalters@0 357
tomwalters@0 358
tomwalters@0 359 /*
tomwalters@0 360 Side-effects of options type specifiers.
tomwalters@0 361 */
tomwalters@0 362
tomwalters@0 363 side_effect( option, j )
tomwalters@0 364 Options *option ;
tomwalters@0 365 int j ;
tomwalters@0 366 {
tomwalters@0 367 int i ;
tomwalters@0 368 char *exstr ;
tomwalters@0 369
tomwalters@0 370 if ( bitset( option[j].type, EXCLUDE ) ) { /* EXCLUDE */
tomwalters@0 371 if ( ison( *(option[j].val) ) )
tomwalters@0 372 exstr = offstr ;
tomwalters@0 373 else
tomwalters@0 374 exstr = onstr ;
tomwalters@0 375 for ( i=0; option[i].name != (char *)0 ; i++)
tomwalters@0 376 if ( i != j && bitset( option[i].type, EXCLUDE ) )
tomwalters@0 377 *(option[i].val) = exstr ;
tomwalters@0 378 }
tomwalters@0 379 }
tomwalters@0 380
tomwalters@0 381
tomwalters@0 382
tomwalters@0 383 /*
tomwalters@0 384 Separate an option value string `optval' into two string tokens at the first
tomwalters@0 385 occurrence of a separator character `sep'. (Given as a string of one char).
tomwalters@0 386 Return the tokens via the pointers `val1' and `val2' (which could be passed
tomwalters@0 387 as the addresses of string pointers).
tomwalters@0 388 Return BADVAL if the option value string is bad (meaning that either `optval' was
tomwalters@0 389 null or empty, or the separator char was found but the 2nd token was missing).
tomwalters@0 390 Return 1 if the option value string is good (meaning that either two tokens
tomwalters@0 391 were found, or only the 1st token with no separator char, in which case `val2'
tomwalters@0 392 will be a ptr to an empty string). (See routine strpsep()).
tomwalters@0 393 */
tomwalters@0 394
tomwalters@0 395 int getvals( optval, val1, val2, sep )
tomwalters@0 396 char *optval ;
tomwalters@0 397 char **val1, **val2 ;
tomwalters@0 398 char *sep ;
tomwalters@0 399 {
tomwalters@0 400 *val1 = optval ;
tomwalters@0 401 if ( isnull( *val2 = strsep( optval, sep ) ) )
tomwalters@0 402 return BADVAL ;
tomwalters@0 403 return 1 ;
tomwalters@0 404 }
tomwalters@0 405
tomwalters@0 406
tomwalters@0 407 /*
tomwalters@0 408 Parse a range selector of the form: a[-b]
tomwalters@0 409 Return 0 if bad selectors, otherwise return 1.
tomwalters@0 410 Items are numbered 1,2,...,max, (where max is 0 by convention).
tomwalters@0 411 When either limit is "min", then set the respective value to 1.
tomwalters@0 412 When either limit is "max", then set the respective value to 0.
tomwalters@0 413 When `b' is missing, then set b=a.
tomwalters@0 414
tomwalters@0 415 If (a==0) then seek eof and process the final item.
tomwalters@0 416 Else seek past (a-1) items, and then process the next (b-a+1) items
tomwalters@0 417 (or all items until eof if (b==0)).
tomwalters@0 418 Eg:
tomwalters@0 419 seekstart( a-1, bytes, fp ) ;
tomwalters@0 420 for ( i = 0 ; ( b == 0 || i < b-a+1 ) ; i++ )
tomwalters@0 421 do process
tomwalters@0 422
tomwalters@0 423 */
tomwalters@0 424
tomwalters@0 425 int selector( s, a, b )
tomwalters@0 426 char *s ;
tomwalters@0 427 int *a, *b ;
tomwalters@0 428 {
tomwalters@0 429 char *val1, *val2 ;
tomwalters@0 430
tomwalters@0 431 if ( getvals( s, &val1, &val2, "-" ) == BADVAL )
tomwalters@0 432 return ( 0 ) ;
tomwalters@0 433 if ( ismin( val1 ) ) *a = 1 ; /* first object */
tomwalters@0 434 else if ( ismax( val1 ) ) *a = 0 ; /* last object */
tomwalters@0 435 else if ( ( *a = atoi( val1 ) ) <= 0 ) { /* intermediate object */
tomwalters@0 436 if ( *a == 0 ) fprintf( stderr,"warning: selected items are numbered 1,...,max\n" ) ;
tomwalters@0 437 return ( 0 ) ;
tomwalters@0 438 }
tomwalters@0 439 if ( isempty( val2 ) ) *b = *a ; /* single object */
tomwalters@0 440 else if ( ismin( val2 ) ) *b = 1 ;
tomwalters@0 441 else if ( ismax( val2 ) ) *b = 0 ;
tomwalters@0 442 else if ( ( *b = atoi( val2 ) ) <= 0 ) {
tomwalters@0 443 return ( 0 ) ;
tomwalters@0 444 }
tomwalters@0 445 if ( *b > 0 && ( *a == 0 || *a > *b ) )
tomwalters@0 446 return ( 0 ) ;
tomwalters@0 447
tomwalters@0 448 return ( 1 ) ;
tomwalters@0 449 }
tomwalters@0 450
tomwalters@0 451
tomwalters@0 452 /*
tomwalters@0 453 Parse a time range selector of the form: a[-b]
tomwalters@0 454 The range is returned as limits meaning: start==a duration==b-a+1.
tomwalters@0 455 (Note: when range=max or range=max-max then a==b==(-1) and duration==1).
tomwalters@0 456 Return 0 if bad selectors, otherwise return 1.
tomwalters@0 457 Time is numbered 0,2,...,max, (where max is (-1) by convention).
tomwalters@0 458 When either limit is "min", then set the respective value to 0.
tomwalters@0 459 When either limit is "max", then set the respective value to (-1).
tomwalters@0 460 When `b' is missing, then set b=a.
tomwalters@0 461 Time is specified as <number>[<units>], where <units> = {p, ms, s}.
tomwalters@0 462 Empty units are interpreted as `p' (ie sample points).
tomwalters@0 463 Convert `a' and `b' to sample points using the given samplerate.
tomwalters@0 464
tomwalters@0 465 (Note: this is like selector() but using to_p() instead of atoi(), and
tomwalters@0 466 numbering from 0 instead of 1).
tomwalters@0 467
tomwalters@0 468 If (a<0) then seek eof and process the final item.
tomwalters@0 469 Else seek past (a) items, and then process the next (b-a+1) items
tomwalters@0 470 (or all items until eof if (b==-1)).
tomwalters@0 471 Eg:
tomwalters@0 472 seekstart( a, bytes, fp ) ;
tomwalters@0 473 for ( i = 0 ; ( b < 0 || i < b-a+1 ) ; i++ )
tomwalters@0 474 do process
tomwalters@0 475
tomwalters@0 476 */
tomwalters@0 477
tomwalters@0 478 int range( s, a, b, samplerate )
tomwalters@0 479 char *s ;
tomwalters@0 480 int *a, *b ;
tomwalters@0 481 int samplerate ;
tomwalters@0 482 {
tomwalters@0 483 char *val1, *val2 ;
tomwalters@0 484
tomwalters@0 485 if ( getvals( s, &val1, &val2, "-" ) == BADVAL )
tomwalters@0 486 return ( 0 ) ;
tomwalters@0 487 if ( ismin( val1 ) ) *a = 0 ; /* first object */
tomwalters@0 488 else if ( ismax( val1 ) ) *a = (-1) ; /* last object */
tomwalters@0 489 else if ( ( *a = to_p( val1, samplerate ) ) < 0 ) {
tomwalters@0 490 return ( 0 ) ;
tomwalters@0 491 }
tomwalters@0 492 if ( isempty( val2 ) ) *b = *a ; /* single object */
tomwalters@0 493 else if ( ismin( val2 ) ) *b = 0 ;
tomwalters@0 494 else if ( ismax( val2 ) ) *b = (-1) ;
tomwalters@0 495 else if ( ( *b = to_p( val2, samplerate ) ) < 0 ) {
tomwalters@0 496 return ( 0 ) ;
tomwalters@0 497 }
tomwalters@0 498 if ( *b >= 0 && ( *a < 0 || *a > *b ) )
tomwalters@0 499 return ( 0 ) ;
tomwalters@0 500
tomwalters@0 501 return ( 1 ) ;
tomwalters@0 502 }
tomwalters@0 503
tomwalters@0 504
tomwalters@0 505 /*
tomwalters@0 506 Seek n items of size bytes from current position in stream.
tomwalters@0 507 (Unlike fseek, this works even when fp is stdin).
tomwalters@0 508 Return the number of items actually read.
tomwalters@0 509 Example: seekstart( n, sizeof(short), fp );
tomwalters@0 510 Datatype "ASCII" is a special case for which 0 is returned by the databytes
tomwalters@0 511 routine, so bytes==0 is taken to mean seek n ascii lines. In general use:
tomwalters@0 512 seekstart( n, databytes( typestr ), fp )
tomwalters@0 513 */
tomwalters@0 514
tomwalters@0 515 seekstart( n, bytes, fp )
tomwalters@0 516 int n, bytes ;
tomwalters@0 517 FILE *fp ;
tomwalters@0 518 {
tomwalters@0 519 int i ;
tomwalters@0 520 char *buf ;
tomwalters@0 521 char *line ;
tomwalters@0 522
tomwalters@0 523 if ( bytes == 0 ) { /* special case meaning ascii lines */
tomwalters@0 524 line = (char *)malloc( LINE_LENGTH ) ;
tomwalters@0 525 for ( i = 0 ; i < n && fgets( line, LINE_LENGTH, fp ) != (char *)0 ; i++ )
tomwalters@0 526 ;
tomwalters@0 527 free( line ) ;
tomwalters@0 528 return ( i ) ;
tomwalters@0 529 }
tomwalters@0 530
tomwalters@0 531 if ( fp != stdin ) {
tomwalters@0 532 if ( fseek( fp, (long)( n * bytes ), 1 ) == 0 )
tomwalters@0 533 return n ; /* if improper, look for any input */
tomwalters@0 534 }
tomwalters@0 535
tomwalters@0 536 if ( ( buf = (char *)malloc( bytes ) ) == (char *)0 ) {
tomwalters@0 537 fprintf( stderr, "seekstart: cannot allocate %d bytes\n", bytes ) ;
tomwalters@0 538 exit( 1 ) ;
tomwalters@0 539 }
tomwalters@0 540
tomwalters@0 541 for ( i = 0 ; i < n && fread( buf, bytes, 1, fp ) ; i++ )
tomwalters@0 542 ;
tomwalters@0 543 free( buf ) ;
tomwalters@0 544
tomwalters@0 545 return ( i ) ;
tomwalters@0 546 }
tomwalters@0 547
tomwalters@0 548
tomwalters@0 549 /*
tomwalters@0 550 Seek n items of of given type from current position in stream.
tomwalters@0 551 This seekstart version takes a `type' arg instead of a size in `bytes'.
tomwalters@0 552 The `type' is an index to the datatype list in options.h, obtained for
tomwalters@0 553 example using: typeindex( typestr ).
tomwalters@0 554 */
tomwalters@0 555
tomwalters@0 556 seektype( n, type, fp )
tomwalters@0 557 int n, type ;
tomwalters@0 558 FILE *fp ;
tomwalters@0 559 {
tomwalters@0 560 return ( seekstart( n, typebytes( type ), fp ) ) ;
tomwalters@0 561 }
tomwalters@0 562
tomwalters@0 563
tomwalters@0 564 /*
tomwalters@0 565 Read the next n items of `type' from the given stream.
tomwalters@0 566 The `type' is an index to the datatype list in options.h, obtained for
tomwalters@0 567 example using: typeindex( typestr ).
tomwalters@0 568 Assign the item as a float in address `y', and return 1.
tomwalters@0 569 Return 0 if eof or error.
tomwalters@0 570 This can replace fread, eg:
tomwalters@0 571 fread( &p, sizeof(short), 1, fp ) ( with short p )
tomwalters@0 572 becomes:
tomwalters@0 573 readitem( &y, typeindex( "short" ), 1, fp ) ( with float y )
tomwalters@0 574 */
tomwalters@0 575
tomwalters@0 576 readitem( y, type, n, fp )
tomwalters@0 577 float *y ;
tomwalters@0 578 int type ;
tomwalters@0 579 int n ;
tomwalters@0 580 FILE *fp ;
tomwalters@0 581 {
tomwalters@0 582 char c ; short s ; int i ; float f ; double d ;
tomwalters@0 583 int j ;
tomwalters@0 584 static char *line ;
tomwalters@0 585 static int first = 1 ;
tomwalters@0 586
tomwalters@0 587 switch ( type ) {
tomwalters@0 588 case 0 : for ( j = 0 ; j < n ; j++ ) {
tomwalters@0 589 if ( fread( &c, sizeof(char), 1, fp ) == 0 ) return 0 ;
tomwalters@0 590 *y++ = (float)c ;
tomwalters@0 591 }
tomwalters@0 592 break ;
tomwalters@0 593 case 1 : for ( j = 0 ; j < n ; j++ ) {
tomwalters@0 594 if ( fread( &s, sizeof(short), 1, fp ) == 0 ) return 0 ;
tomwalters@0 595 *y++ = (float)s ;
tomwalters@0 596 }
tomwalters@0 597 break ;
tomwalters@0 598 case 2 : for ( j = 0 ; j < n ; j++ ) {
tomwalters@0 599 if ( fread( &i, sizeof(int), 1, fp ) == 0 ) return 0 ;
tomwalters@0 600 *y++ = (float)i ;
tomwalters@0 601 }
tomwalters@0 602 break ;
tomwalters@0 603 case 3 : for ( j = 0 ; j < n ; j++ ) {
tomwalters@0 604 if ( fread( &f, sizeof(float), 1, fp ) == 0 ) return 0 ;
tomwalters@0 605 *y++ = (float)f ;
tomwalters@0 606 }
tomwalters@0 607 break ;
tomwalters@0 608 case 4 : for ( j = 0 ; j < n ; j++ ) {
tomwalters@0 609 if ( fread( &d, sizeof(double), 1, fp ) == 0 ) return 0 ;
tomwalters@0 610 *y++ = (float)d ;
tomwalters@0 611 }
tomwalters@0 612 break ;
tomwalters@0 613 case 5 :
tomwalters@0 614 case 6 : if ( first ) {
tomwalters@0 615 line = (char *)malloc( LINE_LENGTH ) ;
tomwalters@0 616 first = 0 ;
tomwalters@0 617 }
tomwalters@0 618 for ( j = 0 ; j < n ; j++ ) {
tomwalters@0 619 if ( fgets( line, LINE_LENGTH, fp ) == (char *)0 ) return 0 ;
tomwalters@0 620 *y++ = atof( line ) ;
tomwalters@0 621 }
tomwalters@0 622 break ;
tomwalters@0 623 }
tomwalters@0 624 return 1 ;
tomwalters@0 625 }
tomwalters@0 626
tomwalters@0 627
tomwalters@0 628 /*
tomwalters@0 629 Write the given n items of `type' onto the given stream.
tomwalters@0 630 The `type' is an index to the datatype list in options.h, (obtained for
tomwalters@0 631 example using: typeindex( typestr ) ).
tomwalters@0 632 */
tomwalters@0 633
tomwalters@0 634 writeitem( y, type, n, fp )
tomwalters@0 635 float *y ;
tomwalters@0 636 int type ;
tomwalters@0 637 int n ;
tomwalters@0 638 FILE *fp ;
tomwalters@0 639 {
tomwalters@0 640 char c ; short s ; int i ; float f ; double d ;
tomwalters@0 641 int j ;
tomwalters@0 642
tomwalters@0 643 switch ( type ) {
tomwalters@0 644 case 0 : for ( j = 0 ; j < n ; j++ ) {
tomwalters@0 645 c = (char) *y++ ;
tomwalters@0 646 fwrite( &c, sizeof(char), 1, fp ) ;
tomwalters@0 647 }
tomwalters@0 648 break ;
tomwalters@0 649 case 1 : for ( j = 0 ; j < n ; j++ ) {
tomwalters@0 650 s = (short) *y++ ;
tomwalters@0 651 fwrite( &s, sizeof(short), 1, fp ) ;
tomwalters@0 652 }
tomwalters@0 653 break ;
tomwalters@0 654 case 2 : for ( j = 0 ; j < n ; j++ ) {
tomwalters@0 655 i = (int) *y++ ;
tomwalters@0 656 fwrite( &i, sizeof(int), 1, fp ) ;
tomwalters@0 657 }
tomwalters@0 658 break ;
tomwalters@0 659 case 3 : for ( j = 0 ; j < n ; j++ ) {
tomwalters@0 660 f = (float) *y++ ;
tomwalters@0 661 fwrite( &f, sizeof(float), 1, fp ) ;
tomwalters@0 662 }
tomwalters@0 663 break ;
tomwalters@0 664 case 4 : for ( j = 0 ; j < n ; j++ ) {
tomwalters@0 665 d = (double) *y++ ;
tomwalters@0 666 fwrite( &d, sizeof(double), 1, fp ) ;
tomwalters@0 667 }
tomwalters@0 668 break ;
tomwalters@0 669 case 5 :
tomwalters@0 670 case 6 : for ( j = 0 ; j < n ; j++ )
tomwalters@0 671 fprintf( fp, "%*.*f\n", FIELDWIDTH, PRECISION, *y++ ) ;
tomwalters@0 672 break ;
tomwalters@0 673 }
tomwalters@0 674 }
tomwalters@0 675
tomwalters@0 676
tomwalters@0 677 /*
tomwalters@0 678 Read the next n items of `type' from the given stream within inclusive range
tomwalters@0 679 limits `a' and `b', (found using, eg: range( rangestr, &a, &b, samplerate ) ).
tomwalters@0 680 This is a version of readitem which incorporates the intial seek and handles
tomwalters@0 681 range=max correctly.
tomwalters@0 682 The `type' is an index to the datatype list in options.h, obtained for
tomwalters@0 683 example using: typeindex( typestr ).
tomwalters@0 684 Assign the item as a float in address `y', and return the number of items
tomwalters@0 685 read. Return 0 if eof or error.
tomwalters@0 686 */
tomwalters@0 687
tomwalters@0 688 nextitem( y, type, n, fp, a, b )
tomwalters@0 689 float *y ;
tomwalters@0 690 int type ;
tomwalters@0 691 int n ;
tomwalters@0 692 FILE *fp ;
tomwalters@0 693 int a, b ;
tomwalters@0 694 {
tomwalters@0 695 static int count = 0 ; /* total items read over all calls */
tomwalters@0 696 int num ; /* number items read this call */
tomwalters@0 697 float x ;
tomwalters@0 698
tomwalters@0 699 if ( count == 0 ) {
tomwalters@0 700
tomwalters@0 701 if ( a == (-1) ) { /* range=max or range=max-max */
tomwalters@0 702 if ( n == 1 && readitem( &x, type, 1, fp ) ) {
tomwalters@0 703 *y = x ;
tomwalters@0 704 while ( readitem( &x, type, 1, fp ) )
tomwalters@0 705 *y = x ;
tomwalters@0 706 num = 1 ;
tomwalters@0 707 }
tomwalters@0 708 else num = 0 ;
tomwalters@0 709 }
tomwalters@0 710
tomwalters@0 711 else {
tomwalters@0 712 if ( seektype( a, type, fp ) < a )
tomwalters@0 713 num = 0 ;
tomwalters@0 714 else {
tomwalters@0 715 if ( b >= 0 && n > b-a+1 ) /* n restricted by upper limit */
tomwalters@0 716 n = b-a+1 ;
tomwalters@0 717 for ( num = 0 ; num < n && readitem( &x, type, 1, fp ) ; num++ )
tomwalters@0 718 y[num] = x ;
tomwalters@0 719 }
tomwalters@0 720 }
tomwalters@0 721
tomwalters@0 722 count += num ;
tomwalters@0 723 }
tomwalters@0 724
tomwalters@0 725 else {
tomwalters@0 726 if ( b >= 0 && count >= b-a+1 )
tomwalters@0 727 num = 0 ;
tomwalters@0 728 else {
tomwalters@0 729 if ( b >= 0 && n > b-a+1 - count ) /* n restricted by upper limit */
tomwalters@0 730 n = b-a+1 - count ;
tomwalters@0 731 for ( num = 0 ; num < n && readitem( &x, type, 1, fp ) ; num++ )
tomwalters@0 732 y[num] = x ;
tomwalters@0 733 }
tomwalters@0 734
tomwalters@0 735 count += num ;
tomwalters@0 736 }
tomwalters@0 737
tomwalters@0 738 return num ;
tomwalters@0 739 }
tomwalters@0 740
tomwalters@0 741
tomwalters@0 742
tomwalters@0 743
tomwalters@0 744 /*
tomwalters@0 745 Return the type index (to the datatype list in options.h) of the given type
tomwalters@0 746 string. String matching allows for abbreviations.
tomwalters@0 747 If the given type string is in error then return an error code (less than 0):
tomwalters@0 748 -1 type string not found in datatype list.
tomwalters@0 749 -2 type string is ambiguous.
tomwalters@0 750 */
tomwalters@0 751
tomwalters@0 752 int typeindex( typestr )
tomwalters@0 753 char *typestr ;
tomwalters@0 754 {
tomwalters@0 755 return ( listindex( datatype, typestr ) ) ;
tomwalters@0 756 }
tomwalters@0 757
tomwalters@0 758
tomwalters@0 759 /*
tomwalters@0 760 Return a number of bytes for a given type index (to the datatype list in
tomwalters@0 761 options.h). Datatype "ASCII" is a special case for which 0 is returned.
tomwalters@0 762 */
tomwalters@0 763
tomwalters@0 764 int typebytes( type )
tomwalters@0 765 int type ;
tomwalters@0 766 {
tomwalters@0 767 int bytes ;
tomwalters@0 768
tomwalters@0 769 switch ( type ) {
tomwalters@0 770 case 0 : bytes = sizeof( char ) ; break ;
tomwalters@0 771 case 1 : bytes = sizeof( short ) ; break ;
tomwalters@0 772 case 2 : bytes = sizeof( int ) ; break ;
tomwalters@0 773 case 3 : bytes = sizeof( float ) ; break ;
tomwalters@0 774 case 4 : bytes = sizeof( double ) ; break ;
tomwalters@0 775 case 5 : /* ASCII */
tomwalters@0 776 case 6 : bytes = 0 ; break ; /* ascii */
tomwalters@0 777 }
tomwalters@0 778 return ( bytes ) ;
tomwalters@0 779 }
tomwalters@0 780
tomwalters@0 781
tomwalters@0 782
tomwalters@0 783 /*
tomwalters@0 784 Return a number of bytes for a given type string.
tomwalters@0 785 The string can be a number (of bytes), or a token from the `datatype' list,
tomwalters@0 786 (see options.h) with which it is matched, allowing for abbreviations.
tomwalters@0 787 Datatype "ASCII" or "ascii" is a special case for which 0 is returned.
tomwalters@0 788 If the given type string is in error then return an error code (less than 0):
tomwalters@0 789 -1 type string not found in datatype list.
tomwalters@0 790 -2 type string is ambiguous.
tomwalters@0 791 -3 type string is a negative number.
tomwalters@0 792 */
tomwalters@0 793
tomwalters@0 794 int databytes( typestr )
tomwalters@0 795 char *typestr ;
tomwalters@0 796 {
tomwalters@0 797 int type, bytes ;
tomwalters@0 798
tomwalters@0 799 if ( isnumber( typestr ) ) { /* case of bytes number string */
tomwalters@0 800 if ( ( bytes = atoi( typestr ) ) < 0 )
tomwalters@0 801 return ( -3 ) ;
tomwalters@0 802 else return bytes ;
tomwalters@0 803 }
tomwalters@0 804
tomwalters@0 805 if ( ( type = typeindex( typestr ) ) < 0 )
tomwalters@0 806 return type ;
tomwalters@0 807
tomwalters@0 808 return ( typebytes( type ) ) ;
tomwalters@0 809 }
tomwalters@0 810
tomwalters@0 811
tomwalters@0 812 /*
tomwalters@0 813 Check for over or underflow when the given float is scaled and cast into the
tomwalters@0 814 given data type (an index to the datatype list in options.h).
tomwalters@0 815 Return a more appropriate scale factor, or a scale factor of 1 if no over
tomwalters@0 816 or underflow. The returned scale factor is the minimum scale factor over
tomwalters@0 817 a succession of calls to check_overflow.
tomwalters@0 818 */
tomwalters@0 819
tomwalters@0 820 float check_overflow( p, scale, type )
tomwalters@0 821 float p, scale ;
tomwalters@0 822 int type ;
tomwalters@0 823 {
tomwalters@0 824 float f, p1 = p * scale ;
tomwalters@0 825 static float first = 1 ;
tomwalters@0 826 static float max, newscale ;
tomwalters@0 827
tomwalters@0 828 if ( type >= 3 ) return ( 1. ) ;
tomwalters@0 829
tomwalters@0 830 if ( first ) {
tomwalters@0 831
tomwalters@0 832 switch ( type ) {
tomwalters@0 833 case 0 : max = pow( 2., 8.*sizeof(char)-1 ) - 1 ; break ;
tomwalters@0 834 case 1 : max = pow( 2., 8.*sizeof(short)-1 ) - 1 ; break ;
tomwalters@0 835 case 2 : max = pow( 2., 8.*sizeof(int)-1 ) - 1 ; break ;
tomwalters@0 836 }
tomwalters@0 837
tomwalters@0 838 newscale = 1. ;
tomwalters@0 839 first = 0 ;
tomwalters@0 840 }
tomwalters@0 841
tomwalters@0 842 if ( p1 > max ) f = max / p ;
tomwalters@0 843 else if ( p1 < (-max) ) f = -( max / p ) ;
tomwalters@0 844 else f = 1. ;
tomwalters@0 845
tomwalters@0 846 if ( f < newscale )
tomwalters@0 847 newscale = f ;
tomwalters@0 848
tomwalters@0 849 return ( newscale ) ;
tomwalters@0 850 }
tomwalters@0 851
tomwalters@0 852
tomwalters@0 853
tomwalters@0 854 /*
tomwalters@0 855 Some particular string tests.
tomwalters@0 856 */
tomwalters@0 857
tomwalters@0 858
tomwalters@0 859 /*
tomwalters@0 860 Test for "on" or any <number> string other than "0".
tomwalters@0 861 */
tomwalters@0 862
tomwalters@0 863 int ison( s )
tomwalters@0 864 char *s ;
tomwalters@0 865 {
tomwalters@0 866 return ( strcmp( "on", s ) == 0 || ( isnumber( s ) && strcmp( "0", s ) != 0 ) ) ;
tomwalters@0 867 }
tomwalters@0 868
tomwalters@0 869 /*
tomwalters@0 870 Test for "off" or "0".
tomwalters@0 871 */
tomwalters@0 872
tomwalters@0 873 int isoff( s )
tomwalters@0 874 char *s ;
tomwalters@0 875 {
tomwalters@0 876 return ( strcmp( "off", s ) == 0 || strcmp( "0", s ) == 0 ) ;
tomwalters@0 877 }
tomwalters@0 878
tomwalters@0 879 /*
tomwalters@0 880 Test for "min".
tomwalters@0 881 */
tomwalters@0 882
tomwalters@0 883 int ismin( s )
tomwalters@0 884 char *s ;
tomwalters@0 885 {
tomwalters@0 886 return ( strcmp( "min", s ) == 0 ) ;
tomwalters@0 887 }
tomwalters@0 888
tomwalters@0 889 /*
tomwalters@0 890 Test for "max".
tomwalters@0 891 */
tomwalters@0 892
tomwalters@0 893 int ismax( s )
tomwalters@0 894 char *s ;
tomwalters@0 895 {
tomwalters@0 896 return ( strcmp( "max", s ) == 0 ) ;
tomwalters@0 897 }
tomwalters@0 898
tomwalters@0 899
tomwalters@0 900
tomwalters@0 901
tomwalters@0 902 /*************************************************************************/
tomwalters@0 903
tomwalters@0 904 /*
tomwalters@0 905 Print help for user
tomwalters@0 906 help=on or -help gets standard help for all except SILENT options.
tomwalters@0 907 help=all gets standard help for all options.
tomwalters@0 908 help=syntax gets help with syntax instead of comment for all except SILENT.
tomwalters@0 909 help=<name> gets help for the named option (which can be abbreviated).
tomwalters@0 910 */
tomwalters@0 911
tomwalters@0 912
tomwalters@0 913 /*
tomwalters@0 914 types of helpopts (see defines in options.h)
tomwalters@0 915
tomwalters@0 916 helpopts standard usage, exit when done
tomwalters@0 917 helpopts1 standard usage, supplied function for exit or additional help
tomwalters@0 918 helpopts2 supplied usage and function for exit or additional help
tomwalters@0 919 helpopts3 supplied usage, exit when done
tomwalters@0 920 */
tomwalters@0 921
tomwalters@0 922
tomwalters@0 923 gethelp( helpstr, prog, applic, usage, option, tail )
tomwalters@0 924 char *helpstr ;
tomwalters@0 925 char *prog ;
tomwalters@0 926 char *applic ;
tomwalters@0 927 char *usage ;
tomwalters@0 928 Options *option ;
tomwalters@0 929 int (*tail)() ; /* function for exit or additional help */
tomwalters@0 930 {
tomwalters@0 931 int i, index[64], span[64] ;
tomwalters@0 932
tomwalters@0 933 if ( isempty( helpstr ) || ison( helpstr ) || isstr( helpstr, "all" ) || isstr( helpstr, "syntax" ) )
tomwalters@0 934 help( prog, applic, usage, option, isstr( helpstr, "all" ), isstr( helpstr, "syntax" ) ) ;
tomwalters@0 935 else {
tomwalters@0 936 i = whichopt( option, helpstr, index, span ) ;
tomwalters@0 937 if ( i == 0 )
tomwalters@0 938 fprintf(stderr,"%s: unknown option [%s]\n", prog, helpstr ) ;
tomwalters@0 939 else if ( i > 1 )
tomwalters@0 940 fprintf(stderr,"%s: ambiguous option [%s]\n", prog, helpstr ) ;
tomwalters@0 941 else
tomwalters@0 942 helpshot( option[*index] ) ; /* single-line help i'th option */
tomwalters@0 943 }
tomwalters@0 944 (*tail)() ;
tomwalters@0 945 }
tomwalters@0 946
tomwalters@0 947
tomwalters@0 948
tomwalters@0 949 help( prog, applic, usage, option, all, syntax )
tomwalters@0 950 char *prog, *applic, *usage ;
tomwalters@0 951 Options *option ;
tomwalters@0 952 int all, syntax ;
tomwalters@0 953 {
tomwalters@0 954 int i ;
tomwalters@0 955 char *which_syntax();
tomwalters@0 956
tomwalters@0 957 if ( usage == (char *)0 ) /* a standard usage */
tomwalters@0 958 printf( "%s: %s\nUsage: %s [arguments] [file]\n", prog, applic, prog );
tomwalters@0 959 else
tomwalters@0 960 printf( "%s: %s\nUsage: %s\n", prog, applic, usage );
tomwalters@0 961
tomwalters@0 962 if ( num_printed_opts( option, all ) > 0 ) {
tomwalters@0 963 printf("name default comment\n");
tomwalters@0 964 printf("---------- ---------- --------.... \n");
tomwalters@0 965 }
tomwalters@0 966 for (i=0 ; option[i].name != (char *)0 ; i++) {
tomwalters@0 967 if ( !bitset( option[i].type, SILENT ) || all ) {
tomwalters@0 968 if ( syntax )
tomwalters@0 969 syntaxline( option[i] ) ;
tomwalters@0 970 else
tomwalters@0 971 helpline( option[i] ) ;
tomwalters@0 972 }
tomwalters@0 973 }
tomwalters@0 974 }
tomwalters@0 975
tomwalters@0 976
tomwalters@0 977 helpline( option )
tomwalters@0 978 Options option ;
tomwalters@0 979 {
tomwalters@0 980 printf("%-10s ", option.name );
tomwalters@0 981 printf("%-10s ", option.dflt );
tomwalters@0 982 printf("%s\n" , option.help );
tomwalters@0 983 }
tomwalters@0 984
tomwalters@0 985 syntaxline( option )
tomwalters@0 986 Options option ;
tomwalters@0 987 {
tomwalters@0 988 char *which_syntax();
tomwalters@0 989
tomwalters@0 990 printf("%-10s ", option.name );
tomwalters@0 991 printf("%-10s ", option.dflt );
tomwalters@0 992 printf("%s\n" , which_syntax( option.type ) );
tomwalters@0 993 }
tomwalters@0 994
tomwalters@0 995
tomwalters@0 996 helpshot( option )
tomwalters@0 997 Options option ;
tomwalters@0 998 {
tomwalters@0 999 char *which_syntax();
tomwalters@0 1000
tomwalters@0 1001 printf("name: %s\n", option.name );
tomwalters@0 1002 printf("default: %s\n", option.dflt );
tomwalters@0 1003 printf("syntax: %s\n", which_syntax( option.type ) );
tomwalters@0 1004 printf("comment: %s\n", option.help );
tomwalters@0 1005 }
tomwalters@0 1006
tomwalters@0 1007
tomwalters@0 1008 /*
tomwalters@0 1009 Return the number of options which will get printed by help
tomwalters@0 1010 */
tomwalters@0 1011
tomwalters@0 1012 int num_printed_opts( option, all )
tomwalters@0 1013 Options *option ;
tomwalters@0 1014 int all ;
tomwalters@0 1015 {
tomwalters@0 1016 int i, j=0 ;
tomwalters@0 1017
tomwalters@0 1018 for (i=0 ; option[i].name != (char *)0 ; i++)
tomwalters@0 1019 if ( !bitset( option[i].type, SILENT ) )
tomwalters@0 1020 j++ ;
tomwalters@0 1021 if ( all ) return ( i ) ; /* num all options */
tomwalters@0 1022 else return ( j ) ; /* num non-SILENT options */
tomwalters@0 1023 }
tomwalters@0 1024
tomwalters@0 1025
tomwalters@0 1026 char *which_syntax( type )
tomwalters@0 1027 int type ;
tomwalters@0 1028 {
tomwalters@0 1029 if ( bitsset( type, ALL_SYNTAX ) ) return (char *)( All_Syntax ) ;
tomwalters@0 1030 if ( bitsset( type, VAL_SYNTAX ) ) return (char *)( Val_Syntax ) ;
tomwalters@0 1031 if ( bitsset( type, TOGGLE_SYNTAX ) ) return (char *)( Toggle_Syntax ) ;
tomwalters@0 1032 if ( bitsset( type, ONOFF_SYNTAX ) ) return (char *)( Onoff_Syntax ) ;
tomwalters@0 1033 if ( bitsset( type, EQ_SYNTAX ) ) return (char *)( Eq_Syntax ) ;
tomwalters@0 1034 if ( bitsset( type, ARG_SYNTAX ) ) return (char *)( Arg_Syntax ) ;
tomwalters@0 1035 if ( bitsset( type, FLAG_SYNTAX ) ) return (char *)( Flag_Syntax ) ;
tomwalters@0 1036 }
tomwalters@0 1037
tomwalters@0 1038