char* fmtsignal(register int sig) { char* buf; int z; if (sig >= 0) { if (sig <= sig_info.sigmax) buf = sig_info.text[sig]; else { buf = fmtbuf(z = 20); sfsprintf(buf, z, "Signal %d", sig); } } else { sig = -sig; if (sig <= sig_info.sigmax) buf = sig_info.name[sig]; else { buf = fmtbuf(z = 20); sfsprintf(buf, z, "%d", sig); } } return buf; }
char* fmtelapsed(register unsigned long u, register int n) { register unsigned long t; char* buf; int z; if (u == 0L) return "0"; if (u == ~0L) return "%"; buf = fmtbuf(z = 8); t = u / n; if (t < 60) sfsprintf(buf, z, "%lu.%02lus", t, (u * 100 / n) % 100); else if (t < 60*60) sfsprintf(buf, z, "%lum%02lus", t / 60, t - (t / 60) * 60); else if (t < 24*60*60) sfsprintf(buf, z, "%luh%02lum", t / (60*60), (t - (t / (60*60)) * (60*60)) / 60); else if (t < 7*24*60*60) sfsprintf(buf, z, "%lud%02luh", t / (24*60*60), (t - (t / (24*60*60)) * (24*60*60)) / (60*60)); else if (t < 31*24*60*60) sfsprintf(buf, z, "%luw%02lud", t / (7*24*60*60), (t - (t / (7*24*60*60)) * (7*24*60*60)) / (24*60*60)); else if (t < 365*24*60*60) sfsprintf(buf, z, "%luM%02lud", (t * 12) / (365*24*60*60), ((t * 12) - ((t * 12) / (365*24*60*60)) * (365*24*60*60)) / (12*24*60*60)); else if (t < (365UL*4UL+1UL)*24UL*60UL*60UL) sfsprintf(buf, z, "%luY%02luM", t / (365*24*60*60), ((t - (t / (365*24*60*60)) * (365*24*60*60)) * 5) / (152 * 24 * 60 * 60)); else sfsprintf(buf, z, "%luY%02luM", (t * 4) / ((365UL*4UL+1UL)*24UL*60UL*60UL), (((t * 4) - ((t * 4) / ((365UL*4UL+1UL)*24UL*60UL*60UL)) * ((365UL*4UL+1UL)*24UL*60UL*60UL)) * 5) / ((4 * 152 + 1) * 24 * 60 * 60)); return buf; }
char* fmttime(const char* format, time_t clock) { char* buf; int z; buf = fmtbuf(z = 80); tmfmt(buf, z, format, &clock); return buf; }
char *fmtscale(Sfulong_t n, int k) { Sfulong_t m; int r; int z; const char *u; char suf[3]; char *s; char *buf; static const char scale[] = "bkMGTPE"; u = scale; if (n < 1000) { r = 0; } else { m = 0; while (n >= k && *(u + 1)) { m = n; n /= k; u++; } if ((r = (10 * (m % k) + (k / 2)) / k) > 9) { r = 0; n++; } if (k == 1024 && n >= 1000) { n = 1; r = 0; u++; } } buf = fmtbuf(z = 8); s = suf; if (u > scale) { if (k == 1024) { *s++ = *u == 'k' ? 'K' : *u; *s++ = 'i'; } else { *s++ = *u; } } *s = 0; if (n > 0 && n < 10) { char *decimal = nl_langinfo(RADIXCHAR); sfsprintf(buf, z, "%I*u%s%d%s", sizeof(n), n, decimal, r, suf); } else { if (r >= 5) n++; sfsprintf(buf, z, "%I*u%s", sizeof(n), n, suf); } return buf; }
char* fmtint(intmax_t ll, int unsign) { char *buff; uintmax_t n,m; int j=0,k=3*sizeof(ll); if(unsign || ll>=0) n = ll; else { n = -ll; j = 1; } if(n<10) { buff = fmtbuf(k=3); buff[--k] = 0; buff[--k] = '0' + n; goto skip; } buff = fmtbuf(k); buff[--k] = 0; do { k -= 3; if((m=n) >= 1000) m = n%1000; memcpy(buff+k,table+3*m,3); n /= 1000; } while(n>0); while(buff[k]=='0') k++; skip: if(j) buff[--k] = '-'; return(&buff[k]); }
char* fmttmx(const char* fmt, Time_t t) { char* b; char* e; int z; z = 0; do { b = fmtbuf(z += 80); e = tmxfmt(b, z, fmt, t); } while (e == b + z); return b; }
char* fmtident(const char* a) { register char* s = (char*)a; register char* t; char* buf; int i; i = 0; for (;;) { while (isspace(*s)) s++; if (s[0] == '[') { while (*++s && *s != '\n'); i |= USAGE; } else if (s[0] == '@' && s[1] == '(' && s[2] == '#' && s[3] == ')') s += 4; else if (s[0] == '$' && s[1] == 'I' && s[2] == 'd' && s[3] == ':' && isspace(s[4])) { s += 5; i |= IDENT; } else break; } if (i) { i &= IDENT; for (t = s; isprint(*t) && *t != '\n'; t++) if (i && t[0] == ' ' && t[1] == '$') break; while (t > s && isspace(t[-1])) t--; i = t - s; buf = fmtbuf(i + 1); memcpy(buf, s, i); s = buf; s[i] = 0; } return s; }
char* fmtfs(struct stat* st) { register Id_t* ip; register void* mp; register Mnt_t* mnt; register char* s; struct stat rt; char* buf; static Dt_t* dict; static Dtdisc_t disc; if (!dict) { disc.key = offsetof(Id_t, id); disc.size = sizeof(dev_t); dict = dtopen(&disc, Dthash); } else if (ip = (Id_t*)dtmatch(dict, &st->st_dev)) return ip->name; s = FS_default; if (mp = mntopen(NiL, "r")) { while ((mnt = mntread(mp)) && (stat(mnt->dir, &rt) || rt.st_dev != st->st_dev)); if (mnt && mnt->type) s = mnt->type; } if (!dict || !(ip = newof(0, Id_t, 1, strlen(s)))) { if (!mp) return s; buf = fmtbuf(strlen(s) + 1); strcpy(buf, s); mntclose(mp); return buf; } strcpy(ip->name, s); if (mp) mntclose(mp); dtinsert(dict, ip); return ip->name; }
int b_mktemp(int argc, char** argv, Shbltin_t* context) { mode_t mode = 0; mode_t mask; int fd; int i; int quiet = 0; int unsafe = 0; int* fdp = &fd; char* dir = ""; char* pfx; char* t; char path[PATH_MAX]; cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY); for (;;) { switch (optget(argv, usage)) { case 'd': fdp = 0; continue; case 'm': mode = strperm(pfx = opt_info.arg, &opt_info.arg, S_IRWXU); if (*opt_info.arg) error(ERROR_exit(0), "%s: invalid mode", pfx); continue; case 'p': if ((t = getenv("TMPDIR")) && *t) dir = 0; else dir = opt_info.arg; continue; case 'q': quiet = 1; continue; case 't': dir = 0; continue; case 'u': unsafe = 1; fdp = 0; continue; case 'R': if (!pathtemp(NiL, 0, opt_info.arg, "/seed", NiL)) error(2, "%s: regression test initializtion failed", opt_info.arg); continue; case ':': error(2, "%s", opt_info.arg); break; case '?': error(ERROR_usage(2), "%s", opt_info.arg); break; } break; } argv += opt_info.index; if (error_info.errors || (pfx = *argv++) && *argv) error(ERROR_usage(2), "%s", optusage(NiL)); mask = umask(0); if (!mode) mode = (fdp ? (S_IRUSR|S_IWUSR) : S_IRWXU) & ~mask; umask(~mode & (S_IRWXU|S_IRWXG|S_IRWXO)); if (!pfx) { pfx = "tmp_"; if (dir && !*dir) dir = 0; } if (t = strrchr(pfx, '/')) { i = ++t - pfx; dir = fmtbuf(i); memcpy(dir, pfx, i); dir[i] = 0; pfx = t; } for (;;) { if (!pathtemp(path, sizeof(path), dir, pfx, fdp)) { if (quiet) error_info.errors++; else error(ERROR_SYSTEM|2, "cannot create temporary path"); break; } if (fdp || unsafe || !mkdir(path, mode)) { if (fdp) close(*fdp); sfputr(sfstdout, path, '\n'); break; } if (sh_checksig(context)) { error_info.errors++; break; } } umask(mask); return error_info.errors != 0; }
char* fmtrec(Recfmt_t f, int fs) { char* b; char* e; char* s; long n; char del[2]; b = s = fmtbuf(n = 32); e = b + n; switch (RECTYPE(f)) { case REC_delimited: *s++ = 'd'; if ((del[0] = REC_D_DELIMITER(f)) != '\n') { del[1] = 0; if (fs) sfsprintf(s, e - s, "0x%02x", *(unsigned char*)del); else sfsprintf(s, e - s, "%s", fmtquote(del, NiL, NiL, 1, 0)); } else *s = 0; break; case REC_fixed: if (!fs) *s++ = 'f'; sfsprintf(s, e - s, "%lu", REC_F_SIZE(f)); break; case REC_variable: *s++ = 'v'; if (n = REC_V_SIZE(f)) s += sfsprintf(s, e - s, "%lu", n); if (REC_V_HEADER(f) != 4) s += sfsprintf(s, e - s, "h%u", REC_V_HEADER(f)); if (REC_V_OFFSET(f) != 0) s += sfsprintf(s, e - s, "o%u", REC_V_OFFSET(f)); if (REC_V_LENGTH(f) != 2) s += sfsprintf(s, e - s, "z%u", REC_V_LENGTH(f)); if (REC_V_LITTLE(f) != 0) *s++ = 'l'; if (REC_V_INCLUSIVE(f) == 0) *s++ = 'n'; *s = 0; break; case REC_method: *s++ = 'm'; switch (n = REC_M_INDEX(f)) { case REC_M_data: sfsprintf(s, e - s, "data"); break; case REC_M_path: sfsprintf(s, e - s, "path"); break; default: sfsprintf(s, e - s, "%lu", n); break; } break; case REC_none: *s++ = 'n'; *s = 0; break; default: sfsprintf(s, e - s, "u%u.0x%07x", RECTYPE(f), REC_U_ATTRIBUTES(f)); break; } return b; }
char* fmtre(const char* as) { register char* s = (char*)as; register int c; register char* t; register Stack_t* p; char* x; int n; int end; char* buf; Stack_t stack[32]; end = 1; c = 2 * strlen(s) + 1; t = buf = fmtbuf(c); p = stack; if (*s != '*' || *(s + 1) == '(' || *(s + 1) == '-' && *(s + 2) == '(') *t++ = '^'; else s++; for (;;) { switch (c = *s++) { case 0: break; case '\\': if (!(c = *s++) || c == '{' || c == '}') return 0; *t++ = '\\'; if ((*t++ = c) == '(' && *s == '|') { *t++ = *s++; goto logical; } continue; case '[': *t++ = c; n = 0; if ((c = *s++) == '!') { *t++ = '^'; c = *s++; } else if (c == '^') { if ((c = *s++) == ']') { *(t - 1) = '\\'; *t++ = '^'; continue; } n = '^'; } for (;;) { if (!(*t++ = c)) return 0; if ((c = *s++) == ']') { if (n) *t++ = n; *t++ = c; break; } } continue; case '{': for (x = s; *x && *x != '}'; x++); if (*x++ && (*x == '(' || *x == '-' && *(x + 1) == '(')) { if (p >= &stack[elementsof(stack)]) return 0; p->beg = s - 1; s = x; p->len = s - p->beg; if (p->min = *s == '-') s++; p++; *t++ = *s++; } else *t++ = c; continue; case '*': if (!*s) { end = 0; break; } /*FALLTHROUGH*/ case '?': case '+': case '@': case '!': case '~': if (*s == '(' || c != '~' && *s == '-' && *(s + 1) == '(') { if (p >= &stack[elementsof(stack)]) return 0; p->beg = s - 1; if (c == '~') { if (*(s + 1) == 'E' && *(s + 2) == ')') { for (s += 3; *t = *s; t++, s++); continue; } p->len = 0; p->min = 0; *t++ = *s++; *t++ = '?'; } else { p->len = c != '@'; if (p->min = *s == '-') s++; *t++ = *s++; } p++; } else { switch (c) { case '*': *t++ = '.'; break; case '?': c = '.'; break; case '+': case '!': *t++ = '\\'; break; } *t++ = c; } continue; case '(': if (p >= &stack[elementsof(stack)]) return 0; p->beg = s - 1; p->len = 0; p->min = 0; p++; *t++ = c; continue; case ')': if (p == stack) return 0; *t++ = c; p--; for (c = 0; c < p->len; c++) *t++ = p->beg[c]; if (p->min) *t++ = '?'; continue; case '^': case '.': case '$': *t++ = '\\'; *t++ = c; continue; case '|': if (t == buf || *(t - 1) == '(') return 0; logical: if (!*s || *s == ')') return 0; /*FALLTHROUGH*/ default: *t++ = c; continue; } break; } if (p != stack) return 0; if (end) *t++ = '$'; *t = 0; return buf; }
char* _ast_strerror(int err) { char* msg; int z; #if _lib_strerror z = errno; msg = strerror(err); errno = z; #else if (err > 0 && err <= sys_nerr) msg = (char*)sys_errlist[err]; else msg = 0; #endif if (msg) { #if !_PACKAGE_astsa if (ERROR_translating()) { #if _lib_strerror static int sys; if (!sys) { char* s; char* t; char* p; #if _lib_strerror /* * stash the pending strerror() msg */ msg = strcpy(fmtbuf(strlen(msg) + 1), msg); #endif /* * make sure that strerror() translates */ if (!(s = strerror(1))) sys = -1; else { t = fmtbuf(z = strlen(s) + 1); strcpy(t, s); ast.locale.set |= AST_LC_internal; p = setlocale(LC_MESSAGES, NiL); setlocale(LC_MESSAGES, "C"); sys = (s = strerror(1)) && strcmp(s, t) ? 1 : -1; setlocale(LC_MESSAGES, p); ast.locale.set &= ~AST_LC_internal; } } if (sys > 0) return msg; #endif return ERROR_translate(NiL, NiL, "errlist", msg); } #endif return msg; } msg = fmtbuf(z = 32); sfsprintf(msg, z, ERROR_translate(NiL, NiL, "errlist", "Error %d"), err); return msg; }
char* fmtquote(const char* as, const char* qb, const char* qe, size_t n, int flags) { register unsigned char* s = (unsigned char*)as; register unsigned char* e = s + n; register char* b; register int c; register int m; register int escaped; register int spaced; register int doublequote; register int singlequote; int shell; char* f; char* buf; c = 4 * (n + 1); if (qb) c += strlen((char*)qb); if (qe) c += strlen((char*)qe); b = buf = fmtbuf(c); shell = 0; doublequote = 0; singlequote = 0; if (qb) { if (qb[0] == '$' && qb[1] == '\'' && qb[2] == 0) shell = 1; else if ((flags & FMT_SHELL) && qb[1] == 0) { if (qb[0] == '"') doublequote = 1; else if (qb[0] == '\'') singlequote = 1; } while (*b = *qb++) b++; } else if (flags & FMT_SHELL) doublequote = 1; f = b; escaped = spaced = !!(flags & FMT_ALWAYS); while (s < e) { if ((m = mbsize(s)) > 1 && (s + m) <= e) { #if _hdr_wchar && _hdr_wctype c = mbchar(s); if (!spaced && !escaped && (iswspace(c) || iswcntrl(c))) spaced = 1; s -= m; #endif while (m--) *b++ = *s++; } else { c = *s++; if (!(flags & FMT_ESCAPED) && (iscntrl(c) || !isprint(c) || c == '\\')) { escaped = 1; *b++ = '\\'; switch (c) { case CC_bel: c = 'a'; break; case '\b': c = 'b'; break; case '\f': c = 'f'; break; case '\n': c = 'n'; break; case '\r': c = 'r'; break; case '\t': c = 't'; break; case CC_vt: c = 'v'; break; case CC_esc: c = 'E'; break; case '\\': break; default: if (!(flags & FMT_WIDE) || !(c & 0200)) { *b++ = '0' + ((c >> 6) & 07); *b++ = '0' + ((c >> 3) & 07); c = '0' + (c & 07); } else b--; break; } }
static int prformat(Sfio_t* sp, void* vp, Sffmt_t* dp) { register Fmt_t* fmt = (Fmt_t*)dp; register Exnode_t* node; register char* s; register char* txt; int n; int from; int to; time_t tm; dp->flags |= SFFMT_VALUE; if (fmt->args) { if (node = (dp->fmt == '*') ? fmt->args->param[dp->size] : fmt->args->arg) fmt->value = exeval(fmt->expr, node, fmt->env); else fmt->value.integer = 0; to = fmt->args->arg->type; } else if (!(fmt->actuals = fmt->actuals->data.operand.right)) exerror("printf: not enough arguments"); else { node = fmt->actuals->data.operand.left; from = node->type; switch (dp->fmt) { case 'f': case 'g': to = FLOATING; break; case 's': case '[': to = STRING; break; default: switch (from) { case INTEGER: case UNSIGNED: to = from; break; default: to = INTEGER; break; } break; } if (to == from) fmt->value = exeval(fmt->expr, node, fmt->env); else { node = excast(fmt->expr, node, to, NiL, 0); fmt->value = exeval(fmt->expr, node, fmt->env); node->data.operand.left = 0; exfree(fmt->expr, node); if (to == STRING) { if (fmt->value.string) { n = strlen(fmt->value.string); if (s = fmtbuf(n + 1)) memcpy(s, fmt->value.string, n + 1); vmfree(fmt->expr->vm, fmt->value.string); fmt->value.string = s; } if (!fmt->value.string) fmt->value.string = ""; } } } switch (to) { case STRING: *((char**)vp) = fmt->value.string; fmt->fmt.size = -1; break; case FLOATING: *((double*)vp) = fmt->value.floating; fmt->fmt.size = sizeof(double); break; default: *((Sflong_t*)vp) = fmt->value.integer; dp->size = sizeof(Sflong_t); break; } if (dp->n_str > 0) { if (!fmt->tmp && !(fmt->tmp = sfstropen())) txt = exnospace(); else { sfprintf(fmt->tmp, "%.*s", dp->n_str, dp->t_str); txt = exstash(fmt->tmp, NiL); } } else txt = 0; switch (dp->fmt) { case 'q': case 'Q': s = *((char**)vp); *((char**)vp) = fmtquote(s, "$'", "'", strlen(s), 0); dp->fmt = 's'; dp->size = -1; break; case 'S': dp->flags &= ~SFFMT_LONG; s = *((char**)vp); if (txt) { if (streq(txt, "identifier")) { if (*s && !isalpha(*s)) *s++ = '_'; for (; *s; s++) if (!isalnum(*s)) *s = '_'; } else if (streq(txt, "invert")) { for (; *s; s++) if (isupper(*s)) *s = tolower(*s); else if (islower(*s)) *s = toupper(*s); } else if (streq(txt, "lower")) { for (; *s; s++) if (isupper(*s)) *s = tolower(*s); } else if (streq(txt, "upper")) { for (; *s; s++) if (islower(*s)) *s = toupper(*s); } else if (streq(txt, "variable")) { for (; *s; s++) if (!isalnum(*s) && *s != '_') *s = '.'; } } dp->fmt = 's'; dp->size = -1; break; case 't': case 'T': if ((tm = *((Sflong_t*)vp)) == -1) tm = time(NiL); *((char**)vp) = fmttime(txt ? txt : "%?%K", tm); dp->fmt = 's'; dp->size = -1; break; } return 0; }
char* fmtfmt(const char* as) { register char* s = (char*)as; char* buf; int i; int c; int a; int q; int x; int t; int m; int n; int z; char formats[256]; unsigned int extra[elementsof(formats)]; z = 1; i = m = 0; for (;;) { switch (*s++) { case 0: break; case '%': if (*s == '%') continue; n = 0; a = 0; q = 0; t = '?'; x = 0; for (;;) { switch (c = *s++) { case 0: s--; break; case '(': q++; continue; case ')': if (--q <= 0) n = 0; continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = n * 10 + (c - '0'); continue; case '$': a = n; n = 0; continue; case '*': x++; n = 0; continue; case 'h': if (!q) t = t == 'h' ? 'c' : 'h'; continue; case 'l': if (!q) t = t == 'l' ? 'j' : 'l'; continue; case 'j': case 't': case 'z': if (!q) t = c; continue; case 'c': case 'p': case 's': if (!q) { t = c; break; } continue; case 'e': case 'g': if (!q) { switch (t) { case 'j': t = 'D'; break; default: t = 'd'; break; } break; } continue; case 'f': if (!q) { switch (t) { case 'j': t = 'D'; break; case 'l': t = 'd'; break; default: t = c; break; } break; } continue; default: if (!q && isalpha(c)) { if (t == '?') t = 'i'; break; } n = 0; continue; } break; } if (a) i = a; else i++; if (i < elementsof(formats)) { formats[i] = t; if (extra[i] = x) do z++; while (x /= 10); if (m < i) m = i; } continue; default: continue; } break; } s = buf = fmtbuf(m + z); for (i = 1; i <= m; i++) { if (extra[i]) s += sfsprintf(s, 10, "%d", extra[m]); *s++ = formats[i]; } *s = 0; return buf; }
char* fmtquote(const char* as, const char* qb, const char* qe, size_t n, int flags) { register unsigned char* s = (unsigned char*)as; register unsigned char* e = s + n; register char* b; register int c; int k; int q = 0; char* buf; c = 4 * (n + 1); if (qb) { k = strlen((char*)qb); c += k; } else { k = 0; if (qe) c += strlen((char*)qe); } b = buf = fmtbuf(c); if (qb) { q = qb[0] == '$' && qb[1] == '\'' && qb[2] == 0 ? 1 : 0; while ((*b = *qb++)) b++; k = (flags & 1) ? 0 : (b - buf); } while (s < e) { c = *s++; if (iscntrl(c) || !isprint(c) || c == '\\') { k = 0; *b++ = '\\'; switch (c) { case CC_bel: c = 'a'; break; case '\b': c = 'b'; break; case '\f': c = 'f'; break; case '\n': c = 'n'; break; case '\r': c = 'r'; break; case '\t': c = 't'; break; case CC_vt: c = 'v'; break; case CC_esc: c = 'E'; break; case '\\': break; default: if (!(flags & 2) || !(c & 0200)) { *b++ = '0' + ((c >> 6) & 07); *b++ = '0' + ((c >> 3) & 07); c = '0' + (c & 07); } else b--; break; }