Exemplo n.º 1
0
static void compresuflen(
  const char * const *lines, const char * const *endline,
  const charset *bodychars, int body, int pre, int suf, int *ppre, int *psuf
)
/* lines is an array of strings, up to but not including endline.  */
/* Writes into *ppre and *psuf the comprelen and comsuflen of the  */
/* lines in lines.  Assumes that they have already been determined */
/* to be at least pre and suf.  endline must not equal lines.      */
{
  const char *start, *end, *knownstart, * const *line, *p1, *p2, *knownend,
             *knownstart2;

  start = *lines;
  end = knownstart = start + pre;
  if (body)
    while (*end) ++end;
  else
    while (*end && !csmember(*end, bodychars)) ++end;
  for (line = lines + 1;  line < endline;  ++line) {
    for (p1 = knownstart, p2 = *line + pre;
         p1 < end && *p1 == *p2;
         ++p1, ++p2);
    end = p1;
  }
  if (body)
    for (p1 = end;  p1 > knownstart;  )
      if (*--p1 != ' ')
        if (csmember(*p1, bodychars))
          end = p1;
        else
          break;
  *ppre = end - start;

  knownstart = *lines + *ppre;
  for (end = knownstart;  *end;  ++end);
  knownend = end - suf;
  if (body)
    start = knownstart;
  else
    for (start = knownend;
         start > knownstart && !csmember(start[-1], bodychars);
         --start);
  for (line = lines + 1;  line < endline;  ++line) {
    knownstart2 = *line + *ppre;
    for (p2 = knownstart2;  *p2;  ++p2);
    for (p1 = knownend, p2 -= suf;
         p1 > start && p2 > knownstart2 && p1[-1] == p2[-1];
         --p1, --p2);
    start = p1;
  }
  if (body) {
    for (p1 = start;
         start < knownend && (*start == ' ' || csmember(*start, bodychars));
         ++start);
    if (start > p1 && start[-1] == ' ') --start;
  }
  else
    while (end - start >= 2 && *start == ' ' && start[1] == ' ') ++start;
  *psuf = end - start;
}
Exemplo n.º 2
0
static void setaffixes(
  const char * const *inlines, const char * const *endline,
  const lineprop *props, const charset *bodychars,
  const charset *quotechars, int hang, int body, int quote,
  int *pafp, int *pfs, int *pprefix, int *psuffix
)
/* inlines is an array of strings, up to but not including endline,    */
/* representing an IP.  inlines and endline must not be equal.  props  */
/* is the the parallel array of lineprop structures.  *pafp and *pfs   */
/* are set to the augmented fallback prelen and fallback suflen of the */
/* IP.  If either of *pprefix, *psuffix is less than 0, it is set to a */
/* default value as specified in "par.doc".                            */
{
  int numin, pre, suf;
  const char *p;

  numin = endline - inlines;

  if ((*pprefix < 0 || *psuffix < 0)  &&  numin > hang + 1)
    compresuflen(inlines + hang, endline, bodychars, body, 0, 0, &pre, &suf);

  p = *inlines + props->p;
  if (numin == 1 && quote)
    while (*p && csmember (*p, quotechars))
      ++p;
  *pafp = p - *inlines;
  *pfs = props->s;

  if (*pprefix < 0)
    *pprefix  =  numin > hang + 1  ?  pre  :  *pafp;

  if (*psuffix < 0)
    *psuffix  =  numin > hang + 1  ?  suf  :  *pfs;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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;
}