Exemple #1
0
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);
}
Exemple #2
0
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);
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
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, &quote, &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, &quote, &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;
}
Exemple #6
0
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;
}