From d7dd590ab60e4bad9f6976129132fe125cefaf99 Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Tue, 15 Mar 2022 22:26:11 -0400 Subject: Remove dash Moved to https://git.causal.agency/dash/ and jorts. --- bin/dash/src/bltin/printf.c | 478 -------------------------------------------- 1 file changed, 478 deletions(-) delete mode 100644 bin/dash/src/bltin/printf.c (limited to 'bin/dash/src/bltin/printf.c') diff --git a/bin/dash/src/bltin/printf.c b/bin/dash/src/bltin/printf.c deleted file mode 100644 index 7785735b..00000000 --- a/bin/dash/src/bltin/printf.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * Copyright (c) 1997-2005 - * Herbert Xu . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -static int conv_escape_str(char *, char **); -static char *conv_escape(char *, int *); -static int getchr(void); -static double getdouble(void); -static uintmax_t getuintmax(int); -static char *getstr(void); -static char *mklong(const char *, const char *); -static void check_conversion(const char *, const char *); - -static int rval; -static char **gargv; - -#define isodigit(c) ((c) >= '0' && (c) <= '7') -#define octtobin(c) ((c) - '0') - -#include "bltin.h" -#include "system.h" - -#define PF(f, func) { \ - switch ((char *)param - (char *)array) { \ - default: \ - (void)printf(f, array[0], array[1], func); \ - break; \ - case sizeof(*param): \ - (void)printf(f, array[0], func); \ - break; \ - case 0: \ - (void)printf(f, func); \ - break; \ - } \ -} - -#define ASPF(sp, f, func) ({ \ - int ret; \ - switch ((char *)param - (char *)array) { \ - default: \ - ret = xasprintf(sp, f, array[0], array[1], func); \ - break; \ - case sizeof(*param): \ - ret = xasprintf(sp, f, array[0], func); \ - break; \ - case 0: \ - ret = xasprintf(sp, f, func); \ - break; \ - } \ - ret; \ -}) - - -static int print_escape_str(const char *f, int *param, int *array, char *s) -{ - struct stackmark smark; - char *p, *q; - int done; - int len; - int total; - - setstackmark(&smark); - done = conv_escape_str(s, &q); - p = stackblock(); - len = q - p; - total = len - 1; - - q[-1] = (!!((f[1] - 's') | done) - 1) & f[2]; - total += !!q[-1]; - if (f[1] == 's') - goto easy; - - p = makestrspace(len, q); - memset(p, 'X', total); - p[total] = 0; - - q = stackblock(); - total = ASPF(&p, f, p); - - len = strchrnul(p, 'X') - p; - memcpy(p + len, q, strspn(p + len, "X")); - -easy: - out1mem(p, total); - - popstackmark(&smark); - return done; -} - - -int printfcmd(int argc, char *argv[]) -{ - char *fmt; - char *format; - int ch; - - rval = 0; - - nextopt(nullstr); - - argv = argptr; - format = *argv; - - if (!format) - error("usage: printf format [arg ...]"); - - gargv = ++argv; - -#define SKIP1 "#-+ 0" -#define SKIP2 "*0123456789" - do { - /* - * Basic algorithm is to scan the format string for conversion - * specifications -- once one is found, find out if the field - * width or precision is a '*'; if it is, gather up value. - * Note, format strings are reused as necessary to use up the - * provided arguments, arguments of zero/null string are - * provided to use up the format string. - */ - - /* find next format specification */ - for (fmt = format; (ch = *fmt++) ;) { - char *start; - char nextch; - int array[2]; - int *param; - - if (ch == '\\') { - int c_ch; - fmt = conv_escape(fmt, &c_ch); - ch = c_ch; - goto pc; - } - if (ch != '%' || (*fmt == '%' && (++fmt || 1))) { -pc: - putchar(ch); - continue; - } - - /* Ok - we've found a format specification, - Save its address for a later printf(). */ - start = fmt - 1; - param = array; - - /* skip to field width */ - fmt += strspn(fmt, SKIP1); - if (*fmt == '*') { - ++fmt; - *param++ = getuintmax(1); - } else { - /* skip to possible '.', - * get following precision - */ - fmt += strspn(fmt, SKIP2); - } - - if (*fmt == '.') { - ++fmt; - if (*fmt == '*') { - ++fmt; - *param++ = getuintmax(1); - } else - fmt += strspn(fmt, SKIP2); - } - - ch = *fmt; - if (!ch) - error("missing format character"); - /* null terminate format string to we can use it - as an argument to printf. */ - nextch = fmt[1]; - fmt[1] = 0; - switch (ch) { - - case 'b': - *fmt = 's'; - /* escape if a \c was encountered */ - if (print_escape_str(start, param, array, - getstr())) - goto out; - *fmt = 'b'; - break; - case 'c': { - int p = getchr(); - PF(start, p); - break; - } - case 's': { - char *p = getstr(); - PF(start, p); - break; - } - case 'd': - case 'i': { - uintmax_t p = getuintmax(1); - start = mklong(start, fmt); - PF(start, p); - break; - } - case 'o': - case 'u': - case 'x': - case 'X': { - uintmax_t p = getuintmax(0); - start = mklong(start, fmt); - PF(start, p); - break; - } - case 'a': - case 'A': - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': { - double p = getdouble(); - PF(start, p); - break; - } - default: - error("%s: invalid directive", start); - } - *++fmt = nextch; - } - } while (gargv != argv && *gargv); - -out: - return rval; -} - - -/* - * Print SysV echo(1) style escape string - * Halts processing string if a \c escape is encountered. - */ -static int -conv_escape_str(char *str, char **sp) -{ - int c; - int ch; - char *cp; - - /* convert string into a temporary buffer... */ - STARTSTACKSTR(cp); - - do { - c = ch = *str++; - if (ch != '\\') - continue; - - c = *str++; - if (c == 'c') { - /* \c as in SYSV echo - abort all processing.... */ - c = ch = 0x100; - continue; - } - - /* - * %b string octal constants are not like those in C. - * They start with a \0, and are followed by 0, 1, 2, - * or 3 octal digits. - */ - if (c == '0' && isodigit(*str)) - str++; - - /* Finally test for sequences valid in the format string */ - str = conv_escape(str - 1, &c); - } while (STPUTC(c, cp), (char)ch); - - *sp = cp; - - return ch; -} - -/* - * Print "standard" escape characters - */ -static char * -conv_escape(char *str, int *conv_ch) -{ - int value; - int ch; - - ch = *str; - - switch (ch) { - default: - if (!isodigit(*str)) { - value = '\\'; - goto out; - } - - ch = 3; - value = 0; - do { - value <<= 3; - value += octtobin(*str++); - } while (isodigit(*str) && --ch); - goto out; - - case '\\': value = '\\'; break; /* backslash */ - case 'a': value = '\a'; break; /* alert */ - case 'b': value = '\b'; break; /* backspace */ - case 'f': value = '\f'; break; /* form-feed */ - case 'n': value = '\n'; break; /* newline */ - case 'r': value = '\r'; break; /* carriage-return */ - case 't': value = '\t'; break; /* tab */ - case 'v': value = '\v'; break; /* vertical-tab */ - } - - str++; -out: - *conv_ch = value; - return str; -} - -static char * -mklong(const char *str, const char *ch) -{ - /* - * Replace a string like "%92.3u" with "%92.3"PRIuMAX. - * - * Although C99 does not guarantee it, we assume PRIiMAX, - * PRIoMAX, PRIuMAX, PRIxMAX, and PRIXMAX are all the same - * as PRIdMAX with the final 'd' replaced by the corresponding - * character. - */ - - char *copy; - size_t len; - - len = ch - str + sizeof(PRIdMAX); - STARTSTACKSTR(copy); - copy = makestrspace(len, copy); - memcpy(copy, str, len - sizeof(PRIdMAX)); - memcpy(copy + len - sizeof(PRIdMAX), PRIdMAX, sizeof(PRIdMAX)); - copy[len - 2] = *ch; - return (copy); -} - -static int -getchr(void) -{ - int val = 0; - - if (*gargv) - val = **gargv++; - return val; -} - -static char * -getstr(void) -{ - char *val = nullstr; - - if (*gargv) - val = *gargv++; - return val; -} - -static uintmax_t -getuintmax(int sign) -{ - uintmax_t val = 0; - char *cp, *ep; - - cp = *gargv; - if (cp == NULL) - goto out; - gargv++; - - val = (unsigned char) cp[1]; - if (*cp == '\"' || *cp == '\'') - goto out; - - errno = 0; - val = sign ? strtoimax(cp, &ep, 0) : strtoumax(cp, &ep, 0); - check_conversion(cp, ep); -out: - return val; -} - -static double -getdouble(void) -{ - double val; - char *cp, *ep; - - cp = *gargv; - if (cp == NULL) - return 0; - gargv++; - - if (*cp == '\"' || *cp == '\'') - return (unsigned char) cp[1]; - - errno = 0; - val = strtod(cp, &ep); - check_conversion(cp, ep); - return val; -} - -static void -check_conversion(const char *s, const char *ep) -{ - if (*ep) { - if (ep == s) - warnx("%s: expected numeric value", s); - else - warnx("%s: not completely converted", s); - rval = 1; - } else if (errno == ERANGE) { - warnx("%s: %s", s, strerror(ERANGE)); - rval = 1; - } -} - -int -echocmd(int argc, char **argv) -{ - const char *lastfmt = snlfmt; - int nonl; - - if (*++argv && equal(*argv, "-n")) { - argv++; - lastfmt = "%s"; - } - - do { - const char *fmt = "%s "; - char *s = *argv; - - if (!s || !*++argv) - fmt = lastfmt; - - nonl = print_escape_str(fmt, NULL, NULL, s ?: nullstr); - } while (!nonl && *argv); - return 0; -} -- cgit 1.4.1