1181834Sroberto
2290001Sglebius/**
3290001Sglebius * \file putshell.c
4181834Sroberto *
5181834Sroberto *  This module will interpret the options set in the tOptions
6181834Sroberto *  structure and print them to standard out in a fashion that
7181834Sroberto *  will allow them to be interpreted by the Bourne or Korn shells.
8290001Sglebius *
9290001Sglebius * @addtogroup autoopts
10290001Sglebius * @{
11181834Sroberto */
12181834Sroberto/*
13290001Sglebius *  This file is part of AutoOpts, a companion to AutoGen.
14290001Sglebius *  AutoOpts is free software.
15290001Sglebius *  AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
16181834Sroberto *
17290001Sglebius *  AutoOpts is available under any one of two licenses.  The license
18290001Sglebius *  in use must be one of these two and the choice is under the control
19290001Sglebius *  of the user of the license.
20181834Sroberto *
21290001Sglebius *   The GNU Lesser General Public License, version 3 or later
22290001Sglebius *      See the files "COPYING.lgplv3" and "COPYING.gplv3"
23181834Sroberto *
24290001Sglebius *   The Modified Berkeley Software Distribution License
25290001Sglebius *      See the file "COPYING.mbsd"
26181834Sroberto *
27290001Sglebius *  These files have the following sha256 sums:
28181834Sroberto *
29290001Sglebius *  8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95  COPYING.gplv3
30290001Sglebius *  4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b  COPYING.lgplv3
31290001Sglebius *  13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239  COPYING.mbsd
32181834Sroberto */
33181834Sroberto
34181834Sroberto/* = = = START-STATIC-FORWARD = = = */
35290001Sglebiusstatic size_t
36290001Sglebiusstring_size(char const * scan, size_t nl_len);
37290001Sglebius
38290001Sglebiusstatic char const *
39290001Sglebiusprint_quoted_apostrophes(char const * str);
40290001Sglebius
41181834Srobertostatic void
42290001Sglebiusprint_quot_str(char const * str);
43290001Sglebius
44290001Sglebiusstatic void
45290001Sglebiusprint_enumeration(tOptions * pOpts, tOptDesc * pOD);
46290001Sglebius
47290001Sglebiusstatic void
48290001Sglebiusprint_membership(tOptions * pOpts, tOptDesc * pOD);
49290001Sglebius
50290001Sglebiusstatic void
51290001Sglebiusprint_stacked_arg(tOptions * pOpts, tOptDesc * pOD);
52290001Sglebius
53290001Sglebiusstatic void
54290001Sglebiusprint_reordering(tOptions * opts);
55181834Sroberto/* = = = END-STATIC-FORWARD = = = */
56181834Sroberto
57290001Sglebius/**
58290001Sglebius * Count the number of bytes required to represent a string as a
59290001Sglebius * compilable string.
60290001Sglebius *
61290001Sglebius * @param[in] scan    the text to be rewritten as a C program text string.
62290001Sglebius * @param[in] nl_len  the number of bytes used for each embedded newline.
63290001Sglebius *
64290001Sglebius * @returns the count, including the terminating NUL byte.
65181834Sroberto */
66290001Sglebiusstatic size_t
67290001Sglebiusstring_size(char const * scan, size_t nl_len)
68290001Sglebius{
69290001Sglebius    /*
70290001Sglebius     *  Start by counting the start and end quotes, plus the NUL.
71290001Sglebius     */
72290001Sglebius    size_t res_ln = 3;
73290001Sglebius
74290001Sglebius    for (;;) {
75290001Sglebius        char ch = *(scan++);
76290001Sglebius        if ((ch >= ' ') && (ch <= '~')) {
77290001Sglebius
78290001Sglebius            /*
79290001Sglebius             * a backslash allowance for double quotes and baskslashes
80290001Sglebius             */
81290001Sglebius            res_ln += ((ch == '"') || (ch == '\\')) ? 2 : 1;
82290001Sglebius        }
83290001Sglebius
84290001Sglebius        /*
85290001Sglebius         *  When not a normal character, then count the characters
86290001Sglebius         *  required to represent whatever it is.
87290001Sglebius         */
88290001Sglebius        else switch (ch) {
89290001Sglebius        case NUL:
90290001Sglebius            return res_ln;
91290001Sglebius
92290001Sglebius        case NL:
93290001Sglebius            res_ln += nl_len;
94290001Sglebius            break;
95290001Sglebius
96290001Sglebius        case HT:
97290001Sglebius        case BEL:
98290001Sglebius        case BS:
99290001Sglebius        case FF:
100290001Sglebius        case CR:
101290001Sglebius        case VT:
102290001Sglebius            res_ln += 2;
103290001Sglebius            break;
104290001Sglebius
105290001Sglebius        default:
106290001Sglebius            res_ln += 4; /* text len for \xNN */
107290001Sglebius        }
108290001Sglebius    }
109290001Sglebius}
110290001Sglebius
111290001Sglebius/*=export_func  optionQuoteString
112290001Sglebius * private:
113290001Sglebius *
114290001Sglebius * what:  Print a string as quoted text suitable for a C compiler.
115290001Sglebius * arg:   + char const * + text  + a block of text to quote +
116290001Sglebius * arg:   + char const * + nl    + line splice text         +
117290001Sglebius *
118290001Sglebius * ret_type:  char const *
119290001Sglebius * ret_desc:  the allocated input string as a quoted string
120290001Sglebius *
121290001Sglebius * doc:
122290001Sglebius *  This is for internal use by autogen and autoopts.
123290001Sglebius *  It takes an input string and produces text the C compiler can process
124290001Sglebius *  to produce an exact copy of the original string.
125290001Sglebius *  The caller must deallocate the result.  Standard C strings and
126290001Sglebius *  K&R strings are distinguished by the "nl" string.
127290001Sglebius=*/
128290001Sglebiuschar const *
129290001SglebiusoptionQuoteString(char const * text, char const * nl)
130290001Sglebius{
131290001Sglebius    size_t   nl_len = strlen(nl);
132290001Sglebius    char *   out;
133290001Sglebius    char *   res = out = AGALOC(string_size(text, nl_len), "quot str");
134290001Sglebius    *(out++) = '"';
135290001Sglebius
136290001Sglebius    for (;;) {
137290001Sglebius        unsigned char ch = (unsigned char)*text;
138290001Sglebius        if ((ch >= ' ') && (ch <= '~')) {
139290001Sglebius            if ((ch == '"') || (ch == '\\'))
140290001Sglebius                /*
141290001Sglebius                 *  We must escape these characters in the output string
142290001Sglebius                 */
143290001Sglebius                *(out++) = '\\';
144290001Sglebius            *(out++) = (char)ch;
145290001Sglebius
146290001Sglebius        } else switch (ch) {
147290001Sglebius#       define   add_esc_ch(_ch)  { *(out++) = '\\'; *(out++) = (_ch); }
148290001Sglebius        case BEL: add_esc_ch('a'); break;
149290001Sglebius        case BS:  add_esc_ch('b'); break;
150290001Sglebius        case HT:  add_esc_ch('t'); break;
151290001Sglebius        case VT:  add_esc_ch('v'); break;
152290001Sglebius        case FF:  add_esc_ch('f'); break;
153290001Sglebius        case CR:  add_esc_ch('r'); break;
154290001Sglebius
155290001Sglebius        case LF:
156290001Sglebius            /*
157290001Sglebius             *  Place contiguous new-lines on a single line.
158290001Sglebius             *  The current character is a NL, check the next one.
159290001Sglebius             */
160290001Sglebius            while (*++text == NL)
161290001Sglebius                add_esc_ch('n');
162290001Sglebius
163290001Sglebius            /*
164290001Sglebius             *  Insert a splice before starting next line
165290001Sglebius             */
166290001Sglebius            if (*text != NUL) {
167290001Sglebius                memcpy(out, nl, nl_len);
168290001Sglebius                out += nl_len;
169290001Sglebius
170290001Sglebius                continue; /* text is already at the next character */
171290001Sglebius            }
172290001Sglebius
173290001Sglebius            add_esc_ch('n');
174290001Sglebius            /* FALLTHROUGH */
175290001Sglebius
176290001Sglebius        case NUL:
177290001Sglebius            /*
178290001Sglebius             *  End of string.  Terminate the quoted output.  If necessary,
179290001Sglebius             *  deallocate the text string.  Return the scan resumption point.
180290001Sglebius             */
181290001Sglebius            *(out++) = '"';
182290001Sglebius            *out = NUL;
183290001Sglebius            return res;
184290001Sglebius
185290001Sglebius        default:
186290001Sglebius            /*
187290001Sglebius             *  sprintf is safe here, because we already computed
188290001Sglebius             *  the amount of space we will be using.
189290001Sglebius             */
190290001Sglebius            sprintf(out, MK_STR_OCT_FMT, ch);
191290001Sglebius            out += 4;
192290001Sglebius        }
193290001Sglebius
194290001Sglebius        text++;
195290001Sglebius#       undef add_esc_ch
196290001Sglebius    }
197290001Sglebius}
198290001Sglebius
199290001Sglebius/**
200290001Sglebius *  Print out escaped apostorophes.
201290001Sglebius *
202290001Sglebius *  @param[in] str  the apostrophies to print
203290001Sglebius */
204290001Sglebiusstatic char const *
205290001Sglebiusprint_quoted_apostrophes(char const * str)
206290001Sglebius{
207290001Sglebius    while (*str == APOSTROPHE) {
208290001Sglebius        fputs(QUOT_APOS, stdout);
209290001Sglebius        str++;
210290001Sglebius    }
211290001Sglebius    return str;
212290001Sglebius}
213290001Sglebius
214290001Sglebius/**
215290001Sglebius *  Print a single quote (apostrophe quoted) string.
216290001Sglebius *  Other than somersaults for apostrophes, nothing else needs quoting.
217290001Sglebius *
218290001Sglebius *  @param[in] str  the string to print
219290001Sglebius */
220181834Srobertostatic void
221290001Sglebiusprint_quot_str(char const * str)
222181834Sroberto{
223181834Sroberto    /*
224181834Sroberto     *  Handle empty strings to make the rest of the logic simpler.
225181834Sroberto     */
226290001Sglebius    if ((str == NULL) || (*str == NUL)) {
227290001Sglebius        fputs(EMPTY_ARG, stdout);
228181834Sroberto        return;
229181834Sroberto    }
230181834Sroberto
231181834Sroberto    /*
232181834Sroberto     *  Emit any single quotes/apostrophes at the start of the string and
233181834Sroberto     *  bail if that is all we need to do.
234181834Sroberto     */
235290001Sglebius    str = print_quoted_apostrophes(str);
236290001Sglebius    if (*str == NUL)
237181834Sroberto        return;
238181834Sroberto
239181834Sroberto    /*
240181834Sroberto     *  Start the single quote string
241181834Sroberto     */
242290001Sglebius    fputc(APOSTROPHE, stdout);
243181834Sroberto    for (;;) {
244290001Sglebius        char const * pz = strchr(str, APOSTROPHE);
245181834Sroberto        if (pz == NULL)
246181834Sroberto            break;
247181834Sroberto
248181834Sroberto        /*
249181834Sroberto         *  Emit the string up to the single quote (apostrophe) we just found.
250181834Sroberto         */
251290001Sglebius        (void)fwrite(str, (size_t)(pz - str), (size_t)1, stdout);
252181834Sroberto
253181834Sroberto        /*
254290001Sglebius         * Close the current string, emit the apostrophes and re-open the
255290001Sglebius         * string (IFF there is more text to print).
256181834Sroberto         */
257290001Sglebius        fputc(APOSTROPHE, stdout);
258290001Sglebius        str = print_quoted_apostrophes(pz);
259290001Sglebius        if (*str == NUL)
260181834Sroberto            return;
261181834Sroberto
262290001Sglebius        fputc(APOSTROPHE, stdout);
263181834Sroberto    }
264181834Sroberto
265181834Sroberto    /*
266181834Sroberto     *  If we broke out of the loop, we must still emit the remaining text
267181834Sroberto     *  and then close the single quote string.
268181834Sroberto     */
269290001Sglebius    fputs(str, stdout);
270290001Sglebius    fputc(APOSTROPHE, stdout);
271181834Sroberto}
272181834Sroberto
273290001Sglebiusstatic void
274290001Sglebiusprint_enumeration(tOptions * pOpts, tOptDesc * pOD)
275290001Sglebius{
276290001Sglebius    uintptr_t e_val = pOD->optArg.argEnum;
277290001Sglebius    printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
278181834Sroberto
279290001Sglebius    /*
280290001Sglebius     *  Convert value to string, print that and restore numeric value.
281290001Sglebius     */
282290001Sglebius    (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
283290001Sglebius    printf(QUOT_ARG_FMT, pOD->optArg.argString);
284290001Sglebius    if (pOD->fOptState & OPTST_ALLOC_ARG)
285290001Sglebius        AGFREE(pOD->optArg.argString);
286290001Sglebius    pOD->optArg.argEnum = e_val;
287290001Sglebius
288290001Sglebius    printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
289290001Sglebius}
290290001Sglebius
291290001Sglebiusstatic void
292290001Sglebiusprint_membership(tOptions * pOpts, tOptDesc * pOD)
293290001Sglebius{
294290001Sglebius    char const * svstr = pOD->optArg.argString;
295290001Sglebius    char const * pz;
296290001Sglebius    uintptr_t val = 1;
297290001Sglebius    printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
298290001Sglebius           (int)(uintptr_t)(pOD->optCookie));
299290001Sglebius    pOD->optCookie = VOIDP(~0UL);
300290001Sglebius    (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
301290001Sglebius
302290001Sglebius    pz = pOD->optArg.argString;
303290001Sglebius    while (*pz != NUL) {
304290001Sglebius        printf("readonly %s_", pOD->pz_NAME);
305290001Sglebius        pz = SPN_PLUS_N_SPACE_CHARS(pz);
306290001Sglebius
307290001Sglebius        for (;;) {
308290001Sglebius            int ch = *(pz++);
309290001Sglebius            if (IS_LOWER_CASE_CHAR(ch))   fputc(toupper(ch), stdout);
310290001Sglebius            else if (IS_UPPER_CASE_CHAR(ch))   fputc(ch, stdout);
311290001Sglebius            else if (IS_PLUS_N_SPACE_CHAR(ch)) goto name_done;
312290001Sglebius            else if (ch == NUL)        { pz--; goto name_done; }
313290001Sglebius            else fputc('_', stdout);
314290001Sglebius        } name_done:;
315290001Sglebius        printf(SHOW_VAL_FMT, (unsigned long)val);
316290001Sglebius        val <<= 1;
317290001Sglebius    }
318290001Sglebius
319290001Sglebius    AGFREE(pOD->optArg.argString);
320290001Sglebius    pOD->optArg.argString = svstr;
321290001Sglebius}
322290001Sglebius
323290001Sglebiusstatic void
324290001Sglebiusprint_stacked_arg(tOptions * pOpts, tOptDesc * pOD)
325290001Sglebius{
326290001Sglebius    tArgList *      pAL = (tArgList *)pOD->optCookie;
327290001Sglebius    char const **   ppz = pAL->apzArgs;
328290001Sglebius    int             ct  = pAL->useCt;
329290001Sglebius
330290001Sglebius    printf(zOptCookieCt, pOpts->pzPROGNAME, pOD->pz_NAME, ct);
331290001Sglebius
332290001Sglebius    while (--ct >= 0) {
333290001Sglebius        printf(ARG_BY_NUM_FMT, pOpts->pzPROGNAME, pOD->pz_NAME,
334290001Sglebius               pAL->useCt - ct);
335290001Sglebius        print_quot_str(*(ppz++));
336290001Sglebius        printf(EXPORT_ARG_FMT, pOpts->pzPROGNAME, pOD->pz_NAME,
337290001Sglebius               pAL->useCt - ct);
338290001Sglebius    }
339290001Sglebius}
340290001Sglebius
341290001Sglebius/**
342290001Sglebius * emit the arguments as readily parsed text.
343290001Sglebius * The program options are set by emitting the shell "set" command.
344290001Sglebius *
345290001Sglebius * @param[in] opts  the program options structure
346290001Sglebius */
347290001Sglebiusstatic void
348290001Sglebiusprint_reordering(tOptions * opts)
349290001Sglebius{
350290001Sglebius    unsigned int ix;
351290001Sglebius
352290001Sglebius    fputs(set_dash, stdout);
353290001Sglebius
354290001Sglebius    for (ix = opts->curOptIdx;
355290001Sglebius         ix < opts->origArgCt;
356290001Sglebius         ix++) {
357290001Sglebius        fputc(' ', stdout);
358290001Sglebius        print_quot_str(opts->origArgVect[ ix ]);
359290001Sglebius    }
360290001Sglebius    fputs(init_optct, stdout);
361290001Sglebius}
362290001Sglebius
363181834Sroberto/*=export_func  optionPutShell
364181834Sroberto * what:  write a portable shell script to parse options
365181834Sroberto * private:
366290001Sglebius * arg:   tOptions *, pOpts, the program options descriptor
367181834Sroberto * doc:   This routine will emit portable shell script text for parsing
368181834Sroberto *        the options described in the option definitions.
369181834Sroberto=*/
370181834Srobertovoid
371290001SglebiusoptionPutShell(tOptions * pOpts)
372181834Sroberto{
373181834Sroberto    int  optIx = 0;
374181834Sroberto
375290001Sglebius    printf(zOptCtFmt, pOpts->curOptIdx-1);
376181834Sroberto
377181834Sroberto    do  {
378290001Sglebius        tOptDesc * pOD = pOpts->pOptDesc + optIx;
379181834Sroberto
380290001Sglebius        if ((pOD->fOptState & OPTST_NO_OUTPUT_MASK) != 0)
381181834Sroberto            continue;
382181834Sroberto
383181834Sroberto        /*
384181834Sroberto         *  Equivalence classes are hard to deal with.  Where the
385181834Sroberto         *  option data wind up kind of squishes around.  For the purposes
386181834Sroberto         *  of emitting shell state, they are not recommended, but we'll
387181834Sroberto         *  do something.  I guess we'll emit the equivalenced-to option
388181834Sroberto         *  at the point in time when the base option is found.
389181834Sroberto         */
390181834Sroberto        if (pOD->optEquivIndex != NO_EQUIVALENT)
391181834Sroberto            continue; /* equivalence to a different option */
392181834Sroberto
393181834Sroberto        /*
394181834Sroberto         *  Equivalenced to a different option.  Process the current option
395181834Sroberto         *  as the equivalenced-to option.  Keep the persistent state bits,
396181834Sroberto         *  but copy over the set-state bits.
397181834Sroberto         */
398181834Sroberto        if (pOD->optActualIndex != optIx) {
399290001Sglebius            tOptDesc * p  = pOpts->pOptDesc + pOD->optActualIndex;
400181834Sroberto            p->optArg     = pOD->optArg;
401181834Sroberto            p->fOptState &= OPTST_PERSISTENT_MASK;
402181834Sroberto            p->fOptState |= pOD->fOptState & ~OPTST_PERSISTENT_MASK;
403290001Sglebius            printf(zEquivMode, pOpts->pzPROGNAME, pOD->pz_NAME, p->pz_NAME);
404181834Sroberto            pOD = p;
405181834Sroberto        }
406181834Sroberto
407181834Sroberto        /*
408181834Sroberto         *  If the argument type is a set membership bitmask, then we always
409181834Sroberto         *  emit the thing.  We do this because it will always have some sort
410181834Sroberto         *  of bitmask value and we need to emit the bit values.
411181834Sroberto         */
412181834Sroberto        if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) {
413290001Sglebius            print_membership(pOpts, pOD);
414181834Sroberto            continue;
415181834Sroberto        }
416181834Sroberto
417181834Sroberto        /*
418181834Sroberto         *  IF the option was either specified or it wakes up enabled,
419181834Sroberto         *  then we will emit information.  Otherwise, skip it.
420181834Sroberto         *  The idea is that if someone defines an option to initialize
421181834Sroberto         *  enabled, we should tell our shell script that it is enabled.
422181834Sroberto         */
423290001Sglebius        if (UNUSED_OPT(pOD) && DISABLED_OPT(pOD))
424181834Sroberto            continue;
425181834Sroberto
426181834Sroberto        /*
427181834Sroberto         *  Handle stacked arguments
428181834Sroberto         */
429181834Sroberto        if (  (pOD->fOptState & OPTST_STACKED)
430181834Sroberto           && (pOD->optCookie != NULL) )  {
431290001Sglebius            print_stacked_arg(pOpts, pOD);
432290001Sglebius            continue;
433181834Sroberto        }
434181834Sroberto
435181834Sroberto        /*
436181834Sroberto         *  If the argument has been disabled,
437181834Sroberto         *  Then set its value to the disablement string
438181834Sroberto         */
439290001Sglebius        if ((pOD->fOptState & OPTST_DISABLED) != 0) {
440290001Sglebius            printf(zOptDisabl, pOpts->pzPROGNAME, pOD->pz_NAME,
441290001Sglebius                   (pOD->pz_DisablePfx != NULL)
442290001Sglebius                   ? pOD->pz_DisablePfx : "false");
443290001Sglebius            continue;
444290001Sglebius        }
445181834Sroberto
446181834Sroberto        /*
447181834Sroberto         *  If the argument type is numeric, the last arg pointer
448181834Sroberto         *  is really the VALUE of the string that was pointed to.
449181834Sroberto         */
450290001Sglebius        if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC) {
451290001Sglebius            printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
452290001Sglebius                   (int)pOD->optArg.argInt);
453290001Sglebius            continue;
454290001Sglebius        }
455181834Sroberto
456181834Sroberto        /*
457181834Sroberto         *  If the argument type is an enumeration, then it is much
458181834Sroberto         *  like a text value, except we call the callback function
459181834Sroberto         *  to emit the value corresponding to the "optArg" number.
460181834Sroberto         */
461290001Sglebius        if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_ENUMERATION) {
462290001Sglebius            print_enumeration(pOpts, pOD);
463290001Sglebius            continue;
464181834Sroberto        }
465181834Sroberto
466181834Sroberto        /*
467181834Sroberto         *  If the argument type is numeric, the last arg pointer
468181834Sroberto         *  is really the VALUE of the string that was pointed to.
469181834Sroberto         */
470290001Sglebius        if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_BOOLEAN) {
471290001Sglebius            printf(zFullOptFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
472290001Sglebius                   (pOD->optArg.argBool == 0) ? "false" : "true");
473290001Sglebius            continue;
474290001Sglebius        }
475181834Sroberto
476181834Sroberto        /*
477181834Sroberto         *  IF the option has an empty value,
478181834Sroberto         *  THEN we set the argument to the occurrence count.
479181834Sroberto         */
480290001Sglebius        if (  (pOD->optArg.argString == NULL)
481290001Sglebius           || (pOD->optArg.argString[0] == NUL) ) {
482181834Sroberto
483290001Sglebius            printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
484290001Sglebius                   pOD->optOccCt);
485290001Sglebius            continue;
486290001Sglebius        }
487181834Sroberto
488181834Sroberto        /*
489181834Sroberto         *  This option has a text value
490181834Sroberto         */
491290001Sglebius        printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
492290001Sglebius        print_quot_str(pOD->optArg.argString);
493290001Sglebius        printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
494290001Sglebius
495181834Sroberto    } while (++optIx < pOpts->presetOptCt );
496181834Sroberto
497181834Sroberto    if (  ((pOpts->fOptSet & OPTPROC_REORDER) != 0)
498290001Sglebius       && (pOpts->curOptIdx < pOpts->origArgCt))
499290001Sglebius        print_reordering(pOpts);
500290001Sglebius
501290001Sglebius    fflush(stdout);
502181834Sroberto}
503181834Sroberto
504290001Sglebius/** @}
505290001Sglebius *
506181834Sroberto * Local Variables:
507181834Sroberto * mode: C
508181834Sroberto * c-file-style: "stroustrup"
509181834Sroberto * indent-tabs-mode: nil
510181834Sroberto * End:
511181834Sroberto * end of autoopts/putshell.c */
512