[BACK]Return to util.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / texi2mdoc

Diff for /texi2mdoc/util.c between version 1.29 and 1.30

version 1.29, 2015/03/07 11:53:21 version 1.30, 2015/03/11 12:51:41
Line 103  texivaluefree(struct texivalue *p)
Line 103  texivaluefree(struct texivalue *p)
         free(p->value);          free(p->value);
 }  }
   
   static void
   texidex_free(struct texidex *p)
   {
           size_t   i;
   
           for (i = 0; i < p->indexsz; i++)
                   free(p->index[i]);
   
           free(p->index);
           free(p->name);
           p->index = NULL;
           p->indexsz = 0;
   }
   
 /*  /*
    * Add the text beginning at "index" and of "sz" bytes to the index
    * named "tok" with name size "toksz".
    * This will also output the necessary mdoc(7) to construct the index.
    */
   void
   texindex(struct texi *p, const char *tok,
           size_t toksz, const char *index, size_t sz)
   {
           size_t   i;
   #ifdef HAVE_INDEX
           char    *cp;
   #endif
   
           if (0 == sz) {
                   texiwarn(p, "zero-length index entry");
                   return;
           }
   
           /* Look for the index.  (Must be found.) */
           for (i = 0; i < p->indexsz; i++) {
                   if (strlen(p->indexs[i].name) != toksz)
                           continue;
                   if (strncmp(p->indexs[i].name, tok, toksz))
                           continue;
                   break;
           }
   
           assert(i < p->indexsz);
           /* Reallocate index's terms. */
           p->indexs[i].index = realloc
                   (p->indexs[i].index,
                    (p->indexs[i].indexsz + 1) *
                    sizeof(char *));
           if (NULL == p->indexs[i].index)
                   texiabort(p, NULL);
   
           /* Add term to term array. */
           p->indexs[i].index[p->indexs[i].indexsz] =
                   malloc(sz + 1);
           if (NULL == p->indexs[i].index[p->indexs[i].indexsz])
                   texiabort(p, NULL);
           memcpy(p->indexs[i].index[p->indexs[i].indexsz],
                   index, sz);
           p->indexs[i].index[p->indexs[i].indexsz][sz] = '\0';
   
           /* Output mdoc(7) for index. */
   #ifdef HAVE_INDEX
           p->seenvs = -1;
           teximacroopen(p, "Ix");
           texiputchars(p, "idx");
           texiputchars(p, p->indexs[i].name);
           cp = p->indexs[i].index[p->indexs[i].indexsz];
           while ('\n' != *cp) {
                   assert('\0' != *cp);
                   texiputchar(p, *cp++);
           }
           teximacroclose(p);
   #endif
           p->indexs[i].indexsz++;
   }
   
   /*
    * Add an index entry named "tok" of length "sz".
    * This usually consists of two letters, e.g., "cp" or "vr".
    * This does nothing if the index exists or is zero-sized.
    */
   void
   texindex_add(struct texi *p, const char *tok, size_t sz)
   {
           size_t   i;
           char    *cp;
   
           if (0 == sz)
                   return;
   
           /* Make sure we don't have a duplicate. */
           for (i = 0; i < p->indexsz; i++) {
                   if (strlen(p->indexs[i].name) != sz)
                           continue;
                   if (strncmp(p->indexs[i].name, tok, sz))
                           continue;
                   return;
           }
   
           /* Reallocate indices. */
           p->indexs = realloc(p->indexs,
                   sizeof(struct texidex) * (p->indexsz + 1));
           if (NULL == p->indexs)
                   texiabort(p, NULL);
           if (NULL == (cp = malloc(sz + 1)))
                   texiabort(p, NULL);
           memcpy(cp, tok, sz);
           cp[sz] = '\0';
           p->indexs[p->indexsz].name = cp;
           p->indexs[p->indexsz].index = NULL;
           p->indexs[p->indexsz].indexsz = 0;
           p->indexsz++;
   }
   
   /*
  * Unmap all files that we're currently using and free all resources   * Unmap all files that we're currently using and free all resources
  * that we've allocated during the parse.   * that we've allocated during the parse.
  * The utility should exit(...) after this is called.   * The utility should exit(...) after this is called.
Line 128  texiexit(struct texi *p)
Line 242  texiexit(struct texi *p)
         for (i = 0; i < p->dirsz; i++)          for (i = 0; i < p->dirsz; i++)
                 free(p->dirs[i]);                  free(p->dirs[i]);
         for (i = 0; i < p->indexsz; i++)          for (i = 0; i < p->indexsz; i++)
                 free(p->indexs[i]);                  texidex_free(&p->indexs[i]);
         for (i = 0; i < p->valsz; i++)          for (i = 0; i < p->valsz; i++)
                 texivaluefree(&p->vals[i]);                  texivaluefree(&p->vals[i]);
   
Line 280  void
Line 394  void
 teximacroclose(struct texi *p)  teximacroclose(struct texi *p)
 {  {
   
         if (p->ign)          if (p->ign || p->literal|| TEXILIST_TABLE == p->list)
                 return;                  return;
   
         if (0 == --p->outmacro) {          if (0 == --p->outmacro) {
                 fputc('\n', p->outfile);                  fputc('\n', p->outfile);
                 p->outcol = p->seenws = 0;                  p->outcol = p->seenws = 0;
         }          }
         p->seenvs = 0;  
 }  }
   
 /*  /*
Line 301  teximacroopen(struct texi *p, const char *s)
Line 414  teximacroopen(struct texi *p, const char *s)
 {  {
         int      rc;          int      rc;
   
         if (p->ign)          if (p->ign || p->literal|| TEXILIST_TABLE == p->list)
                 return;                  return;
   
         if (p->outcol && 0 == p->outmacro) {          if (p->outcol && 0 == p->outmacro) {
Line 309  teximacroopen(struct texi *p, const char *s)
Line 422  teximacroopen(struct texi *p, const char *s)
                 p->outcol = 0;                  p->outcol = 0;
         }          }
   
           if (p->seenvs > 0 && 0 == p->outmacro)
                   fputs(".Pp\n", p->outfile);
   
         if (0 == p->outmacro)          if (0 == p->outmacro)
                 fputc('.', p->outfile);                  fputc('.', p->outfile);
         else          else
Line 320  teximacroopen(struct texi *p, const char *s)
Line 436  teximacroopen(struct texi *p, const char *s)
         fputc(' ', p->outfile);          fputc(' ', p->outfile);
         p->outcol++;          p->outcol++;
         p->outmacro++;          p->outmacro++;
         p->seenws = 0;          p->seenws = p->seenvs = 0;
         p->seenvs = 0;  
 }  }
   
 /*  /*
Line 338  teximacro(struct texi *p, const char *s)
Line 453  teximacro(struct texi *p, const char *s)
                 texierr(p, "\"%s\" in open line scope!?", s);                  texierr(p, "\"%s\" in open line scope!?", s);
         if (p->literal)          if (p->literal)
                 texierr(p, "\"%s\" in a literal scope!?", s);                  texierr(p, "\"%s\" in a literal scope!?", s);
   
         if (p->outcol)          if (p->outcol)
                 fputc('\n', p->outfile);                  fputc('\n', p->outfile);
           if (p->seenvs > 0)
                   fputs(".Pp\n", p->outfile);
   
         fputc('.', p->outfile);          fputc('.', p->outfile);
         fputs(s, p->outfile);          fputs(s, p->outfile);
         fputc('\n', p->outfile);          fputc('\n', p->outfile);
         p->outcol = p->seenws = 0;          p->outcol = p->seenws = 0;
         p->seenvs = 0;  
 }  }
   
 /*  /*
Line 356  void
Line 471  void
 texivspace(struct texi *p)  texivspace(struct texi *p)
 {  {
   
         if (TEXILIST_TABLE != p->list)          if (TEXILIST_TABLE != p->list && p->seenvs >= 0)
                 teximacro(p, "Pp");                  p->seenvs = 1;
 }  }
   
 /*  /*
Line 420  texipunctuate(struct texi *p, size_t *pos)
Line 535  texipunctuate(struct texi *p, size_t *pos)
         if (end == *pos)          if (end == *pos)
                 return;                  return;
         if (end + 1 == BUFSZ(p) || ' ' == BUF(p)[end] ||          if (end + 1 == BUFSZ(p) || ' ' == BUF(p)[end] ||
                 '\n' == BUF(p)[end]) {                  '@' == BUF(p)[end] || '\n' == BUF(p)[end]) {
                 for ( ; start < end; start++) {                  for ( ; start < end; start++) {
                         texiputchar(p, ' ');                          texiputchar(p, ' ');
                         texiputchar(p, BUF(p)[start]);                          texiputchar(p, BUF(p)[start]);
Line 448  advancenext(struct texi *p, size_t *pos)
Line 563  advancenext(struct texi *p, size_t *pos)
   
         while (*pos < BUFSZ(p) && ismspace(BUF(p)[*pos])) {          while (*pos < BUFSZ(p) && ismspace(BUF(p)[*pos])) {
                 p->seenws = 1;                  p->seenws = 1;
                   if (0 == p->seenvs && '\n' == BUF(p)[*pos])
                           if (*pos + 1 < BUFSZ(p) && '\n' == BUF(p)[*pos + 1])
                                   p->seenvs = 1;
                 advance(p, pos);                  advance(p, pos);
         }          }
         return(*pos);          return(*pos);
Line 608  parseword(struct texi *p, size_t *pos, char extra)
Line 726  parseword(struct texi *p, size_t *pos, char extra)
          * We don't do this if we're in a literal context (we'll print           * We don't do this if we're in a literal context (we'll print
          * out the newlines themselves) nor in a `TS' table.           * out the newlines themselves) nor in a `TS' table.
          */           */
         if (p->seenvs && 0 == p->literal && TEXILIST_TABLE != p->list)          if (p->seenvs > 0 && 0 == p->literal && TEXILIST_TABLE != p->list) {
                 teximacro(p, "Pp");                  if (p->outcol > 0)
                           fputc('\n', p->outfile);
                   fputs(".Pp\n", p->outfile);
                   p->outcol = 0;
           }
   
         p->seenvs = 0;  
   
         /*          /*
          * Some line control: if we (non-macro, non-literal) already           * Some line control: if we (non-macro, non-literal) already
          * have more than 72 characters written to the screen, then           * have more than 72 characters written to the screen, then
Line 684  parseword(struct texi *p, size_t *pos, char extra)
Line 804  parseword(struct texi *p, size_t *pos, char extra)
                         continue;                          continue;
                 }                  }
   
                 if (*pos < BUFSZ(p) - 2 &&                  if ('"' == BUF(p)[*pos]) {
                           texiputchars(p, "\\(dq");
                   } else if (*pos < BUFSZ(p) - 2 &&
                          '-' == BUF(p)[*pos] &&                           '-' == BUF(p)[*pos] &&
                          '-' == BUF(p)[*pos + 1] &&                           '-' == BUF(p)[*pos + 1] &&
                          '-' == BUF(p)[*pos + 2]) {                           '-' == BUF(p)[*pos + 2]) {
Line 712  parseword(struct texi *p, size_t *pos, char extra)
Line 834  parseword(struct texi *p, size_t *pos, char extra)
                 advance(p, pos);                  advance(p, pos);
         }          }
   
         if (*pos + 1 < BUFSZ(p) &&  
                 '\n' == BUF(p)[*pos] &&  
                 '\n' == BUF(p)[*pos + 1])  
                 p->seenvs = 1;  
   
         /*          /*
          * New sentence, new line:if we (non-macro, non-literal) see a           * New sentence, new line:if we (non-macro, non-literal) see a
          * period at the end of the last printed word, then open a           * period at the end of the last printed word, then open a
          * newline.           * newline.
          */           */
         if (0 == p->literal && 0 == p->outmacro &&          if (0 == p->literal && 0 == p->outmacro && *pos < BUFSZ(p))
                 *pos < BUFSZ(p) && '.' == BUF(p)[*pos - 1])                  switch (BUF(p)[*pos - 1]) {
                 texiputchar(p, '\n');                  case ('.'):
                   case ('!'):
                   case ('?'):
                           texiputchar(p, '\n');
                           break;
                   default:
                           break;
                   }
   
           p->seenvs = 0;
 }  }
   
 /*  /*
Line 778  texicmd(const struct texi *p, size_t pos, size_t *end,
Line 904  texicmd(const struct texi *p, size_t pos, size_t *end,
   
         /* Look for it in our indices. */          /* Look for it in our indices. */
         for (i = 0; i < p->indexsz; i++) {          for (i = 0; i < p->indexsz; i++) {
                 toksz = strlen(p->indexs[i]);                  toksz = strlen(p->indexs[i].name);
                 if (len != 5 + toksz)                  if (len != 5 + toksz)
                         continue;                          continue;
                 if (strncmp(&BUF(p)[pos], p->indexs[i], toksz))                  if (strncmp(&BUF(p)[pos], p->indexs[i].name, toksz))
                         continue;                          continue;
                 if (0 == strncmp(&BUF(p)[pos + toksz], "index", 5))                  if (0 == strncmp(&BUF(p)[pos + toksz], "index", 5))
                         return(TEXICMD_USER_INDEX);                          return(TEXICMD_USER_INDEX);
Line 946  parseeoln(struct texi *p, size_t *pos)
Line 1072  parseeoln(struct texi *p, size_t *pos)
                                 texiwarn(p, "unexpected \"{\"");                                  texiwarn(p, "unexpected \"{\"");
                         advance(p, pos);                          advance(p, pos);
                         continue;                          continue;
                   case ('\n'):
                           continue;
                 case ('@'):                  case ('@'):
                         break;                          break;
                 default:                  default:
Line 968  parseeoln(struct texi *p, size_t *pos)
Line 1096  parseeoln(struct texi *p, size_t *pos)
                 advance(p, pos);                  advance(p, pos);
 }  }
   
   enum texicmd
   peeklinecmd(const struct texi *p, size_t pos)
   {
           size_t          end;
   
           while (pos < BUFSZ(p) && isws(BUF(p)[pos]))
                   pos++;
           if (pos == BUFSZ(p) || '@' != BUF(p)[pos])
                   return(TEXICMD__MAX);
           return(texicmd(p, pos, &end, NULL));
   }
   
 /*  /*
  * Peek to see if there's a command after subsequent whitespace.   * Peek to see if there's a command after subsequent whitespace.
  * If so, return the macro identifier.   * If so, return the macro identifier.
Line 1152  parseto(struct texi *p, size_t *pos, const char *endto
Line 1292  parseto(struct texi *p, size_t *pos, const char *endto
                 if (NULL != texitoks[cmd].fp)                  if (NULL != texitoks[cmd].fp)
                         (*texitoks[cmd].fp)(p, cmd, pos);                          (*texitoks[cmd].fp)(p, cmd, pos);
         }          }
   
           if (*pos == BUFSZ(p))
                   texiwarn(p, "EOF expecting \"%s\" end\n", endtoken);
 }  }
   
 /*  /*
Line 1577  teximdocopen(struct texi *p, size_t *pos)
Line 1720  teximdocopen(struct texi *p, size_t *pos)
         t = time(NULL);          t = time(NULL);
         strftime(date, sizeof(date), "%F", localtime(&t));          strftime(date, sizeof(date), "%F", localtime(&t));
   
           p->seenvs = -1;
         teximacroopen(p, "Dd");          teximacroopen(p, "Dd");
         texiputchars(p, date);          texiputchars(p, date);
         teximacroclose(p);          teximacroclose(p);

Legend:
Removed from v.1.29  
changed lines
  Added in v.1.30

CVSweb