int main(int argc, char *argv[]) { Rune *rarg; size_t i, j, argi, lastargi, formatlen, blen; long long num; double dou; int cooldown = 0, width, precision, ret = 0; char *format, *tmp, *arg, *fmt, flag; argv0 = argv[0]; if (argc < 2) usage(); format = argv[1]; if ((tmp = strstr(format, "\\c"))) { *tmp = 0; cooldown = 1; } formatlen = unescape(format); if (formatlen == 0) return 0; lastargi = 0; for (i = 0, argi = 2; !cooldown || i < formatlen; i++, i = cooldown ? i : (i % formatlen)) { if (i == 0) { if (lastargi == argi) break; lastargi = argi; } if (format[i] != '%') { putchar(format[i]); continue; } /* flag */ for (flag = '\0', i++; strchr("#-+ 0", format[i]); i++) { flag = format[i]; } /* field width */ width = -1; if (format[i] == '*') { if (argi < argc) width = estrtonum(argv[argi++], 0, INT_MAX); else cooldown = 1; i++; } else { j = i; for (; strchr("+-0123456789", format[i]); i++); if (j != i) { tmp = estrndup(format + j, i - j); width = estrtonum(tmp, 0, INT_MAX); free(tmp); } else { width = 0; } } /* field precision */ precision = -1; if (format[i] == '.') { if (format[++i] == '*') { if (argi < argc) precision = estrtonum(argv[argi++], 0, INT_MAX); else cooldown = 1; i++; } else { j = i; for (; strchr("+-0123456789", format[i]); i++); if (j != i) { tmp = estrndup(format + j, i - j); precision = estrtonum(tmp, 0, INT_MAX); free(tmp); } else { precision = 0; } } } if (format[i] != '%') { if (argi < argc) arg = argv[argi++]; else { arg = ""; cooldown = 1; } } else { putchar('%'); continue; } switch (format[i]) { case 'b': if ((tmp = strstr(arg, "\\c"))) { *tmp = 0; blen = unescape(arg); fwrite(arg, sizeof(*arg), blen, stdout); return 0; } blen = unescape(arg); fwrite(arg, sizeof(*arg), blen, stdout); break; case 'c': unescape(arg); rarg = ereallocarray(NULL, utflen(arg) + 1, sizeof(*rarg)); utftorunestr(arg, rarg); efputrune(rarg, stdout, "<stdout>"); free(rarg); break; case 's': printf("%*.*s", width, precision, arg); break; case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': for (j = 0; isspace(arg[j]); j++); if (arg[j] == '\'' || arg[j] == '\"') { arg += j + 1; unescape(arg); rarg = ereallocarray(NULL, utflen(arg) + 1, sizeof(*rarg)); utftorunestr(arg, rarg); num = rarg[0]; } else if (arg[0]) { errno = 0; if (format[i] == 'd' || format[i] == 'i') num = strtol(arg, &tmp, 0); else num = strtoul(arg, &tmp, 0); if (tmp == arg || *tmp != '\0') { ret = 1; weprintf("%%%c %s: conversion error\n", format[i], arg); } if (errno == ERANGE) { ret = 1; weprintf("%%%c %s: out of range\n", format[i], arg); } } else { num = 0; } fmt = estrdup(flag ? "%#*.*ll#" : "%*.*ll#"); if (flag) fmt[1] = flag; fmt[flag ? 7 : 6] = format[i]; printf(fmt, width, precision, num); free(fmt); break; case 'a': case 'A': case 'e': case 'E': case 'f': case 'F': case 'g': case 'G': fmt = estrdup(flag ? "%#*.*#" : "%*.*#"); if (flag) fmt[1] = flag; fmt[flag ? 5 : 4] = format[i]; dou = (strlen(arg) > 0) ? estrtod(arg) : 0; printf(fmt, width, precision, dou); free(fmt); break; default: eprintf("Invalid format specifier '%c'.\n", format[i]); } if (argi >= argc) cooldown = 1; } return fshut(stdout, "<stdout>") | ret; }
static char* tkentryinsert(Tk *tk, char *arg, char **val) { TkTop *top; TkEntry *tke; int ins, i, n, locked; char *e, *t, *text, *buf; Rune *etext; USED(val); tke = TKobj(TkEntry, tk); top = tk->env->top; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; arg = tkword(top, arg, buf, buf+Tkmaxitem, nil); e = tkentryparseindex(tk, buf, &ins); free(buf); if(e != nil) return e; if(*arg == '\0') return nil; n = strlen(arg) + 1; if(n < Tkmaxitem) n = Tkmaxitem; text = malloc(n); if(text == nil) return TkNomem; tkword(top, arg, text, text+n, nil); n = utflen(text); etext = realloc(tke->text, (tke->textlen+n+1)*sizeof(Rune)); if(etext == nil) { free(text); return TkNomem; } tke->text = etext; memmove(tke->text+ins+n, tke->text+ins, (tke->textlen-ins)*sizeof(Rune)); t = text; for(i=0; i<n; i++) t += chartorune(tke->text+ins+i, t); free(text); tke->textlen += n; tke->sel0 = adjustforins(ins, n, tke->sel0); tke->sel1 = adjustforins(ins, n, tke->sel1); tke->icursor = adjustforins(ins, n, tke->icursor); tke->anchor = adjustforins(ins, n, tke->anchor); locked = lockdisplay(tk->env->top->display); if (ins < tke->v0) tke->x0 += entrytextwidth(tk, tke->v0 + n) + (tke->x0 - tke->xv0); if (locked) unlockdisplay(tk->env->top->display); recalcentry(tk); e = tkentrysh(tk); blinkreset(tk); tk->dirty = tkrect(tk, 1); return e; }