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

Diff for /texi2mdoc/util.c between version 1.1 and 1.5

version 1.1, 2015/02/20 09:58:50 version 1.5, 2015/02/21 21:49:18
Line 67  texiexit(struct texi *p)
Line 67  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++)
                   free(p->indexs[i]);
   
         for (i = 0; i < p->valsz; i++) {          for (i = 0; i < p->valsz; i++) {
                 free(p->vals[i].value);                  free(p->vals[i].value);
                 free(p->vals[i].key);                  free(p->vals[i].key);
         }          }
   
         free(p->vals);          free(p->vals);
           free(p->indexs);
         free(p->dirs);          free(p->dirs);
         free(p->subtitle);          free(p->subtitle);
         free(p->title);          free(p->title);
Line 248  void
Line 252  void
 texivspace(struct texi *p)  texivspace(struct texi *p)
 {  {
   
         if (p->seenvs)          if (p->seenvs || TEXILIST_TABLE == p->list)
                 return;                  return;
         teximacro(p, "Pp");          teximacro(p, "Pp");
         p->seenvs = 1;          p->seenvs = 1;
Line 429  enum texicmd
Line 433  enum texicmd
 texicmd(struct texi *p, const char *buf,  texicmd(struct texi *p, const char *buf,
         size_t pos, size_t sz, size_t *end)          size_t pos, size_t sz, size_t *end)
 {  {
         size_t   i, len;          size_t   i, len, toksz;
   
         assert('@' == buf[pos]);          assert('@' == buf[pos]);
   
Line 452  texicmd(struct texi *p, const char *buf, 
Line 456  texicmd(struct texi *p, const char *buf, 
                 return(TEXICMD__MAX);                  return(TEXICMD__MAX);
         }          }
   
           /* Scan to the end of the possible command name. */
         for (*end = pos; *end < sz && ! ismspace(buf[*end]); (*end)++)          for (*end = pos; *end < sz && ! ismspace(buf[*end]); (*end)++)
                 if ((*end > pos && ('@' == buf[*end] ||                  if ((*end > pos && ('@' == buf[*end] ||
                           '{' == buf[*end] || '}' == buf[*end])))                            '{' == buf[*end] || '}' == buf[*end])))
                         break;                          break;
   
           /* Look for the command. */
         len = *end - pos;          len = *end - pos;
         for (i = 0; i < TEXICMD__MAX; i++) {          for (i = 0; i < TEXICMD__MAX; i++) {
                 if (len != texitoks[i].len)                  if (len != texitoks[i].len)
Line 465  texicmd(struct texi *p, const char *buf, 
Line 471  texicmd(struct texi *p, const char *buf, 
                         return(i);                          return(i);
         }          }
   
           /* Look for it in our indices. */
           for (i = 0; i < p->indexsz; i++) {
                   toksz = strlen(p->indexs[i]);
                   if (len != 5 + toksz)
                           continue;
                   if (strncmp(&buf[pos], p->indexs[i], toksz))
                           continue;
                   if (0 == strncmp(&buf[pos + toksz], "index", 5))
                           return(TEXICMD_INDEX);
           }
   
         texiwarn(p, "bad command: @%.*s", (int)len, &buf[pos]);          texiwarn(p, "bad command: @%.*s", (int)len, &buf[pos]);
         return(TEXICMD__MAX);          return(TEXICMD__MAX);
 }  }
Line 667  parselinearg(struct texi *p, const char *buf, size_t s
Line 684  parselinearg(struct texi *p, const char *buf, size_t s
   
         if (*pos < sz && '{' == buf[*pos])          if (*pos < sz && '{' == buf[*pos])
                 parsebracket(p, buf, sz, pos);                  parsebracket(p, buf, sz, pos);
         else if ('\n' != buf[*pos])          else if (*pos < sz && '\n' != buf[*pos])
                 parsesingle(p, buf, sz, pos);                  parsesingle(p, buf, sz, pos);
         else          else
                 return(0);                  return(0);
Line 760  parsefile(struct texi *p, const char *fname, int parse
Line 777  parsefile(struct texi *p, const char *fname, int parse
         struct stat      st;          struct stat      st;
         size_t           i;          size_t           i;
   
         assert(p->filepos < 64);          if (64 == p->filepos)
                   texiabort(p, "too many open files");
         f = &p->files[p->filepos];          f = &p->files[p->filepos];
         memset(f, 0, sizeof(struct texifile));          memset(f, 0, sizeof(struct texifile));
   
Line 801  parsefile(struct texi *p, const char *fname, int parse
Line 819  parsefile(struct texi *p, const char *fname, int parse
         texifilepop(p);          texifilepop(p);
 }  }
   
   /*
    * Look up the value to a stored pair's value starting in "buf" from
    * start to end.
    * Return the pointer to the value memory, which can be NULL if the
    * pointer key does not exist.
    * The pointer can point to NULL if the value has been unset.
    */
   static char **
   valuequery(const struct texi *p,
           const char *buf, size_t start, size_t end)
   {
           size_t   i, sz, len;
   
           assert(end >= start);
           /* Ignore zero-length. */
           if (0 == (len = (end - start)))
                   return(NULL);
           for (i = 0; i < p->valsz; i++) {
                   sz = strlen(p->vals[i].key);
                   if (sz != len)
                           continue;
                   if (0 == strncmp(p->vals[i].key, &buf[start], len))
                           return(&p->vals[i].value);
           }
           return(NULL);
   }
   
   /*
    * Parse a key until the end of line, e.g., @clear foo\n, and return the
    * pointer to its value via valuequery().
    */
   static char **
   valuelquery(struct texi *p, const char *buf, size_t sz, size_t *pos)
   {
           size_t    start, end;
           char    **ret;
   
           while (*pos < sz && isws(buf[*pos]))
                   advance(p, buf, pos);
           if (*pos == sz)
                   return(NULL);
           for (start = end = *pos; end < sz; end++)
                   if ('\n' == buf[end])
                           break;
           advanceto(p, buf, pos, end);
           if (*pos < sz) {
                   assert('\n' == buf[*pos]);
                   advance(p, buf, pos);
           }
           if (NULL == (ret = valuequery(p, buf, start, end)))
                   return(NULL);
           return(ret);
   }
   
   void
   valuelclear(struct texi *p, const char *buf, size_t sz, size_t *pos)
   {
           char    **ret;
   
           if (NULL == (ret = valuelquery(p, buf, sz, pos)))
                   return;
           free(*ret);
           *ret = NULL;
   }
   
   const char *
   valuellookup(struct texi *p, const char *buf, size_t sz, size_t *pos)
   {
           char    **ret;
   
           if (NULL == (ret = valuelquery(p, buf, sz, pos)))
                   return(NULL);
           return(*ret);
   }
   
   /*
    * Parse a key from a bracketed string, e.g., @value{foo}, and return
    * the pointer to its value.
    * If the returned pointer is NULL, either there was no string within
    * the brackets (or no brackets), or the value was not found, or the
    * value had previously been unset.
    */
   const char *
   valueblookup(struct texi *p, const char *buf, size_t sz, size_t *pos)
   {
           size_t    start, end;
           char    **ret;
   
           while (*pos < sz && isws(buf[*pos]))
                   advance(p, buf, pos);
           if (*pos == sz || '{' != buf[*pos])
                   return(NULL);
           advance(p, buf, pos);
           for (start = end = *pos; end < sz; end++)
                   if ('}' == buf[end])
                           break;
           advanceto(p, buf, pos, end);
           if (*pos < sz) {
                   assert('}' == buf[*pos]);
                   advance(p, buf, pos);
           }
           if (NULL == (ret = valuequery(p, buf, start, end)))
                   return(NULL);
           return(*ret);
   }
   
   void
   valueadd(struct texi *p, char *key, char *val)
   {
           size_t   i;
   
           assert(NULL != key);
           assert(NULL != val);
   
           for (i = 0; i < p->valsz; i++)
                   if (0 == strcmp(p->vals[i].key, key))
                           break;
   
           if (i < p->valsz) {
                   free(key);
                   free(p->vals[i].value);
                   p->vals[i].value = val;
           } else {
                   /* FIXME: reallocarray() */
                   p->vals = realloc(p->vals,
                           (p->valsz + 1) *
                            sizeof(struct texivalue));
                   if (NULL == p->vals)
                           texiabort(p, NULL);
                   p->vals[p->valsz].key = key;
                   p->vals[p->valsz].value = val;
                   p->valsz++;
           }
   }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.5

CVSweb