local void checkhelp(param *pvec, string arg1) { param *pp; char buf[BUFLEN]; if (streq(arg1, "-clue") || streq(arg1, "--clue")) { // print brief help message printf("%s", pvec->value); for (pp = pvec+1; pp->name != NULL; pp++) printf(" %s=%s", pp->name, pp->value); printf("\n"); exit(0); } if (streq(arg1, "-help") || streq(arg1, "--help")) { // print full help message printparam(pvec->value, pvec->comment, FALSE); for (pp = pvec+1; pp->name != NULL; pp++) { sprintf(buf, " %s=%s", pp->name, pp->value); printparam(buf, pp->comment, FALSE); } exit(0); } if (streq(arg1, "-explain") || streq(arg1, "--explain")) { // print long help message printf("\n"); printparam(pvec->value, pvec->comment, TRUE); for (pp = pvec+1; pp->name != NULL; pp++) { sprintf(buf, " %s=%s", pp->name, pp->value); printparam(buf, pp->comment, TRUE); } exit(0); } }
static char * strval(const char *val) { char *info, *ip, c; const char *ps, *pe; int p, nop; size_t len, l; len = 1024; /* no single string should be bigger */ info = ip = malloc(len); if (info == NULL) return 0; /* Move the = */ *ip++ = *val++; /* Set ps and pe to point to the start and end of the padding */ if (isdigit((unsigned char)*val)) { for (ps = pe = val; isdigit((unsigned char)*val) || *val == '.'; val++) pe++; if (*val == '*') { val++; pe++; } } else ps = pe = NULL; l = nop = 0; p = 1; for (; *val != '\0'; val++) { if (l + 2 > len) goto elen; if (*val != '%') { if (*val == ',') { if (l + 3 > len) goto elen; *ip++ = '\\'; l++; } *ip++ = *val; l++; continue; } switch (c = *++(val)) { case 'B': if (l + sizeof(fmtB) > len) goto elen; memcpy(ip, fmtB, sizeof(fmtB) - 1); /* Replace the embedded parameters with real ones */ ip[2] += p; ip[19] += p; ip += sizeof(fmtB) - 1; l += sizeof(fmtB) - 1; nop = 1; continue; case 'D': if (l + sizeof(fmtD) > len) goto elen; memcpy(ip, fmtD, sizeof(fmtD) - 1); /* Replace the embedded parameters with real ones */ ip[2] += p; ip[5] += p; ip += sizeof(fmtD) - 1; l += sizeof(fmtD) - 1; nop = 1; continue; case 'r': /* non op as switched below */ break; case '2': /* FALLTHROUGH */ case '3': /* FALLTHROUGH */ case 'd': if (l + 7 > len) goto elen; l += printparam(&ip, p, &nop); *ip++ = '%'; if (c != 'd') { *ip++ = c; l++; } *ip++ = 'd'; l += 2; break; case '+': if (l + 13 > len) goto elen; l += printparam(&ip, p, &nop); l += printchar(&ip, &val); *ip++ = '%'; *ip++ = c; *ip++ = '%'; *ip++ = 'c'; l += 7; break; case '>': if (l + sizeof(fmtIf) + sizeof(fmtThen) + sizeof(fmtElse) + (6 * 2) > len) goto elen; memcpy(ip, fmtIf, sizeof(fmtIf) - 1); /* Replace the embedded parameters with real ones */ ip[2] += p; ip[5] += p; ip += sizeof(fmtIf) - 1; l += sizeof(fmtIf) - 1; l += printchar(&ip, &val); memcpy(ip, fmtThen, sizeof(fmtThen) - 1); ip += sizeof(fmtThen) - 1; l += sizeof(fmtThen) - 1; l += printchar(&ip, &val); memcpy(ip, fmtElse, sizeof(fmtElse) - 1); ip += sizeof(fmtElse) - 1; l += sizeof(fmtElse) - 1; l += 16; nop = 1; continue; case '.': if (l + 6 > len) goto elen; l += printparam(&ip, p, &nop); *ip++ = '%'; *ip++ = 'c'; l += 2; break; default: /* Hope it matches a terminfo command. */ *ip++ = '%'; *ip++ = c; l += 2; if (c == 'i') continue; break; } /* Swap p1 and p2 */ p = 3 - p; } /* \E\ is valid termcap. * We need to escape the final \ for terminfo. */ if (l > 2 && info[l - 1] == '\\' && (info[l - 2] != '\\' && info[l - 2] != '^')) { if (l + 1 > len) goto elen; *ip++ = '\\'; } /* Add our padding at the end. */ if (ps != NULL) { size_t n = pe - ps; if (l + n + 4 > len) goto elen; *ip++ = '$'; *ip++ = '<'; strncpy(ip, ps, n); ip += n; *ip++ = '/'; *ip++ = '>'; } *ip = '\0'; return info; elen: free(info); errno = ENOMEM; return NULL; }