📄 printf.def
字号:
case 'a': case 'A':#endif { char *f; floatmax_t p; p = getfloatmax (); f = mklong (start, FLOATMAX_CONV, sizeof(FLOATMAX_CONV) - 1); PF (f, p); break; } /* We don't output unrecognized format characters; we print an error message and return a failure exit status. */ default: builtin_error (_("`%c': invalid format character"), convch); PRETURN (EXECUTION_FAILURE); } modstart[0] = thisch; modstart[1] = nextch; } if (ferror (stdout)) { sh_wrerror (); clearerr (stdout); PRETURN (EXECUTION_FAILURE); } } while (garglist && garglist != list->next); if (conversion_error) retval = EXECUTION_FAILURE; PRETURN (retval);}static voidprintf_erange (s) char *s;{ builtin_error (_("warning: %s: %s"), s, strerror(ERANGE));}/* We duplicate a lot of what printf(3) does here. */static intprintstr (fmt, string, len, fieldwidth, precision) char *fmt; /* format */ char *string; /* expanded string argument */ int len; /* length of expanded string */ int fieldwidth; /* argument for width of `*' */ int precision; /* argument for precision of `*' */{#if 0 char *s;#endif int padlen, nc, ljust, i; int fw, pr; /* fieldwidth and precision */#if 0 if (string == 0 || *string == '\0')#else if (string == 0 || len == 0)#endif return 0;#if 0 s = fmt;#endif if (*fmt == '%') fmt++; ljust = fw = 0; pr = -1; /* skip flags */ while (strchr (SKIP1, *fmt)) { if (*fmt == '-') ljust = 1; fmt++; } /* get fieldwidth, if present */ if (*fmt == '*') { fmt++; fw = fieldwidth; if (fw < 0) { fw = -fw; ljust = 1; } } else if (DIGIT (*fmt)) { fw = *fmt++ - '0'; while (DIGIT (*fmt)) fw = (fw * 10) + (*fmt++ - '0'); } /* get precision, if present */ if (*fmt == '.') { fmt++; if (*fmt == '*') { fmt++; pr = precision; } else if (DIGIT (*fmt)) { pr = *fmt++ - '0'; while (DIGIT (*fmt)) pr = (pr * 10) + (*fmt++ - '0'); } }#if 0 /* If we remove this, get rid of `s'. */ if (*fmt != 'b' && *fmt != 'q') { internal_error ("format parsing problem: %s", s); fw = pr = 0; }#endif /* chars from string to print */ nc = (pr >= 0 && pr <= len) ? pr : len; padlen = fw - nc; if (padlen < 0) padlen = 0; if (ljust) padlen = -padlen; /* leading pad characters */ for (; padlen > 0; padlen--) PC (' '); /* output NC characters from STRING */ for (i = 0; i < nc; i++) PC (string[i]); /* output any necessary trailing padding */ for (; padlen < 0; padlen++) PC (' '); return (ferror (stdout) ? -1 : 0);} /* Convert STRING by expanding the escape sequences specified by the POSIX standard for printf's `%b' format string. If SAWC is non-null, perform the processing appropriate for %b arguments. In particular, recognize `\c' and use that as a string terminator. If we see \c, set *SAWC to 1 before returning. LEN is the length of STRING. *//* Translate a single backslash-escape sequence starting at ESTART (the character after the backslash) and return the number of characters consumed by the sequence. CP is the place to return the translated value. *SAWC is set to 1 if the escape sequence was \c, since that means to short-circuit the rest of the processing. If SAWC is null, we don't do the \c short-circuiting, and \c is treated as an unrecognized escape sequence; we also bypass the other processing specific to %b arguments. */static inttescape (estart, cp, lenp, sawc) char *estart; char *cp; int *lenp, *sawc;{ register char *p; int temp, c, evalue; unsigned long uvalue; p = estart; if (lenp) *lenp = 1; switch (c = *p++) {#if defined (__STDC__) case 'a': *cp = '\a'; break;#else case 'a': *cp = '\007'; break;#endif case 'b': *cp = '\b'; break; case 'e': case 'E': *cp = '\033'; break; /* ESC -- non-ANSI */ case 'f': *cp = '\f'; break; case 'n': *cp = '\n'; break; case 'r': *cp = '\r'; break; case 't': *cp = '\t'; break; case 'v': *cp = '\v'; break; /* The octal escape sequences are `\0' followed by up to three octal digits (if SAWC), or `\' followed by up to three octal digits (if !SAWC). As an extension, we allow the latter form even if SAWC. */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': evalue = OCTVALUE (c); for (temp = 2 + (!evalue && !!sawc); ISOCTAL (*p) && temp--; p++) evalue = (evalue * 8) + OCTVALUE (*p); *cp = evalue & 0xFF; break; /* And, as another extension, we allow \xNN, where each N is a hex digit. */ case 'x': for (temp = 2, evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++) evalue = (evalue * 16) + HEXVALUE (*p); if (p == estart + 1) { builtin_error (_("missing hex digit for \\x")); *cp = '\\'; return 0; } *cp = evalue & 0xFF; break;#if defined (HANDLE_MULTIBYTE) case 'u': case 'U': temp = (c == 'u') ? 4 : 8; /* \uNNNN \UNNNNNNNN */ for (uvalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++) uvalue = (uvalue * 16) + HEXVALUE (*p); if (p == estart + 1) { builtin_error (_("missing unicode digit for \\%c"), c); *cp = '\\'; return 0; } if (uvalue <= UCHAR_MAX) *cp = uvalue; else { temp = u32cconv (uvalue, cp); cp[temp] = '\0'; if (lenp) *lenp = temp; } break;#endif case '\\': /* \\ -> \ */ *cp = c; break; /* SAWC == 0 means that \', \", and \? are recognized as escape sequences, though the only processing performed is backslash removal. */ case '\'': case '"': case '?': if (!sawc) *cp = c; else { *cp = '\\'; return 0; } break; case 'c': if (sawc) { *sawc = 1; break; } /* other backslash escapes are passed through unaltered */ default: *cp = '\\'; return 0; } return (p - estart);}static char *bexpand (string, len, sawc, lenp) char *string; int len, *sawc, *lenp;{ int temp; char *ret, *r, *s, c;#if defined (HANDLE_MULTIBYTE) char mbch[25]; int mbind, mblen;#endif if (string == 0 || len == 0) { if (sawc) *sawc = 0; if (lenp) *lenp = 0; return ((char *)NULL); } ret = (char *)xmalloc (len + 1); for (r = ret, s = string; s && *s; ) { c = *s++; if (c != '\\' || *s == '\0') { *r++ = c; continue; } temp = 0;#if defined (HANDLE_MULTIBYTE) memset (mbch, '\0', sizeof (mbch)); s += tescape (s, mbch, &mblen, &temp);#else s += tescape (s, &c, (int *)NULL, &temp);#endif if (temp) { if (sawc) *sawc = 1; break; }#if defined (HANDLE_MULTIBYTE) for (mbind = 0; mbind < mblen; mbind++) *r++ = mbch[mbind];#else *r++ = c;#endif } *r = '\0'; if (lenp) *lenp = r - ret; return ret;}static char *vbadd (buf, blen) char *buf; int blen;{ size_t nlen; nlen = vblen + blen + 1; if (nlen >= vbsize) { vbsize = ((nlen + 63) >> 6) << 6; vbuf = (char *)xrealloc (vbuf, vbsize); } if (blen == 1) vbuf[vblen++] = buf[0]; else if (blen > 1) { FASTCOPY (buf, vbuf + vblen, blen); vblen += blen; } vbuf[vblen] = '\0';#ifdef DEBUG if (strlen (vbuf) != vblen) internal_error ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));#endif return vbuf;}static int#if defined (PREFER_STDARG)vbprintf (const char *format, ...)#elsevbprintf (format, va_alist) const char *format; va_dcl#endif{ va_list args; size_t nlen; int blen; SH_VA_START (args, format); blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args); va_end (args); nlen = vblen + blen + 1; if (nlen >= vbsize) { vbsize = ((nlen + 63) >> 6) << 6; vbuf = (char *)xrealloc (vbuf, vbsize); SH_VA_START (args, format); blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args); va_end (args); } vblen += blen; vbuf[vblen] = '\0';#ifdef DEBUG if (strlen (vbuf) != vblen) internal_error ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));#endif return (blen);}static char *mklong (str, modifiers, mlen) char *str; char *modifiers; size_t mlen;{ size_t len, slen; slen = strlen (str); len = slen + mlen + 1; if (len > conv_bufsize) { conv_bufsize = (((len + 1023) >> 10) << 10); conv_buf = (char *)xrealloc (conv_buf, conv_bufsize); } FASTCOPY (str, conv_buf, slen - 1); FASTCOPY (modifiers, conv_buf + slen - 1, mlen); conv_buf[len - 2] = str[slen - 1]; conv_buf[len - 1] = '\0'; return (conv_buf);}static intgetchr (){ int ret; if (garglist == 0) return ('\0'); ret = (int)garglist->word->word[0]; garglist = garglist->next; return ret;}static char *getstr (){ char *ret; if (garglist == 0) return (""); ret = garglist->word->word; garglist = garglist->next; return ret;}static intgetint (){ intmax_t ret; ret = getintmax (); if (ret > INT_MAX) { printf_erange (garglist->word->word); ret = INT_MAX; } else if (ret < INT_MIN) { printf_erange (garglist->word->word); ret = INT_MIN; } return ((int)ret);}static intmax_tgetintmax (){ intmax_t ret; char *ep; if (garglist == 0) return (0); if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') return asciicode (); errno = 0; ret = strtoimax (garglist->word->word, &ep, 0); if (*ep) { sh_invalidnum (garglist->word->word); /* POSIX.2 says ``...a diagnostic message shall be written to standard error, and the utility shall not exit with a zero exit status, but shall continue processing any remaining operands and shall write the value accumulated at the time the error was detected to standard output.'' Yecch. */#if 0 ret = 0; /* return partially-converted value from strtoimax */#endif conversion_error = 1; } else if (errno == ERANGE) printf_erange (garglist->word->word); garglist = garglist->next; return (ret);}static uintmax_tgetuintmax (){ uintmax_t ret; char *ep; if (garglist == 0) return (0); if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') return asciicode (); errno = 0; ret = strtoumax (garglist->word->word, &ep, 0); if (*ep) { sh_invalidnum (garglist->word->word); /* Same POSIX.2 conversion error requirements as getintmax(). */ ret = 0; conversion_error = 1; } else if (errno == ERANGE) printf_erange (garglist->word->word); garglist = garglist->next; return (ret);}static floatmax_tgetfloatmax (){ floatmax_t ret; char *ep; if (garglist == 0) return (0); if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') return asciicode (); errno = 0; ret = strtofltmax (garglist->word->word, &ep); if (*ep) { sh_invalidnum (garglist->word->word); /* Same thing about POSIX.2 conversion error requirements. */ ret = 0; conversion_error = 1; } else if (errno == ERANGE) printf_erange (garglist->word->word); garglist = garglist->next; return (ret);}/* NO check is needed for garglist here. */static intmax_tasciicode (){ register intmax_t ch;#if defined (HANDLE_MULTIBYTE) wchar_t wc; size_t mblength, slen;#endif DECLARE_MBSTATE;#if defined (HANDLE_MULTIBYTE) slen = strlen (garglist->word->word+1); mblength = MBLEN (garglist->word->word+1, slen); if (mblength > 1) { mblength = mbtowc (&wc, garglist->word->word+1, slen); ch = wc; /* XXX */ } else#endif ch = (unsigned char)garglist->word->word[1]; garglist = garglist->next; return (ch);}static SHELL_VAR *bind_printf_variable (name, value, flags) char *name; char *value; int flags;{#if defined (ARRAY_VARS) if (valid_array_reference (name) == 0) return (bind_variable (name, value, flags)); else return (assign_array_element (name, value, flags));#else /* !ARRAY_VARS */ return bind_variable (name, value, flags);#endif /* !ARRAY_VARS */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -