Ignore:
Timestamp:
Mar 26, 2018, 10:25:56 PM (7 years ago)
Author:
bird
Message:

kmkbuiltin: funnel output thru output.c (usually via err.c).

File:
1 edited

Legend:

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

    r3188 r3192  
    4646#endif*/ /* not lint */
    4747
    48 #if !defined(kmk_builtin_printf) && !defined(BUILTIN) && !defined(SHELL)
     48
     49/*********************************************************************************************************************************
     50*   Header Files                                                                                                                 *
     51*********************************************************************************************************************************/
     52#if !defined(KMK_BUILTIN_STANDALONE) && !defined(BUILTIN) && !defined(SHELL)
    4953# include "../makeint.h"
    5054# include "../filedef.h"
     
    8387#endif
    8488
    85 
     89#if 0
     90#ifdef BUILTIN          /* csh builtin */
     91#define kmk_builtin_printf progprintf
     92#endif
     93
     94#ifdef SHELL            /* sh (aka ash) builtin */
     95#define kmk_builtin_printf printfcmd
     96#include "../../bin/sh/bltin/bltin.h"
     97#endif /* SHELL */
     98#endif
     99
     100
     101/*********************************************************************************************************************************
     102*   Defined Constants And Macros                                                                                                 *
     103*********************************************************************************************************************************/
    86104#if 0 /*def __GNUC__ - bird: gcc complains about non-ISO-standard escape. */
    87105#define ESCAPE '\e'
     
    90108#endif
    91109
    92 
    93 static size_t   b_length;
    94 static char     *b_fmt;
    95 static int      rval;
    96 static char  **gargv;
    97 #if !defined(kmk_builtin_printf) && !defined(BUILTIN) && !defined(SHELL)
    98 static char *g_o = NULL;
    99 #endif
    100 static struct option long_options[] =
    101 {
    102     { "help",                                           no_argument, 0, 261 },
    103     { "version",                                        no_argument, 0, 262 },
    104     { 0, 0,     0, 0 },
    105 };
    106 
    107 
    108 static int       common_printf(int argc, char *argv[]);
    109 static void      conv_escape_str(char *, void (*)(int));
    110 static char     *conv_escape(char *, char *);
    111 static char     *conv_expand(const char *);
    112 static int       getchr(void);
    113 static double    getdouble(void);
    114 static int       getwidth(void);
    115 static intmax_t  getintmax(void);
    116 static uintmax_t getuintmax(void);
    117 static char     *getstr(void);
    118 static char     *mklong(const char *, int);
    119 static void      check_conversion(const char *, const char *);
    120 static int       usage(FILE *);
    121 
    122 static int      flush_buffer(void);
    123 static void     b_count(int);
    124 static void     b_output(int);
    125 static int      wrap_putchar(int ch);
    126 static int      wrap_printf(const char *, ...);
    127 
    128 #ifdef BUILTIN          /* csh builtin */
    129 #define kmk_builtin_printf progprintf
    130 #endif
    131 
    132 #ifdef SHELL            /* sh (aka ash) builtin */
    133 #define kmk_builtin_printf printfcmd
    134 #include "../../bin/sh/bltin/bltin.h"
    135 #endif /* SHELL */
    136 
    137 /* Buffer the output because windows doesn't do line buffering of stdout. */
    138 static char     g_achBuf[256];
    139 static size_t   g_cchBuf;
    140 
    141110#define PF(f, func) { \
    142111        if (fieldwidth != -1) { \
    143112                if (precision != -1) \
    144                         (void)wrap_printf(f, fieldwidth, precision, func); \
     113                        (void)wrap_printf(pThis, f, fieldwidth, precision, func); \
    145114                else \
    146                         (void)wrap_printf(f, fieldwidth, func); \
     115                        (void)wrap_printf(pThis, f, fieldwidth, func); \
    147116        } else if (precision != -1) \
    148                 (void)wrap_printf(f, precision, func); \
     117                (void)wrap_printf(pThis, f, precision, func); \
    149118        else \
    150                 (void)wrap_printf(f, func); \
     119                (void)wrap_printf(pThis, f, func); \
    151120}
    152121
     
    163132}
    164133
    165 int kmk_builtin_printf(int argc, char *argv[], char **envp)
    166 {
    167         int rc;
     134
     135/*********************************************************************************************************************************
     136*   Structures and Typedefs                                                                                                      *
     137*********************************************************************************************************************************/
     138typedef struct PRINTFINSTANCE
     139{
     140    PKMKBUILTINCTX pCtx;
     141    size_t b_length;
     142    char *b_fmt;
     143    int rval;
     144    char **gargv;
     145#ifndef KMK_BUILTIN_STANDALONE
     146    char *g_o;
     147#endif
     148    /* Buffer the output because windows doesn't do line buffering of stdout. */
     149    size_t g_cchBuf;
     150    char g_achBuf[256];
     151} PRINTFINSTANCE;
     152typedef PRINTFINSTANCE *PPRINTFINSTANCE;
     153
     154
     155/*********************************************************************************************************************************
     156*   Global Variables                                                                                                             *
     157*********************************************************************************************************************************/
     158static struct option long_options[] =
     159{
     160    { "help",                                           no_argument, 0, 261 },
     161    { "version",                                        no_argument, 0, 262 },
     162    { 0, 0,     0, 0 },
     163};
     164
     165
     166/*********************************************************************************************************************************
     167*   Internal Functions                                                                                                           *
     168*********************************************************************************************************************************/
     169static int       common_printf(PPRINTFINSTANCE pThis, int argc, char *argv[]);
     170static void      conv_escape_str(PPRINTFINSTANCE, char *, void (*)(PPRINTFINSTANCE, int));
     171static char     *conv_escape(PPRINTFINSTANCE, char *, char *);
     172static char     *conv_expand(const char *);
     173static int       getchr(PPRINTFINSTANCE);
     174static double    getdouble(PPRINTFINSTANCE);
     175static int       getwidth(PPRINTFINSTANCE);
     176static intmax_t  getintmax(PPRINTFINSTANCE);
     177static uintmax_t getuintmax(PPRINTFINSTANCE);
     178static char     *getstr(PPRINTFINSTANCE);
     179static char     *mklong(PPRINTFINSTANCE, const char *, int, char[64]);
     180static void      check_conversion(PPRINTFINSTANCE, const char *, const char *);
     181static int       usage(PKMKBUILTINCTX, int);
     182
     183static int      flush_buffer(PPRINTFINSTANCE);
     184static void     b_count(PPRINTFINSTANCE, int);
     185static void     b_output(PPRINTFINSTANCE, int);
     186static int      wrap_putchar(PPRINTFINSTANCE, int ch);
     187static int      wrap_printf(PPRINTFINSTANCE, const char *, ...);
     188
     189
     190
     191int kmk_builtin_printf(int argc, char **argv, char **envp, PKMKBUILTINCTX pCtx)
     192{
    168193        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;
    169204
    170205        /* kmk: reset getopt, set progname and reset buffer. */
    171         g_progname = argv[0];
    172206        opterr = 1;
    173207        optarg = NULL;
     
    175209        optind = 0; /* init */
    176210
    177 #if !defined(SHELL) && !defined(BUILTIN) && !defined(kmk_builtin_printf) /* kmk did this already. */
    178         (void)setlocale (LC_ALL, "");
    179 #endif
    180 
    181211        while ((ch = getopt_long(argc, argv, "", long_options, NULL)) != -1) {
    182212                switch (ch) {
    183213                case 261:
    184                         usage(stdout);
     214                        usage(pCtx, 0);
    185215                        return 0;
    186216                case 262:
     
    188218                case '?':
    189219                default:
    190                         return usage(stderr);
     220                        return usage(pCtx, 1);
    191221                }
    192222        }
     
    194224        argv += optind;
    195225
    196         if (argc < 1) {
    197                 return usage(stderr);
    198         }
    199 
    200         rc = common_printf(argc, argv);
    201         return rc;
    202 }
    203 
    204 #ifndef kmk_builtin_printf
     226        if (argc < 1)
     227                return usage(pCtx, 1);
     228        return common_printf(&This, argc, argv);
     229}
     230
     231#ifdef KMK_BUILTIN_STANDALONE
     232int main(int argc, char **argv, char **envp)
     233{
     234        KMKBUILTINCTX Ctx = { "kmk_printf", NULL };
     235        setlocale(LC_ALL, "");
     236        return kmk_builtin_printf(argc, argv, envp, &Ctx);
     237}
     238#else /* KMK_BUILTIN_STANDALONE */
    205239/* entry point used by function.c $(printf ..,..). */
    206240char *kmk_builtin_func_printf(char *o, char **argv, const char *funcname)
    207241{
     242        PRINTFINSTANCE This;
    208243        int rc;
    209244        int argc;
     
    211246        for (argc = 0; argv[argc] != NULL; argc++)
    212247                /* nothing */;
    213 
    214         g_o = o;
    215         rc = common_printf(argc, argv);
    216         o = g_o;
    217         g_o = NULL;
     248        if (argc == 0)
     249            fatal(NILF, strlen(funcname) + INTSTR_LENGTH, _("$(%s): no format string\n"), funcname);
     250
     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;
     257        This.g_o = o;
     258
     259        rc = common_printf(&This, argc, argv);
     260        o = This.g_o;
    218261
    219262        if (rc != 0)
     
    221264        return o;
    222265}
    223 #endif
    224 
    225 static int common_printf(int argc, char *argv[])
     266#endif /* KMK_BUILTIN_STANDALONE */
     267
     268static int common_printf(PPRINTFINSTANCE pThis, int argc, char *argv[])
    226269{
    227270        char *fmt, *start;
     
    230273        char *format;
    231274        int ch;
     275        char longbuf[64];
    232276
    233277        /* kmk: reinitialize globals */
    234         b_length = 0;
    235         b_fmt = NULL;
    236         rval = 0;
    237         gargv = NULL;
    238         g_cchBuf = 0;
    239 
     278        pThis->b_length = 0;
     279        pThis->b_fmt = NULL;
     280        pThis->rval = 0;
     281        pThis->gargv = NULL;
     282        pThis->g_cchBuf = 0;
    240283        format = *argv;
    241         gargv = ++argv;
     284        pThis->gargv = ++argv;
    242285
    243286#define SKIP1   "#-+ 0"
     
    257300                        if (ch == '\\') {
    258301                                char c_ch;
    259                                 fmt = conv_escape(fmt, &c_ch);
    260                                 wrap_putchar(c_ch);
     302                                fmt = conv_escape(pThis, fmt, &c_ch);
     303                                wrap_putchar(pThis, c_ch);
    261304                                continue;
    262305                        }
    263306                        if (ch != '%' || (*fmt == '%' && ++fmt)) {
    264                                 (void)wrap_putchar(ch);
     307                                (void)wrap_putchar(pThis, ch);
    265308                                continue;
    266309                        }
     
    272315                        /* skip to field width */
    273316                        fmt += strspn(fmt, SKIP1);
    274                         fieldwidth = *fmt == '*' ? getwidth() : -1;
     317                        fieldwidth = *fmt == '*' ? getwidth(pThis) : -1;
    275318
    276319                        /* skip to possible '.', get following precision */
     
    278321                        if (*fmt == '.')
    279322                                ++fmt;
    280                         precision = *fmt == '*' ? getwidth() : -1;
     323                        precision = *fmt == '*' ? getwidth(pThis) : -1;
    281324
    282325                        fmt += strspn(fmt, SKIP2);
     
    284327                        ch = *fmt;
    285328                        if (!ch) {
    286                                 flush_buffer();
    287                                 warnx("missing format character");
     329                                flush_buffer(pThis);
     330                                warnx(pThis->pCtx, "missing format character");
    288331                                return (1);
    289332                        }
     
    295338
    296339                        case 'B': {
    297                                 const char *p = conv_expand(getstr());
     340                                const char *p = conv_expand(getstr(pThis));
    298341                                *fmt = 's';
    299342                                PF(start, p);
     
    305348                                 * embedded nulls. */
    306349                                static char *a, *t;
    307                                 char *cp = getstr();
     350                                char *cp = getstr(pThis);
    308351                                /* Free on entry in case shell longjumped out */
    309352                                if (a != NULL)
     
    314357                                t = NULL;
    315358                                /* Count number of bytes we want to output */
    316                                 b_length = 0;
    317                                 conv_escape_str(cp, b_count);
    318                                 t = malloc(b_length + 1);
     359                                pThis->b_length = 0;
     360                                conv_escape_str(pThis, cp, b_count);
     361                                t = malloc(pThis->b_length + 1);
    319362                                if (t == NULL)
    320363                                        break;
    321                                 memset(t, 'x', b_length);
    322                                 t[b_length] = 0;
     364                                memset(t, 'x', pThis->b_length);
     365                                t[pThis->b_length] = 0;
    323366                                /* Get printf to calculate the lengths */
    324367                                *fmt = 's';
    325368                                APF(&a, start, t);
    326                                 b_fmt = a;
     369                                pThis->b_fmt = a;
    327370                                /* Output leading spaces and data bytes */
    328                                 conv_escape_str(cp, b_output);
     371                                conv_escape_str(pThis, cp, b_output);
    329372                                /* Add any trailing spaces */
    330                                 wrap_printf("%s", b_fmt);
     373                                wrap_printf(pThis, "%s", pThis->b_fmt);
    331374                                break;
    332375                        }
    333376                        case 'c': {
    334                                 char p = getchr();
     377                                char p = getchr(pThis);
    335378                                PF(start, p);
    336379                                break;
    337380                        }
    338381                        case 's': {
    339                                 char *p = getstr();
     382                                char *p = getstr(pThis);
    340383                                PF(start, p);
    341384                                break;
     
    343386                        case 'd':
    344387                        case 'i': {
    345                                 intmax_t p = getintmax();
    346                                 char *f = mklong(start, ch);
     388                                intmax_t p = getintmax(pThis);
     389                                char *f = mklong(pThis, start, ch, longbuf);
    347390                                PF(f, p);
    348391                                break;
     
    352395                        case 'x':
    353396                        case 'X': {
    354                                 uintmax_t p = getuintmax();
    355                                 char *f = mklong(start, ch);
     397                                uintmax_t p = getuintmax(pThis);
     398                                char *f = mklong(pThis, start, ch, longbuf);
    356399                                PF(f, p);
    357400                                break;
     
    362405                        case 'g':
    363406                        case 'G': {
    364                                 double p = getdouble();
     407                                double p = getdouble(pThis);
    365408                                PF(start, p);
    366409                                break;
    367410                        }
    368411                        default:
    369                                 flush_buffer();
    370                                 warnx("%s: invalid directive", start);
     412                                flush_buffer(pThis);
     413                                warnx(pThis->pCtx, "%s: invalid directive", start);
    371414                                return 1;
    372415                        }
     
    374417                        *fmt = nextch;
    375418                        /* escape if a \c was encountered */
    376                         if (rval & 0x100) {
    377                                 flush_buffer();
    378                                 return rval & ~0x100;
    379                         }
    380                 }
    381         } while (gargv != argv && *gargv);
    382 
    383         flush_buffer();
    384         return rval;
     419                        if (pThis->rval & 0x100) {
     420                                flush_buffer(pThis);
     421                                return pThis->rval & ~0x100;
     422                        }
     423                }
     424        } while (pThis->gargv != argv && *pThis->gargv);
     425
     426        flush_buffer(pThis);
     427        return pThis->rval;
    385428}
    386429
     
    390433static void
    391434/*ARGSUSED*/
    392 b_count(int ch)
    393 {
    394         b_length++;
     435b_count(PPRINTFINSTANCE pThis, int ch)
     436{
     437        pThis->b_length++;
    395438        (void)ch;
    396439}
     
    399442
    400443static void
    401 b_output(int ch)
     444b_output(PPRINTFINSTANCE pThis, int ch)
    402445{
    403446        for (;;) {
    404                 switch (*b_fmt++) {
     447                switch (*pThis->b_fmt++) {
    405448                case 0:
    406                         b_fmt--;
     449                        pThis->b_fmt--;
    407450                        return;
    408451                case ' ':
    409                         wrap_putchar(' ');
     452                        wrap_putchar(pThis, ' ');
    410453                        break;
    411454                default:
    412                         wrap_putchar(ch);
     455                        wrap_putchar(pThis, ch);
    413456                        return;
    414457                }
     
    416459}
    417460
    418 static int wrap_putchar(int ch)
    419 {
    420 #ifndef kmk_builtin_printf
    421         if (g_o) {
     461static int wrap_putchar(PPRINTFINSTANCE pThis, int ch)
     462{
     463#ifndef KMK_BUILTIN_STANDALONE
     464        if (pThis->g_o) {
    422465                char sz[2];
    423466                sz[0] = ch; sz[1] = '\0';
    424                 g_o = variable_buffer_output(g_o, sz, 1);
    425                 return ch;
    426         }
     467                pThis->g_o = variable_buffer_output(pThis->g_o, sz, 1);
     468        }
     469        else
    427470#endif
    428471        /* Buffered output. */
    429         if (g_cchBuf + 1 < sizeof(g_achBuf)) {
    430                 g_achBuf[g_cchBuf++] = ch;
     472        if (pThis->g_cchBuf + 1 < sizeof(pThis->g_achBuf)) {
     473                pThis->g_achBuf[pThis->g_cchBuf++] = ch;
    431474        } else {
    432                 int rc = flush_buffer();
    433                 g_achBuf[g_cchBuf++] = ch;
     475                int rc = flush_buffer(pThis);
     476                pThis->g_achBuf[pThis->g_cchBuf++] = ch;
    434477                if (rc)
    435478                        return -1;
     
    438481}
    439482
    440 static int wrap_printf(const char * fmt, ...)
     483static int wrap_printf(PPRINTFINSTANCE pThis, const char * fmt, ...)
    441484{
    442485        ssize_t cchRet;
     
    448491        va_end(va);
    449492        if (cchRet >= 0) {
    450 #ifndef kmk_builtin_printf
    451                 if (g_o) {
    452                         g_o = variable_buffer_output(g_o, pszTmp, cchRet);
     493#ifndef KMK_BUILTIN_STANDALONE
     494                if (pThis->g_o) {
     495                        pThis->g_o = variable_buffer_output(pThis->g_o, pszTmp, cchRet);
    453496                } else
    454497#endif
    455498                {
    456                         if (cchRet + g_cchBuf <= sizeof(g_achBuf)) {
     499                        if (cchRet + pThis->g_cchBuf <= sizeof(pThis->g_achBuf)) {
    457500                                /* We've got space in the buffer. */
    458                                 memcpy(&g_achBuf[g_cchBuf], pszTmp, cchRet);
    459                                 g_cchBuf += cchRet;
     501                                memcpy(&pThis->g_achBuf[pThis->g_cchBuf], pszTmp, cchRet);
     502                                pThis->g_cchBuf += cchRet;
    460503                        } else {
    461504                                /* Try write out complete lines. */
     
    466509                                        const char *pchNewLine = strchr(pszLeft, '\n');
    467510                                        ssize_t     cchLine    = pchNewLine ? pchNewLine - pszLeft + 1 : cchLeft;
    468                                         if (g_cchBuf + cchLine <= sizeof(g_achBuf)) {
    469                                                 memcpy(&g_achBuf[g_cchBuf], pszLeft, cchLine);
    470                                                 g_cchBuf += cchLine;
     511                                        if (pThis->g_cchBuf + cchLine <= sizeof(pThis->g_achBuf)) {
     512                                                memcpy(&pThis->g_achBuf[pThis->g_cchBuf], pszLeft, cchLine);
     513                                                pThis->g_cchBuf += cchLine;
    471514                                        } else {
    472                                                 if (flush_buffer() < 0) {
     515                                                if (flush_buffer(pThis) < 0) {
    473516                                                        return -1;
    474517                                                }
    475                                                 if (fwrite(pszLeft, cchLine, 1, stdout) < 1) {
     518#ifndef KMK_BUILTIN_STANDALONE
     519                                                if (output_write_text(pThis->pCtx->pOut, 0,pszLeft, cchLine) < 1)
     520#else
     521                                                if (fwrite(pszLeft, cchLine, 1, stdout) < 1)
     522#endif
     523
    476524                                                        return -1;
    477                                                 }
    478525                                        }
    479526                                        pszLeft += cchLine;
     
    490537 * Flushes the g_abBuf/g_cchBuf.
    491538 */
    492 static int flush_buffer(void)
    493 {
    494     if (g_cchBuf > 0) {
    495                 ssize_t cchToWrite = g_cchBuf;
    496                 ssize_t cchWritten = fwrite(g_achBuf, 1, g_cchBuf, stdout);
    497                 g_cchBuf = 0;
     539static int flush_buffer(PPRINTFINSTANCE pThis)
     540{
     541    ssize_t cchToWrite = pThis->g_cchBuf;
     542    if (cchToWrite > 0) {
     543#ifndef KMK_BUILTIN_STANDALONE
     544                ssize_t cchWritten = output_write_text(pThis->pCtx->pOut, 0, pThis->g_achBuf, cchToWrite);
     545#else
     546                ssize_t cchWritten = fwrite(pThis->g_achBuf, 1, cchToWrite, stdout);
     547#endif
     548                pThis->g_cchBuf = 0;
    498549                if (cchWritten >= cchToWrite) {
    499550                        /* likely */
     
    509560
    510561                        while (off < cchToWrite) {
    511                                 cchWritten = fwrite(&g_achBuf[off], 1, cchToWrite - off, stdout);
     562#ifndef KMK_BUILTIN_STANDALONE
     563                                cchWritten = output_write_text(pThis->pCtx->pOut, 0, &pThis->g_achBuf[off], cchToWrite - off);
     564#else
     565                                cchWritten = fwrite(&pThis->g_achBuf[off], 1, cchToWrite - off, stdout);
     566#endif
    512567                                if (cchWritten > 0) {
    513568                                        off += cchWritten;
     
    530585 */
    531586static void
    532 conv_escape_str(char *str, void (*do_putchar)(int))
     587conv_escape_str(PPRINTFINSTANCE pThis, char *str, void (*do_putchar)(PPRINTFINSTANCE, int))
    533588{
    534589        int value;
     
    538593        while ((ch = *str++) != '\0') {
    539594                if (ch != '\\') {
    540                         do_putchar(ch);
     595                        do_putchar(pThis, ch);
    541596                        continue;
    542597                }
     
    545600                if (ch == 'c') {
    546601                        /* \c as in SYSV echo - abort all processing.... */
    547                         rval |= 0x100;
     602                        pThis->rval |= 0x100;
    548603                        break;
    549604                }
     
    561616                                octnum = (octnum << 3) | (*str++ - '0');
    562617                        }
    563                         do_putchar(octnum);
     618                        do_putchar(pThis, octnum);
    564619                        continue;
    565620                }
     
    567622                /* \[M][^|-]C as defined by vis(3) */
    568623                if (ch == 'M' && *str == '-') {
    569                         do_putchar(0200 | str[1]);
     624                        do_putchar(pThis, 0200 | str[1]);
    570625                        str += 2;
    571626                        continue;
     
    583638                        else
    584639                                value |= ch & 037;
    585                         do_putchar(value);
     640                        do_putchar(pThis, value);
    586641                        continue;
    587642                }
    588643
    589644                /* Finally test for sequences valid in the format string */
    590                 str = conv_escape(str - 1, &c);
    591                 do_putchar(c);
     645                str = conv_escape(pThis, str - 1, &c);
     646                do_putchar(pThis, c);
    592647        }
    593648}
     
    597652 */
    598653static char *
    599 conv_escape(char *str, char *conv_ch)
     654conv_escape(PPRINTFINSTANCE pThis, char *str, char *conv_ch)
    600655{
    601656        int value;
     
    643698
    644699        default:
    645                 warnx("unknown escape sequence `\\%c'", ch);
    646                 rval = 1;
     700                warnx(pThis->pCtx, "unknown escape sequence `\\%c'", ch);
     701                pThis->rval = 1;
    647702                value = ch;
    648703                break;
     
    720775
    721776static char *
    722 mklong(const char *str, int ch)
    723 {
    724         static char copy[64];
     777mklong(PPRINTFINSTANCE pThis, const char *str, int ch, char copy[64])
     778{
    725779        size_t len;
    726780
    727781        len = strlen(str) - 1;
    728         if (len > sizeof(copy) - 5) {
    729                 warnx("format %s too complex\n", str);
     782        if (len > 64 - 5) {
     783                warnx(pThis->pCtx, "format %s too complex\n", str);
    730784                len = 4;
    731785        }
     
    744798
    745799static int
    746 getchr(void)
    747 {
    748         if (!*gargv)
     800getchr(PPRINTFINSTANCE pThis)
     801{
     802        if (!*pThis->gargv)
    749803                return 0;
    750         return (int)**gargv++;
     804        return (int)**pThis->gargv++;
    751805}
    752806
    753807static char *
    754 getstr(void)
     808getstr(PPRINTFINSTANCE pThis)
    755809{
    756810        static char empty[] = "";
    757         if (!*gargv)
     811        if (!*pThis->gargv)
    758812                return empty;
    759         return *gargv++;
     813        return *pThis->gargv++;
    760814}
    761815
    762816static int
    763 getwidth(void)
     817getwidth(PPRINTFINSTANCE pThis)
    764818{
    765819        long val;
    766820        char *s, *ep;
    767821
    768         s = *gargv;
    769         if (!*gargv)
     822        s = *pThis->gargv;
     823        if (!s)
    770824                return (0);
    771         gargv++;
     825        pThis->gargv++;
    772826
    773827        errno = 0;
    774828        val = strtoul(s, &ep, 0);
    775         check_conversion(s, ep);
     829        check_conversion(pThis, s, ep);
    776830
    777831        /* Arbitrarily 'restrict' field widths to 1Mbyte */
    778832        if (val < 0 || val > 1 << 20) {
    779                 warnx("%s: invalid field width", s);
     833                warnx(pThis->pCtx, "%s: invalid field width", s);
    780834                return 0;
    781835        }
     
    785839
    786840static intmax_t
    787 getintmax(void)
     841getintmax(PPRINTFINSTANCE pThis)
    788842{
    789843        intmax_t val;
    790844        char *cp, *ep;
    791845
    792         cp = *gargv;
     846        cp = *pThis->gargv;
    793847        if (cp == NULL)
    794848                return 0;
    795         gargv++;
     849        pThis->gargv++;
    796850
    797851        if (*cp == '\"' || *cp == '\'')
     
    800854        errno = 0;
    801855        val = strtoimax(cp, &ep, 0);
    802         check_conversion(cp, ep);
     856        check_conversion(pThis, cp, ep);
    803857        return val;
    804858}
    805859
    806860static uintmax_t
    807 getuintmax(void)
     861getuintmax(PPRINTFINSTANCE pThis)
    808862{
    809863        uintmax_t val;
    810864        char *cp, *ep;
    811865
    812         cp = *gargv;
     866        cp = *pThis->gargv;
    813867        if (cp == NULL)
    814868                return 0;
    815         gargv++;
     869        pThis->gargv++;
    816870
    817871        if (*cp == '\"' || *cp == '\'')
     
    822876                cp++;
    823877        if (*cp == '-') {
    824                 warnx("%s: expected positive numeric value", cp);
    825                 rval = 1;
     878                warnx(pThis->pCtx, "%s: expected positive numeric value", cp);
     879                pThis->rval = 1;
    826880                return 0;
    827881        }
     
    829883        errno = 0;
    830884        val = strtoumax(cp, &ep, 0);
    831         check_conversion(cp, ep);
     885        check_conversion(pThis, cp, ep);
    832886        return val;
    833887}
    834888
    835889static double
    836 getdouble(void)
     890getdouble(PPRINTFINSTANCE pThis)
    837891{
    838892        double val;
    839893        char *ep;
    840 
    841         if (!*gargv)
     894        char *s;
     895
     896        s = *pThis->gargv;
     897        if (!s)
    842898                return (0.0);
    843 
    844         if (**gargv == '\"' || **gargv == '\'')
    845                 return (double) *((*gargv++)+1);
     899        pThis->gargv++;
     900
     901        if (*s == '\"' || *s == '\'')
     902                return (double) s[1];
    846903
    847904        errno = 0;
    848         val = strtod(*gargv, &ep);
    849         check_conversion(*gargv++, ep);
     905        val = strtod(s, &ep);
     906        check_conversion(pThis, s, ep);
    850907        return val;
    851908}
    852909
    853910static void
    854 check_conversion(const char *s, const char *ep)
     911check_conversion(PPRINTFINSTANCE pThis, const char *s, const char *ep)
    855912{
    856913        if (*ep) {
    857914                if (ep == s)
    858                         warnx("%s: expected numeric value", s);
     915                        warnx(pThis->pCtx, "%s: expected numeric value", s);
    859916                else
    860                         warnx("%s: not completely converted", s);
    861                 rval = 1;
     917                        warnx(pThis->pCtx, "%s: not completely converted", s);
     918                pThis->rval = 1;
    862919        } else if (errno == ERANGE) {
    863                 warnx("%s: %s", s, strerror(ERANGE));
    864                 rval = 1;
     920                warnx(pThis->pCtx, "%s: %s", s, strerror(ERANGE));
     921                pThis->rval = 1;
    865922        }
    866923}
    867924
    868925static int
    869 usage(FILE *pf)
    870 {
    871         fprintf(pf, "usage: %s format [arg ...]\n"
    872                                 "   or: %s --help\n"
    873                                 "   or: %s --version\n",
    874                         g_progname, g_progname, g_progname);
     926usage(PKMKBUILTINCTX pCtx, int fIsErr)
     927{
     928        kmk_builtin_ctx_printf(pCtx, fIsErr,
     929                               "usage: %s format [arg ...]\n"
     930                               "   or: %s --help\n"
     931                               "   or: %s --version\n",
     932                               pCtx->pszProgName, pCtx->pszProgName, pCtx->pszProgName);
    875933        return 1;
    876934}
     935
Note: See TracChangeset for help on using the changeset viewer.