3
* $Id: makeshell.c,v 4.14 2006/10/06 05:29:00 bkorb Exp $
4
* Time-stamp: "2006-10-05 20:41:23 bkorb"
6
* This module will interpret the options set in the tOptions
7
* structure and create a Bourne shell script capable of parsing them.
11
* Automated Options copyright 1992-2006 Bruce Korb
13
* Automated Options is free software.
14
* You may redistribute it and/or modify it under the terms of the
15
* GNU General Public License, as published by the Free Software
16
* Foundation; either version 2, or (at your option) any later version.
18
* Automated Options is distributed in the hope that it will be useful,
19
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
* GNU General Public License for more details.
23
* You should have received a copy of the GNU General Public License
24
* along with Automated Options. See the file "COPYING". If not,
25
* write to: The Free Software Foundation, Inc.,
26
* 51 Franklin Street, Fifth Floor,
27
* Boston, MA 02110-1301, USA.
29
* As a special exception, Bruce Korb gives permission for additional
30
* uses of the text contained in his release of AutoOpts.
32
* The exception is that, if you link the AutoOpts library with other
33
* files to produce an executable, this does not by itself cause the
34
* resulting executable to be covered by the GNU General Public License.
35
* Your use of that executable is in no way restricted on account of
36
* linking the AutoOpts library code into it.
38
* This exception does not however invalidate any other reasons why
39
* the executable file might be covered by the GNU General Public License.
41
* This exception applies only to the code released by Bruce Korb under
42
* the name AutoOpts. If you copy code from other sources under the
43
* General Public License into a copy of AutoOpts, as the General Public
44
* License permits, the exception does not apply to the code that you add
45
* in this way. To avoid misleading anyone as to the status of such
46
* modified files, you must delete this exception notice from them.
48
* If you write modifications of your own for AutoOpts, it is your choice
49
* whether to permit this exception to apply to your modifications.
50
* If you do not wish that, delete this exception notice.
53
tOptions* pShellParseOptions = NULL;
55
/* * * * * * * * * * * * * * * * * * * * *
57
* Setup Format Strings
60
"# # # # # # # # # # -- do not modify this marker --\n#\n"
61
"# DO NOT EDIT THIS SECTION";
65
"# From here to the next `-- do not modify this marker --',\n"
66
"# the text has been generated %s\n";
69
"# From the %s option definitions\n#\n";
71
tSCC zMultiDef[] = "\n"
72
"if test -z \"${%1$s_%2$s}\"\n"
77
" %1$s_%2$s_1=\"${%1$s_%2$s}\"\n"
79
"export %1$s_%2$s_CT";
81
tSCC zSingleDef[] = "\n"
82
"%1$s_%2$s=\"${%1$s_%2$s-'%3$s'}\"\n"
83
"%1$s_%2$s_set=false\n"
86
tSCC zSingleNoDef[] = "\n"
87
"%1$s_%2$s=\"${%1$s_%2$s}\"\n"
88
"%1$s_%2$s_set=false\n"
91
/* * * * * * * * * * * * * * * * * * * * *
95
* The loop may run in either of two modes:
96
* all options are named options (loop only)
97
* regular, marked option processing.
99
tSCC zLoopCase[] = "\n"
102
"while ${OPT_PROCESS} && [ $# -gt 0 ]\ndo\n"
104
" OPT_ARG_VAL=''\n\n"
106
* 'OPT_ARG' may or may not match the current $1
108
" case \"${OPT_ARG}\" in\n"
110
" OPT_PROCESS=false\n"
114
tSCC zLoopOnly[] = "\n"
116
"while [ $# -gt 0 ]\ndo\n"
118
" OPT_ARG_VAL=''\n\n"
119
" OPT_ARG=\"${1}\"\n";
121
/* * * * * * * * * * * * * * * *
125
* If the loop runs as a regular option loop,
126
* then we must have selectors for each acceptable option
127
* type (long option, flag character and non-option)
129
tSCC zLongSelection[] =
132
tSCC zFlagSelection[] =
135
tSCC zEndSelection[] =
138
tSCC zNoSelection[] =
140
" OPT_PROCESS=false\n"
144
/* * * * * * * * * * * * * * * *
149
" if [ -n \"${OPT_ARG_VAL}\" ]\n"
151
" eval %1$s_${OPT_NAME}${OPT_ELEMENT}=\"'${OPT_ARG_VAL}'\"\n"
152
" export %1$s_${OPT_NAME}${OPT_ELEMENT}\n"
155
"unset OPT_PROCESS || :\n"
156
"unset OPT_ELEMENT || :\n"
157
"unset OPT_ARG || :\n"
158
"unset OPT_ARG_NEEDED || :\n"
159
"unset OPT_NAME || :\n"
160
"unset OPT_CODE || :\n"
161
"unset OPT_ARG_VAL || :\n%2$s";
163
tSCC zTrailerMarker[] = "\n"
164
"# # # # # # # # # #\n#\n"
165
"# END OF AUTOMATED OPTION PROCESSING\n"
166
"#\n# # # # # # # # # # -- do not modify this marker --\n";
168
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
173
" case \"${OPT_CODE}\" in\n";
175
tSCC zOptionPartName[] =
178
tSCC zOptionFullName[] =
184
tSCC zOptionEndSelect[] =
187
tSCC zOptionUnknown[] =
189
" echo Unknown %s: \"${OPT_CODE}\" >&2\n"
190
" echo \"$%s_USAGE_TEXT\"\n"
195
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
199
* Formats for emitting the text for handling particular options
202
" echo \"$%s_%s_TEXT\"\n"
205
tSCC zPagedUsageExit[] =
206
" echo \"$%s_LONGUSAGE_TEXT\" | ${PAGER-more}\n"
213
" if [ $%1$s_%2$s_CT -ge %3$d ] ; then\n"
214
" echo Error: more than %3$d %2$s options >&2\n"
215
" echo \"$%1$s_USAGE_TEXT\"\n"
219
" %1$s_%2$s_CT=`expr ${%1$s_%2$s_CT} + 1`\n"
220
" OPT_ELEMENT=\"_${%1$s_%2$s_CT}\"\n"
221
" OPT_NAME='%2$s'\n";
224
" if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n"
225
" echo Error: duplicate %2$s option >&2\n"
226
" echo \"$%1$s_USAGE_TEXT\"\n"
228
" %1$s_%2$s_set=true\n"
229
" OPT_NAME='%2$s'\n";
234
" %1$s_%2$s='%3$s'\n"
235
" export %1$s_%2$s\n"
236
" OPT_NAME='%2$s'\n";
238
tSCC zNoSingleArg[] =
239
" if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n"
240
" echo Error: duplicate %2$s option >&2\n"
241
" echo \"$%1$s_USAGE_TEXT\"\n"
243
" %1$s_%2$s_set=true\n"
244
" %1$s_%2$s='%3$s'\n"
245
" export %1$s_%2$s\n"
246
" OPT_NAME='%2$s'\n";
249
" eval %1$s_%2$s${OPT_ELEMENT}=true\n"
250
" export %1$s_%2$s${OPT_ELEMENT}\n"
251
" OPT_ARG_NEEDED=OK\n";
254
" OPT_ARG_NEEDED=YES\n";
257
" eval %1$s_%2$s${OPT_ELEMENT}=true\n"
258
" export %1$s_%2$s${OPT_ELEMENT}\n"
259
" OPT_ARG_NEEDED=NO\n";
261
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
263
* LONG OPTION PROCESSING
265
* Formats for emitting the text for handling long option types
267
tSCC zLongOptInit[] =
268
" OPT_CODE=`echo \"X${OPT_ARG}\"|sed 's/^X-*//'`\n"
270
" OPT_ARG=\"$1\"\n\n"
271
" case \"${OPT_CODE}\" in *=* )\n"
272
" OPT_ARG_VAL=`echo \"${OPT_CODE}\"|sed 's/^[^=]*=//'`\n"
273
" OPT_CODE=`echo \"${OPT_CODE}\"|sed 's/=.*$//'` ;; esac\n\n";
276
" case \"${OPT_ARG_NEEDED}\" in\n"
281
" if [ -z \"${OPT_ARG_VAL}\" ]\n"
285
" echo No argument provided for ${OPT_NAME} option >&2\n"
286
" echo \"$%s_USAGE_TEXT\"\n"
289
" OPT_ARG_VAL=\"${OPT_ARG}\"\n"
295
" if [ -z \"${OPT_ARG_VAL}\" ] && [ $# -gt 0 ]\n"
297
" case \"${OPT_ARG}\" in -* ) ;; * )\n"
298
" OPT_ARG_VAL=\"${OPT_ARG}\"\n"
300
" OPT_ARG=\"$1\" ;; esac\n"
305
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
307
* FLAG OPTION PROCESSING
309
* Formats for emitting the text for handling flag option types
311
tSCC zFlagOptInit[] =
312
" OPT_CODE=`echo \"X${OPT_ARG}\" | sed 's/X-\\(.\\).*/\\1/'`\n"
313
" OPT_ARG=` echo \"X${OPT_ARG}\" | sed 's/X-.//'`\n\n";
316
" case \"${OPT_ARG_NEEDED}\" in\n"
318
" if [ -n \"${OPT_ARG}\" ]\n"
320
" OPT_ARG=-\"${OPT_ARG}\"\n"
327
" if [ -n \"${OPT_ARG}\" ]\n"
329
" OPT_ARG_VAL=\"${OPT_ARG}\"\n\n"
333
" echo No argument provided for ${OPT_NAME} option >&2\n"
334
" echo \"$%s_USAGE_TEXT\"\n"
338
" OPT_ARG_VAL=\"$1\"\n"
344
" if [ -n \"${OPT_ARG}\" ]\n"
346
" OPT_ARG_VAL=\"${OPT_ARG}\"\n"
348
" OPT_ARG=\"$1\"\n\n"
353
" case \"$1\" in -* ) ;; * )\n"
354
" OPT_ARG_VAL=\"$1\"\n"
362
tSCC* pzShell = NULL;
363
static char* pzLeader = NULL;
364
static char* pzTrailer = NULL;
366
/* = = = START-STATIC-FORWARD = = = */
367
/* static forward declarations maintained by :mkfwd */
369
textToVariable( tOptions* pOpts, teTextTo whichVar, tOptDesc* pOD );
372
emitUsage( tOptions* pOpts );
375
emitSetup( tOptions* pOpts );
378
printOptionAction( tOptions* pOpts, tOptDesc* pOptDesc );
381
printOptionInaction( tOptions* pOpts, tOptDesc* pOptDesc );
384
emitFlag( tOptions* pOpts );
387
emitMatchExpr( tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts );
390
emitLong( tOptions* pOpts );
393
openOutput( char const* pzFile );
394
/* = = = END-STATIC-FORWARD = = = */
396
/*=export_func optionParseShell
399
* what: Decipher a boolean value
400
* arg: + tOptions* + pOpts + program options descriptor +
403
* Emit a shell script that will parse the command line options.
406
optionParseShell( tOptions* pOpts )
409
* Check for our SHELL option now.
410
* IF the output file contains the "#!" magic marker,
411
* it will override anything we do here.
413
if (HAVE_OPT( SHELL ))
414
pzShell = OPT_ARG( SHELL );
416
else if (! ENABLED_OPT( SHELL ))
419
else if ((pzShell = getenv( "SHELL" )),
425
* Check for a specified output file
427
if (HAVE_OPT( SCRIPT ))
428
openOutput( OPT_ARG( SCRIPT ));
434
* There are four modes of option processing.
436
switch (pOpts->fOptSet & (OPTPROC_LONGOPT|OPTPROC_SHORTOPT)) {
437
case OPTPROC_LONGOPT:
438
fputs( zLoopCase, stdout );
440
fputs( zLongSelection, stdout );
441
fputs( zLongOptInit, stdout );
443
printf( zLongOptArg, pOpts->pzPROGNAME );
444
fputs( zEndSelection, stdout );
446
fputs( zNoSelection, stdout );
450
fputs( zLoopOnly, stdout );
451
fputs( zLongOptInit, stdout );
453
printf( zLongOptArg, pOpts->pzPROGNAME );
456
case OPTPROC_SHORTOPT:
457
fputs( zLoopCase, stdout );
459
fputs( zFlagSelection, stdout );
460
fputs( zFlagOptInit, stdout );
462
printf( zFlagOptArg, pOpts->pzPROGNAME );
463
fputs( zEndSelection, stdout );
465
fputs( zNoSelection, stdout );
468
case OPTPROC_LONGOPT|OPTPROC_SHORTOPT:
469
fputs( zLoopCase, stdout );
471
fputs( zLongSelection, stdout );
472
fputs( zLongOptInit, stdout );
474
printf( zLongOptArg, pOpts->pzPROGNAME );
475
fputs( zEndSelection, stdout );
477
fputs( zFlagSelection, stdout );
478
fputs( zFlagOptInit, stdout );
480
printf( zFlagOptArg, pOpts->pzPROGNAME );
481
fputs( zEndSelection, stdout );
483
fputs( zNoSelection, stdout );
487
printf( zLoopEnd, pOpts->pzPROGNAME, zTrailerMarker );
488
if ((pzTrailer != NULL) && (*pzTrailer != '\0'))
489
fputs( pzTrailer, stdout );
490
else if (ENABLED_OPT( SHELL ))
491
printf( "\nenv | egrep %s_\n", pOpts->pzPROGNAME );
494
fchmod( STDOUT_FILENO, 0755 );
500
textToVariable( tOptions* pOpts, teTextTo whichVar, tOptDesc* pOD )
502
# define _TT_(n) tSCC z ## n [] = #n;
505
# define _TT_(n) z ## n ,
506
static char const* apzTTNames[] = { TEXTTO_TABLE };
509
#if defined(__windows__) && !defined(__CYGWIN__)
510
printf( "%1$s_%2$s_TEXT='no %2$s text'\n",
511
pOpts->pzPROGNAME, apzTTNames[ whichVar ]);
517
printf( "%s_%s_TEXT='", pOpts->pzPROGNAME, apzTTNames[ whichVar ]);
520
if (pipe( pipeFd ) != 0) {
521
fprintf( stderr, zBadPipe, errno, strerror( errno ));
522
exit( EXIT_FAILURE );
527
fprintf( stderr, zForkFail, errno, strerror(errno), pOpts->pzProgName);
528
exit( EXIT_FAILURE );
532
dup2( pipeFd[1], STDERR_FILENO );
533
dup2( pipeFd[1], STDOUT_FILENO );
538
(*(pOpts->pUsageProc))( pOpts, EXIT_SUCCESS );
540
exit( EXIT_FAILURE );
543
(*(pOpts->pUsageProc))( pOpts, EXIT_FAILURE );
545
exit( EXIT_FAILURE );
548
pOD->optArg.argString = "c";
549
optionPrintVersion( pOpts, pOD );
553
exit( EXIT_FAILURE );
558
fp = fdopen( pipeFd[0], "r" FOPEN_BINARY_FLAG );
562
int ch = fgetc( fp );
570
while (nlHoldCt > 0) {
571
fputc( '\n', stdout );
574
fputs( "'\\''", stdout );
581
while (nlHoldCt > 0) {
582
fputc( '\n', stdout );
590
fputs( "'\n\n", stdout );
597
emitUsage( tOptions* pOpts )
599
char zTimeBuf[ AO_NAME_SIZE ];
602
* First, switch stdout to the output file name.
603
* Then, change the program name to the one defined
604
* by the definitions (rather than the current
605
* executable name). Down case the upper cased name.
607
if (pzLeader != NULL)
608
fputs( pzLeader, stdout );
611
tSCC zStdout[] = "stdout";
615
time_t curTime = time( NULL );
616
struct tm* pTime = localtime( &curTime );
617
strftime( zTimeBuf, AO_NAME_SIZE, "%A %B %e, %Y at %r %Z", pTime );
620
if (HAVE_OPT( SCRIPT ))
621
pzOutName = OPT_ARG( SCRIPT );
622
else pzOutName = zStdout;
624
if ((pzLeader == NULL) && (pzShell != NULL))
625
printf( "#! %s\n", pzShell );
627
printf( zPreamble, zStartMarker, pzOutName, zTimeBuf );
631
* Get a copy of the original program name in lower case
634
char* pzPN = zTimeBuf;
635
tCC* pz = pOpts->pzPROGNAME;
637
if ((*pzPN++ = tolower( *pz++ )) == '\0')
642
printf( zEndPreamble, pOpts->pzPROGNAME );
644
pOpts->pzProgPath = pOpts->pzProgName = zTimeBuf;
645
textToVariable( pOpts, TT_LONGUSAGE, NULL );
646
textToVariable( pOpts, TT_USAGE, NULL );
649
tOptDesc* pOptDesc = pOpts->pOptDesc;
650
int optionCt = pOpts->optCt;
653
if (pOptDesc->pOptProc == optionPrintVersion) {
654
textToVariable( pOpts, TT_VERSION, pOptDesc );
667
emitSetup( tOptions* pOpts )
669
tOptDesc* pOptDesc = pOpts->pOptDesc;
670
int optionCt = pOpts->presetOptCt;
672
char const* pzDefault;
674
for (;optionCt > 0; pOptDesc++, --optionCt) {
678
* Options that are either usage documentation or are compiled out
679
* are not to be processed.
681
if (SKIP_OPT(pOptDesc) || (pOptDesc->pz_NAME == NULL))
684
if (pOptDesc->optMaxCt > 1)
686
else pzFmt = zSingleDef;
689
* IF this is an enumeration/bitmask option, then convert the value
690
* to a string before printing the default value.
692
switch (OPTST_GET_ARGTYPE(pOptDesc->fOptState)) {
693
case OPARG_TYPE_ENUMERATION:
694
(*(pOptDesc->pOptProc))( (tOptions*)2UL, pOptDesc );
695
pzDefault = pOptDesc->optArg.argString;
699
* Numeric and membership bit options are just printed as a number.
701
case OPARG_TYPE_NUMERIC:
702
snprintf( zVal, sizeof( zVal ), "%d",
703
(int)pOptDesc->optArg.argInt );
707
case OPARG_TYPE_MEMBERSHIP:
708
snprintf( zVal, sizeof( zVal ), "%lu",
709
(unsigned long)pOptDesc->optArg.argIntptr );
713
case OPARG_TYPE_BOOLEAN:
714
pzDefault = (pOptDesc->optArg.argBool) ? "true" : "false";
718
if (pOptDesc->optArg.argString == NULL) {
719
if (pzFmt == zSingleDef)
720
pzFmt = zSingleNoDef;
724
pzDefault = pOptDesc->optArg.argString;
727
printf( pzFmt, pOpts->pzPROGNAME, pOptDesc->pz_NAME, pzDefault );
733
printOptionAction( tOptions* pOpts, tOptDesc* pOptDesc )
735
if (pOptDesc->pOptProc == optionPrintVersion)
736
printf( zTextExit, pOpts->pzPROGNAME, "VERSION" );
738
else if (pOptDesc->pOptProc == optionPagedUsage)
739
printf( zPagedUsageExit, pOpts->pzPROGNAME );
741
else if (pOptDesc->pOptProc == optionLoadOpt) {
742
printf( zCmdFmt, "echo 'Warning: Cannot load options files' >&2" );
743
printf( zCmdFmt, "OPT_ARG_NEEDED=YES" );
745
} else if (pOptDesc->pz_NAME == NULL) {
747
if (pOptDesc->pOptProc == NULL) {
748
printf( zCmdFmt, "echo 'Warning: Cannot save options files' "
750
printf( zCmdFmt, "OPT_ARG_NEEDED=OK" );
752
printf( zTextExit, pOpts->pzPROGNAME, "LONGUSAGE" );
755
if (pOptDesc->optMaxCt == 1)
756
printf( zSingleArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME );
758
if ((unsigned)pOptDesc->optMaxCt < NOLIMIT)
759
printf( zCountTest, pOpts->pzPROGNAME,
760
pOptDesc->pz_NAME, pOptDesc->optMaxCt );
762
printf( zMultiArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME );
768
if (OPTST_GET_ARGTYPE(pOptDesc->fOptState) == OPARG_TYPE_NONE) {
769
printf( zCantArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME );
771
} else if (pOptDesc->fOptState & OPTST_ARG_OPTIONAL) {
772
printf( zMayArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME );
775
fputs( zMustArg, stdout );
778
fputs( zOptionEndSelect, stdout );
783
printOptionInaction( tOptions* pOpts, tOptDesc* pOptDesc )
785
if (pOptDesc->pOptProc == optionLoadOpt) {
786
printf( zCmdFmt, "echo 'Warning: Cannot suppress the loading of "
787
"options files' >&2" );
789
} else if (pOptDesc->optMaxCt == 1)
790
printf( zNoSingleArg, pOpts->pzPROGNAME,
791
pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx );
793
printf( zNoMultiArg, pOpts->pzPROGNAME,
794
pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx );
796
printf( zCmdFmt, "OPT_ARG_NEEDED=NO" );
797
fputs( zOptionEndSelect, stdout );
802
emitFlag( tOptions* pOpts )
804
tOptDesc* pOptDesc = pOpts->pOptDesc;
805
int optionCt = pOpts->optCt;
807
fputs( zOptionCase, stdout );
809
for (;optionCt > 0; pOptDesc++, --optionCt) {
811
if (SKIP_OPT(pOptDesc))
814
if (isprint( pOptDesc->optValue )) {
815
printf( zOptionFlag, pOptDesc->optValue );
816
printOptionAction( pOpts, pOptDesc );
819
printf( zOptionUnknown, "flag", pOpts->pzPROGNAME );
824
* Emit the match text for a long option
827
emitMatchExpr( tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts )
829
tOptDesc* pOD = pOpts->pOptDesc;
830
int oCt = pOpts->optCt;
839
* Omit the current option, Documentation opts and compiled out opts.
841
if ((pOD == pCurOpt) || SKIP_OPT(pOD)){
849
* Check each character of the name case insensitively.
850
* They must not be the same. They cannot be, because it would
851
* not compile correctly if they were.
853
while ( toupper( pOD->pz_Name[matchCt] )
854
== toupper( pzMatchName[matchCt] ))
861
* Check the disablement name, too.
863
if (pOD->pz_DisableName != NULL) {
865
while ( toupper( pOD->pz_DisableName[matchCt] )
866
== toupper( pzMatchName[matchCt] ))
877
* IF the 'min' is all or one short of the name length,
878
* THEN the entire string must be matched.
880
if ( (pzMatchName[min ] == NUL)
881
|| (pzMatchName[min+1] == NUL) )
882
printf( zOptionFullName, pzMatchName );
886
for (; matchCt <= min; matchCt++)
887
*pz++ = pzMatchName[matchCt];
891
printf( zOptionPartName, zName );
892
*pz++ = pzMatchName[matchCt++];
893
if (pzMatchName[matchCt] == NUL) {
895
printf( zOptionFullName, zName );
904
* Emit GNU-standard long option handling code
907
emitLong( tOptions* pOpts )
909
tOptDesc* pOD = pOpts->pOptDesc;
910
int ct = pOpts->optCt;
912
fputs( zOptionCase, stdout );
915
* do each option, ...
919
* Documentation & compiled-out options
924
emitMatchExpr( pOD->pz_Name, pOD, pOpts );
925
printOptionAction( pOpts, pOD );
928
* Now, do the same thing for the disablement version of the option.
930
if (pOD->pz_DisableName != NULL) {
931
emitMatchExpr( pOD->pz_DisableName, pOD, pOpts );
932
printOptionInaction( pOpts, pOD );
934
} while (pOD++, --ct > 0);
936
printf( zOptionUnknown, "option", pOpts->pzPROGNAME );
941
openOutput( char const* pzFile )
952
* IF we cannot stat the file,
953
* THEN assume we are creating a new file.
954
* Skip the loading of the old data.
956
if (stat( pzFile, &stbf ) != 0)
960
* The file must be a regular file
962
if (! S_ISREG( stbf.st_mode )) {
963
fprintf( stderr, zNotFile, pzFile );
964
exit( EXIT_FAILURE );
967
pzData = (char*)malloc( (unsigned)(stbf.st_size + 1) );
968
fp = fopen( pzFile, "r" FOPEN_BINARY_FLAG );
970
sizeLeft = (unsigned)stbf.st_size;
974
* Read in all the data as fast as our OS will let us.
977
int inct = fread( (void*)pzScan, 1, sizeLeft, fp );
989
* NUL-terminate the leader and look for the trailer
993
pzScan = strstr( pzData, zStartMarker );
994
if (pzScan == NULL) {
1000
pzScan = strstr( pzScan, zTrailerMarker );
1001
if (pzScan == NULL) {
1007
* Check to see if the data contains
1008
* our marker. If it does, then we will skip over it
1010
pzTrailer = pzScan + sizeof( zTrailerMarker ) - 1;
1014
freopen( pzFile, "w" FOPEN_BINARY_FLAG, stdout );
1018
/*=export_func genshelloptUsage
1020
* what: The usage function for the genshellopt generated program
1022
* arg: + tOptions* + pOpts + program options descriptor +
1023
* arg: + int + exitCode + usage text type to produce +
1026
* This function is used to create the usage strings for the option
1027
* processing shell script code. Two child processes are spawned
1028
* each emitting the usage text in either the short (error exit)
1029
* style or the long style. The generated program will capture this
1030
* and create shell script variables containing the two types of text.
1033
genshelloptUsage( tOptions* pOpts, int exitCode )
1035
#if defined(__windows__) && !defined(__CYGWIN__)
1036
optionUsage( pOpts, exitCode );
1039
* IF not EXIT_SUCCESS,
1040
* THEN emit the short form of usage.
1042
if (exitCode != EXIT_SUCCESS)
1043
optionUsage( pOpts, exitCode );
1047
option_usage_fp = stdout;
1050
* First, print our usage
1054
optionUsage( pOpts, EXIT_FAILURE );
1056
_exit( EXIT_FAILURE );
1059
pagerState = PAGER_STATE_CHILD;
1060
optionUsage( pOpts, EXIT_SUCCESS );
1062
_exit( EXIT_FAILURE );
1072
* Generate the pzProgName, since optionProcess() normally
1073
* gets it from the command line
1077
AGDUPSTR( pz, pShellParseOptions->pzPROGNAME, "program name" );
1078
pShellParseOptions->pzProgName = pz;
1079
while (*pz != NUL) {
1080
*pz = tolower( *pz );
1086
* Separate the makeshell usage from the client usage
1088
fprintf( option_usage_fp, zGenshell, pShellParseOptions->pzProgName );
1089
fflush( option_usage_fp );
1092
* Now, print the client usage.
1096
pagerState = PAGER_STATE_CHILD;
1099
optionUsage( pShellParseOptions, EXIT_FAILURE );
1108
exit( EXIT_SUCCESS );
1115
* c-file-style: "stroustrup"
1116
* indent-tabs-mode: nil
1118
* end of autoopts/makeshell.c */