int pzheadprint(register Pz_t* pz, register Sfio_t* op, int parts) { register Pzpart_t* pp; char t; if (pz->flags & PZ_FORCE) sfprintf(op, "# fixed record input\n"); else { sfprintf(op, "# pzip %d.%d partition\n", pz->major, pz->minor); if (pz->disc->comment) sfprintf(op, "# %s\n", pz->disc->comment); sfprintf(op, "# window %I*u\n", sizeof(pz->win), pz->win); if (pz->prefix.count) { sfprintf(op, "\nprefix=%I*u", sizeof(pz->prefix.count), pz->prefix.count); if (pz->prefix.terminator >= 0) { t = pz->prefix.terminator; sfprintf(op, "*%s\n", fmtquote(&t, "'", "'", 1, FMT_ALWAYS)); } else sfputc(op, '\n'); } if (pz->headoptions || pz->det) { sfputc(op, '\n'); if (pz->headoptions) sfputr(op, pz->headoptions, '\n'); if (pz->det) { sfwrite(op, sfstrbase(pz->det), sfstrtell(pz->det)); sfputc(op, '\n'); } } } if (parts) { pp = pz->partdict ? (Pzpart_t*)dtfirst(pz->partdict) : pz->part; while (pp) { if (pzpartprint(pz, pp, op)) return -1; if (!pz->partdict) break; pp = (Pzpart_t*)dtnext(pz->partdict, pp); } } return sferror(op) ? -1 : 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; }
static int getfmt(Sfio_t* sp, void* vp, Sffmt_t* dp) { register Fmt_t* fp = (Fmt_t*)dp; register Arg_t* ap = fp->ap++; Value_t* value = (Value_t*)vp; Cxoperand_t ret; if (ap->expr && cxeval(fp->cx, ap->expr, fp->data, &ret) < 0 || cxcast(fp->cx, &ret, ap->variable, ap->cast, fp->data, ap->details)) { fp->errors++; return -1; } fp->fmt.flags |= SFFMT_VALUE; switch (ap->type) { case DSS_FORMAT_char: fp->fmt.size = sizeof(int); if (ret.value.number < 1) value->c = 0; else if (ret.value.number > UCHAR_MAX) value->c = UCHAR_MAX; else value->c = (unsigned char)ret.value.number; break; case DSS_FORMAT_float: fp->fmt.size = sizeof(double); value->f = ret.value.number; break; case DSS_FORMAT_int: #if 0 /* * this code is technically correct but overly * complicates script portability between architectures * with differing sizeof(int) and/or sizeof(long) */ fp->fmt.size = sizeof(int); if (((ret.value.number >= 0) ? ret.value.number : -ret.value.number) < 1) value->i = 0; else if (ret.value.number > UINT_MAX) value->i = INT_MAX; else if (ret.value.number < INT_MIN) value->i = INT_MAX; else value->i = (unsigned int)ret.value.number; break; #endif case DSS_FORMAT_long: fp->fmt.size = sizeof(Sflong_t); if (((ret.value.number >= 0) ? ret.value.number : -ret.value.number) < 1) value->q = 0; else if (ret.value.number > FLTMAX_UINTMAX_MAX) value->q = FLTMAX_INTMAX_MAX; else if (ret.value.number < FLTMAX_INTMAX_MIN) value->q = FLTMAX_INTMAX_MAX; else value->q = (Sfulong_t)((Sflong_t)ret.value.number); break; case DSS_FORMAT_string: if (ap->fmt & (FMT_EXP_CHAR|FMT_EXP_LINE|FMT_EXP_NOCR|FMT_EXP_NONL|FMT_EXP_WIDE)) ret.value.string.size = strexp(ret.value.string.data, ap->fmt); if (ap->edit) cxsub(fp->cx, ap->edit, &ret); if (ap->flags & DSS_FORMAT_quote) ret.value.string.size = strlen(ret.value.string.data = fmtquote(ret.value.string.data, ap->qb, ap->qe, ret.value.string.size, ap->fmt)); value->s = ret.value.string.data; fp->fmt.size = ret.value.string.size; break; } return 0; }
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; }