void csremove(charset *cset1, const charset *cset2, errmsg_t errmsg) { charset *csu; csu = csdiff(cset1,cset2,errmsg); if (*errmsg) return; csswap(csu,cset1); freecharset(csu); }
void csadd(charset *cset1, const charset *cset2, errmsg_t errmsg) { charset *csu; csu = csunion(cset1,cset2,errmsg); if (*errmsg) return; csswap(csu,cset1); freecharset(csu); }
charset *parsecharset(const char *str, errmsg_t errmsg) { charset *cset = NULL; buffer *cbuf = NULL; const wchar_t *p, * const singleescapes = L"_sbqQx"; int hex1, hex2; wchar_t ch; wchar_t *wstr; wstr = (wchar_t *) malloc((strlen(str) + 1) * sizeof(wchar_t)); if (!wstr) { wcscpy(errmsg,outofmem); goto pcserror; } if ((size_t)(-1) == mbstowcs(wstr, str, strlen(str) + 1)) { wcscpy(errmsg,mbserror); goto pcserror; } cset = malloc(sizeof (charset)); if (!cset) { wcscpy(errmsg,outofmem); goto pcserror; } cset->inlist = cset->outlist = NULL; cset->flags = 0; cbuf = newbuffer(sizeof (wchar_t), errmsg); if (*errmsg) goto pcserror; for (p = wstr; *p; ++p) if (*p == L'_') { ++p; if (appearsin(*p, singleescapes)) { if (*p == L'_') ch = L'_' ; else if (*p == L's') ch = L' ' ; else if (*p == L'b') ch = L'\\'; else if (*p == L'q') ch = L'\''; else if (*p == L'Q') ch = L'\"'; else /* *p == 'x' */ { /* FIXME _x metacharacter should allow wide characters input.*/ hex1 = hexdigtoint(p[1]); hex2 = hexdigtoint(p[2]); if (hex1 < 0 || hex2 < 0) goto pcsbadstr; ch = 16 * hex1 + hex2; p += 2; } if (!ch) cset->flags |= CS_NUL; else { additem(cbuf, &ch, errmsg); if (*errmsg) goto pcserror; } } else { if (*p == L'A') cset->flags |= CS_UCASE; else if (*p == L'a') cset->flags |= CS_LCASE; else if (*p == L'0') cset->flags |= CS_DIGIT; else goto pcsbadstr; } } else { additem(cbuf, p,errmsg); if (*errmsg) goto pcserror; } ch = '\0'; additem(cbuf, &ch, errmsg); if (*errmsg) goto pcserror; cset->inlist = copyitems(cbuf,errmsg); if (*errmsg) goto pcserror; pcscleanup: if (cbuf) freebuffer(cbuf); if (wstr) free(wstr); return cset; pcsbadstr: swprintf(errmsg, errmsg_size, L"Bad charset syntax: %.*s\n", errmsg_size - 22, str); pcserror: if (cset) freecharset(cset); cset = NULL; goto pcscleanup; }
static charset *csud( int u, const charset *cset1, const charset *cset2, errmsg_t errmsg ) /* Returns the union of cset1 and cset2 if u is 1, or the set */ /* difference cset1 - cset2 if u is 0. Returns NULL on failure. */ { charset *csu; buffer *inbuf = NULL, *outbuf = NULL; wchar_t *lists[4], **list, *p, nullchar = L'\0'; csu = malloc(sizeof (charset)); if (!csu) { wcscpy(errmsg,outofmem); goto csuderror; } inbuf = newbuffer(sizeof (wchar_t), errmsg); if (*errmsg) goto csuderror; outbuf = newbuffer(sizeof (wchar_t), errmsg); if (*errmsg) goto csuderror; csu->inlist = csu->outlist = NULL; csu->flags = u ? cset1->flags | cset2->flags : cset1->flags & ~cset2->flags; lists[0] = cset1->inlist; lists[1] = cset1->outlist; lists[2] = cset2->inlist; lists[3] = cset2->outlist; for (list = lists; list < lists + 4; ++list) if (*list) { for (p = *list; *p; ++p) if (u ? csmember(*p, cset1) || csmember(*p, cset2) : csmember(*p, cset1) && !csmember(*p, cset2)) { if (!csmember(*p, csu)) { additem(inbuf,p,errmsg); if (*errmsg) goto csuderror; } } else if (csmember(*p, csu)) { additem(outbuf,p,errmsg); if (*errmsg) goto csuderror; } } additem(inbuf, &nullchar, errmsg); if (*errmsg) goto csuderror; additem(outbuf, &nullchar, errmsg); if (*errmsg) goto csuderror; csu->inlist = copyitems(inbuf,errmsg); if (*errmsg) goto csuderror; csu->outlist = copyitems(outbuf,errmsg); if (*errmsg) goto csuderror; csudcleanup: if (inbuf) freebuffer(inbuf); if (outbuf) freebuffer(outbuf); return csu; csuderror: if (csu) freecharset(csu); csu = NULL; goto csudcleanup; }
int main(int argc, const char * const *argv) { int help = 0, version = 0, hang = 0, prefix = -1, repeat = 0, suffix = -1, Tab = 1, width = 72, body = 0, cap = 0, div = 0, Err = 0, expel = 0, fit = 0, guess = 0, invis = 0, just = 0, last = 0, quote = 0, Report = 0, touch = -1; int prefixbak, suffixbak, c, sawnonblank, oweblank, n, i, afp, fs; charset *bodychars = NULL, *protectchars = NULL, *quotechars = NULL; char *parinit = NULL, *arg, **inlines = NULL, **endline, **firstline, *end, **nextline, **outlines = NULL, **line; const char *env, * const whitechars = " \f\n\r\t\v"; errmsg_t errmsg = { '\0' }; lineprop *props = NULL, *firstprop, *nextprop; FILE *errout; /* Process environment variables: */ env = getenv("PARBODY"); if (!env) env = ""; bodychars = parsecharset(env,errmsg); if (*errmsg) { help = 1; goto parcleanup; } env = getenv("PARPROTECT"); if (!env) env = ""; protectchars = parsecharset(env,errmsg); if (*errmsg) { help = 1; goto parcleanup; } env = getenv("PARQUOTE"); if (!env) env = "> "; quotechars = parsecharset(env,errmsg); if (*errmsg) { help = 1; goto parcleanup; } env = getenv("PARINIT"); if (env) { parinit = malloc((strlen(env) + 1) * sizeof (char)); if (!parinit) { strcpy(errmsg,outofmem); goto parcleanup; } strcpy(parinit,env); arg = strtok(parinit,whitechars); while (arg) { parsearg(arg, &help, &version, bodychars, protectchars, quotechars, &hang, &prefix, &repeat, &suffix, &Tab, &width, &body, &cap, &div, &Err, &expel, &fit, &guess, &invis, &just, &last, "e, &Report, &touch, errmsg ); if (*errmsg || help || version) goto parcleanup; arg = strtok(NULL,whitechars); } free(parinit); parinit = NULL; } /* Process command line arguments: */ while (*++argv) { parsearg(*argv, &help, &version, bodychars, protectchars, quotechars, &hang, &prefix, &repeat, &suffix, &Tab, &width, &body, &cap, &div, &Err, &expel, &fit, &guess, &invis, &just, &last, "e, &Report, &touch, errmsg ); if (*errmsg || help || version) goto parcleanup; } if (Tab == 0) { strcpy(errmsg, "<Tab> must not be 0.\n"); goto parcleanup; } if (touch < 0) touch = fit || last; prefixbak = prefix; suffixbak = suffix; /* Main loop: */ for (sawnonblank = oweblank = 0; ; ) { for (;;) { c = getchar(); if (expel && c == '\n') { oweblank = sawnonblank; continue; } if (csmember((char) c, protectchars)) { sawnonblank = 1; if (oweblank) { putchar('\n'); oweblank = 0; } while (c != '\n' && c != EOF) { putchar(c); c = getchar(); } } if (c != '\n') break; putchar(c); } if (c == EOF) break; ungetc(c,stdin); inlines = readlines(&props, protectchars, quotechars, Tab, invis, quote, errmsg); if (*errmsg) goto parcleanup; for (endline = inlines; *endline; ++endline); if (endline == inlines) { free(inlines); inlines = NULL; continue; } sawnonblank = 1; if (oweblank) { putchar('\n'); oweblank = 0; } delimit((const char * const *) inlines, (const char * const *) endline, bodychars, repeat, body, div, 0, 0, props); if (expel) marksuperf((const char * const *) inlines, (const char * const *) endline, props); firstline = inlines, firstprop = props; do { if (isbodiless(firstprop)) { if (!isinvis(firstprop) && !(expel && issuperf(firstprop))) { for (end = *firstline; *end; ++end); if (!repeat || firstprop->rc == ' ' && !firstprop->s) { while (end > *firstline && end[-1] == ' ') --end; *end = '\0'; puts(*firstline); } else { n = width - firstprop->p - firstprop->s; if (n < 0) { sprintf(errmsg,impossibility,5); goto parcleanup; } printf("%.*s", firstprop->p, *firstline); for (i = n; i; --i) putchar(firstprop->rc); puts(end - firstprop->s); } } ++firstline, ++firstprop; continue; } for (nextline = firstline + 1, nextprop = firstprop + 1; nextline < endline && !isbodiless(nextprop) && !isfirst(nextprop); ++nextline, ++nextprop); prefix = prefixbak, suffix = suffixbak; setaffixes((const char * const *) firstline, (const char * const *) nextline, firstprop, bodychars, quotechars, hang, body, quote, &afp, &fs, &prefix, &suffix); if (width <= prefix + suffix) { sprintf(errmsg, "<width> (%d) <= <prefix> (%d) + <suffix> (%d)\n", width, prefix, suffix); goto parcleanup; } outlines = reformat((const char * const *) firstline, (const char * const *) nextline, afp, fs, hang, prefix, suffix, width, cap, fit, guess, just, last, Report, touch, errmsg); if (*errmsg) goto parcleanup; for (line = outlines; *line; ++line) puts(*line); freelines(outlines); outlines = NULL; firstline = nextline, firstprop = nextprop; } while (firstline < endline); freelines(inlines); inlines = NULL; free(props); props = NULL; } parcleanup: if (bodychars) freecharset(bodychars); if (protectchars) freecharset(protectchars); if (quotechars) freecharset(quotechars); if (parinit) free(parinit); if (inlines) freelines(inlines); if (props) free(props); if (outlines) freelines(outlines); errout = Err ? stderr : stdout; if (*errmsg) fprintf(errout, "par error:\n%.*s", errmsg_size, errmsg); if (version) fputs("par 1.50\n",errout); if (help) fputs(usagemsg,errout); return *errmsg ? EXIT_FAILURE : EXIT_SUCCESS; }
static void parsearg( const char *arg, int *phelp, int *pversion, charset *bodychars, charset *protectchars, charset *quotechars, int *phang, int *pprefix, int *prepeat, int *psuffix, int *pTab, int *pwidth, int *pbody, int *pcap, int *pdiv, int *pErr, int *pexpel, int *pfit, int *pguess, int *pinvis, int *pjust, int *plast, int *pquote, int *pReport, int *ptouch, errmsg_t errmsg ) /* Parses the command line argument in *arg, setting the objects pointed to */ /* by the other pointers as appropriate. *phelp and *pversion are boolean */ /* flags indicating whether the help and version options were supplied. */ { const char *savearg = arg; charset *chars, *change; char oc; int n; *errmsg = '\0'; if (*arg == '-') ++arg; if (!strcmp(arg, "help")) { *phelp = 1; return; } if (!strcmp(arg, "version")) { *pversion = 1; return; } if (*arg == 'B' || *arg == 'P' || *arg == 'Q' ) { chars = *arg == 'B' ? bodychars : *arg == 'P' ? protectchars : /* *arg == 'Q' */ quotechars ; ++arg; if (*arg != '=' && *arg != '+' && *arg != '-') goto badarg; change = parsecharset(arg + 1, errmsg); if (change) { if (*arg == '=') csswap(chars,change); else if (*arg == '+') csadd(chars,change,errmsg); else /* *arg == '-' */ csremove(chars,change,errmsg); freecharset(change); } return; } if (isdigit(*arg)) { if (!strtoudec(arg, &n)) goto badarg; if (n <= 8) *pprefix = n; else *pwidth = n; } for (;;) { while (isdigit(*arg)) ++arg; oc = *arg; if (!oc) break; n = -1; if (!strtoudec(++arg, &n)) goto badarg; if ( oc == 'h' || oc == 'p' || oc == 'r' || oc == 's' || oc == 'T' || oc == 'w') { if (oc == 'h') *phang = n >= 0 ? n : 1; else if (oc == 'p') *pprefix = n; else if (oc == 'r') *prepeat = n >= 0 ? n : 3; else if (oc == 's') *psuffix = n; else if (oc == 'T') *pTab = n >= 0 ? n : 8; else /* oc == 'w' */ *pwidth = n >= 0 ? n : 79; } else { if (n < 0) n = 1; if (n > 1) goto badarg; if (oc == 'b') *pbody = n; else if (oc == 'c') *pcap = n; else if (oc == 'd') *pdiv = n; else if (oc == 'E') *pErr = n; else if (oc == 'e') *pexpel = n; else if (oc == 'f') *pfit = n; else if (oc == 'g') *pguess = n; else if (oc == 'i') *pinvis = n; else if (oc == 'j') *pjust = n; else if (oc == 'l') *plast = n; else if (oc == 'q') *pquote = n; else if (oc == 'R') *pReport = n; else if (oc == 't') *ptouch = n; else goto badarg; } } return; badarg: sprintf(errmsg, "Bad argument: %.*s\n", errmsg_size - 16, savearg); *phelp = 1; }