Ignore:
Timestamp:
Mar 31, 2018, 12:01:55 AM (7 years ago)
Author:
bird
Message:

kmk_ln, kmk_mkdir, kmk_mv, kmk_printf: changed to use getopt_r and got rid of remaining static buffers.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/kmkbuiltin/printf.c

    r3192 r3215  
    5050*   Header Files                                                                                                                 *
    5151*********************************************************************************************************************************/
     52#define FAKES_NO_GETOPT_H /* bird */
    5253#if !defined(KMK_BUILTIN_STANDALONE) && !defined(BUILTIN) && !defined(SHELL)
    5354# include "../makeint.h"
     
    7071#include <string.h>
    7172#include <unistd.h>
    72 #include "getopt.h"
     73#include "getopt_r.h"
    7374#ifdef __sun__
    7475# include "solfakes.h"
     
    139140{
    140141    PKMKBUILTINCTX pCtx;
     142    /* former globals */
    141143    size_t b_length;
    142144    char *b_fmt;
     
    146148    char *g_o;
    147149#endif
     150    /* former function level statics in common_printf(); both need freeing. */
     151    char *a, *t;
     152
     153    /* former function level statics in conv_expand(); needs freeing. */
     154    char *conv_str;
     155
    148156    /* Buffer the output because windows doesn't do line buffering of stdout. */
    149157    size_t g_cchBuf;
     
    167175*   Internal Functions                                                                                                           *
    168176*********************************************************************************************************************************/
    169 static int       common_printf(PPRINTFINSTANCE pThis, int argc, char *argv[]);
     177static int       common_printf(PPRINTFINSTANCE pThis, char *argv[], PKMKBUILTINCTX pCtx);
     178static int       common_printf_inner(PPRINTFINSTANCE pThis, char *argv[]);
    170179static void      conv_escape_str(PPRINTFINSTANCE, char *, void (*)(PPRINTFINSTANCE, int));
    171180static char     *conv_escape(PPRINTFINSTANCE, char *, char *);
    172 static char     *conv_expand(const char *);
     181static const char *conv_expand(PPRINTFINSTANCE, const char *);
    173182static int       getchr(PPRINTFINSTANCE);
    174183static double    getdouble(PPRINTFINSTANCE);
     
    191200int kmk_builtin_printf(int argc, char **argv, char **envp, PKMKBUILTINCTX pCtx)
    192201{
     202        PRINTFINSTANCE This;
     203        struct getopt_state_r gos;
    193204        int ch;
    194         PRINTFINSTANCE This;
    195         This.pCtx = pCtx;
    196         This.b_length = 0;
    197         This.b_fmt = NULL;
    198         This.rval = 0;
    199         This.gargv = NULL;
    200 #ifndef KMK_BUILTIN_STANDALONE
    201         This.g_o = NULL;
    202 #endif
    203         This.g_cchBuf = 0;
    204 
    205         /* kmk: reset getopt, set progname and reset buffer. */
    206         opterr = 1;
    207         optarg = NULL;
    208         optopt = 0;
    209         optind = 0; /* init */
    210 
    211         while ((ch = getopt_long(argc, argv, "", long_options, NULL)) != -1) {
     205
     206        getopt_initialize_r(&gos, argc, argv, "", long_options, envp, pCtx);
     207        while ((ch = getopt_long_r(&gos, NULL)) != -1) {
    212208                switch (ch) {
    213209                case 261:
     
    221217                }
    222218        }
    223         argc -= optind;
    224         argv += optind;
     219        argc -= gos.optind;
     220        argv += gos.optind;
    225221
    226222        if (argc < 1)
    227223                return usage(pCtx, 1);
    228         return common_printf(&This, argc, argv);
     224
     225#ifndef KMK_BUILTIN_STANDALONE
     226        This.g_o = NULL;
     227#endif
     228        return common_printf(&This, argv, pCtx);
    229229}
    230230
     
    249249            fatal(NILF, strlen(funcname) + INTSTR_LENGTH, _("$(%s): no format string\n"), funcname);
    250250
    251         This.pCtx = NULL;
    252         This.b_length = 0;
    253         This.b_fmt = NULL;
    254         This.rval = 0;
    255         This.gargv = NULL;
    256         This.g_cchBuf = 0;
    257251        This.g_o = o;
    258 
    259         rc = common_printf(&This, argc, argv);
     252        rc = common_printf(&This, argv, NULL);
    260253        o = This.g_o;
    261254
     
    266259#endif /* KMK_BUILTIN_STANDALONE */
    267260
    268 static int common_printf(PPRINTFINSTANCE pThis, int argc, char *argv[])
     261static int common_printf(PPRINTFINSTANCE pThis, char *argv[], PKMKBUILTINCTX pCtx)
     262{
     263        int rc;
     264
     265        /* Init all but g_o. */
     266        pThis->pCtx = pCtx;
     267        pThis->b_length = 0;
     268        pThis->b_fmt = NULL;
     269        pThis->rval = 0;
     270        pThis->gargv = NULL;
     271        pThis->g_cchBuf = 0;
     272        pThis->a = NULL;
     273        pThis->t = NULL;
     274        pThis->conv_str = NULL;
     275
     276        rc = common_printf_inner(pThis, argv);
     277
     278        /* Cleanup allocations. */
     279        if (pThis->a) {
     280                free(pThis->a);
     281                pThis->a = NULL;
     282        }
     283        if (pThis->t) {
     284                free(pThis->t);
     285                pThis->t = NULL;
     286        }
     287        if (pThis->conv_str) {
     288                free(pThis->conv_str);
     289                pThis->conv_str = NULL;
     290        }
     291        return rc;
     292}
     293
     294static int common_printf_inner(PPRINTFINSTANCE pThis, char *argv[])
    269295{
    270296        char *fmt, *start;
     
    275301        char longbuf[64];
    276302
    277         /* kmk: reinitialize globals */
    278         pThis->b_length = 0;
    279         pThis->b_fmt = NULL;
    280         pThis->rval = 0;
    281         pThis->gargv = NULL;
    282         pThis->g_cchBuf = 0;
    283303        format = *argv;
    284304        pThis->gargv = ++argv;
     
    338358
    339359                        case 'B': {
    340                                 const char *p = conv_expand(getstr(pThis));
     360                                const char *p = conv_expand(pThis, getstr(pThis));
    341361                                *fmt = 's';
    342362                                PF(start, p);
     
    347367                                 * but the string we generate might have
    348368                                 * embedded nulls. */
    349                                 static char *a, *t;
    350369                                char *cp = getstr(pThis);
    351370                                /* Free on entry in case shell longjumped out */
    352                                 if (a != NULL)
    353                                         free(a);
    354                                 a = NULL;
    355                                 if (t != NULL)
    356                                         free(t);
    357                                 t = NULL;
     371                                if (pThis->a != NULL) {
     372                                        free(pThis->a);
     373                                        pThis->a = NULL;
     374                                }
     375                                if (pThis->t != NULL) {
     376                                        free(pThis->t);
     377                                        pThis->t = NULL;
     378                                }
    358379                                /* Count number of bytes we want to output */
    359380                                pThis->b_length = 0;
    360381                                conv_escape_str(pThis, cp, b_count);
    361                                 t = malloc(pThis->b_length + 1);
    362                                 if (t == NULL)
     382                                pThis->t = malloc(pThis->b_length + 1);
     383                                if (pThis->t == NULL)
    363384                                        break;
    364                                 memset(t, 'x', pThis->b_length);
    365                                 t[pThis->b_length] = 0;
     385                                memset(pThis->t, 'x', pThis->b_length);
     386                                pThis->t[pThis->b_length] = 0;
    366387                                /* Get printf to calculate the lengths */
    367388                                *fmt = 's';
    368                                 APF(&a, start, t);
    369                                 pThis->b_fmt = a;
     389                                APF(&pThis->a, start, pThis->t);
     390                                pThis->b_fmt = pThis->a;
    370391                                /* Output leading spaces and data bytes */
    371392                                conv_escape_str(pThis, cp, b_output);
     
    710731/* expand a string so that everything is printable */
    711732
    712 static char *
    713 conv_expand(const char *str)
    714 {
    715         static char *conv_str;
    716         static char no_memory[] = "<no memory>";
     733static const char *
     734conv_expand(PPRINTFINSTANCE pThis, const char *str)
     735{
     736        static const char no_memory[] = "<no memory>";
    717737        char *cp;
    718738        int ch;
    719739
    720         if (conv_str)
    721                 free(conv_str);
     740        if (pThis->conv_str)
     741                free(pThis->conv_str);
    722742        /* get a buffer that is definitely large enough.... */
    723         conv_str = malloc(4 * strlen(str) + 1);
    724         if (!conv_str)
     743        pThis->conv_str = cp = malloc(4 * strlen(str) + 1);
     744        if (!cp)
    725745                return no_memory;
    726         cp = conv_str;
    727746
    728747        while ((ch = *(const unsigned char *)str++) != '\0') {
     
    771790
    772791        *cp = 0;
    773         return conv_str;
     792        return pThis->conv_str;
    774793}
    775794
Note: See TracChangeset for help on using the changeset viewer.