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

Diff for /mandoc/roff.c between version 1.261 and 1.265

version 1.261, 2015/02/17 17:16:52 version 1.265, 2015/04/18 17:28:36
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2010, 2011, 2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2009-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
Line 28 
Line 28 
   
 #include "mandoc.h"  #include "mandoc.h"
 #include "mandoc_aux.h"  #include "mandoc_aux.h"
   #include "roff.h"
 #include "libmandoc.h"  #include "libmandoc.h"
 #include "libroff.h"  #include "libroff.h"
   
Line 412  static const char *roff_getstrn(const struct roff *,
Line 413  static const char *roff_getstrn(const struct roff *,
 static  enum rofferr     roff_insec(ROFF_ARGS);  static  enum rofferr     roff_insec(ROFF_ARGS);
 static  enum rofferr     roff_it(ROFF_ARGS);  static  enum rofferr     roff_it(ROFF_ARGS);
 static  enum rofferr     roff_line_ignore(ROFF_ARGS);  static  enum rofferr     roff_line_ignore(ROFF_ARGS);
   static  void             roff_man_alloc1(struct roff_man *);
   static  void             roff_man_free1(struct roff_man *);
 static  enum rofferr     roff_nr(ROFF_ARGS);  static  enum rofferr     roff_nr(ROFF_ARGS);
 static  enum rofft       roff_parse(struct roff *, char *, int *,  static  enum rofft       roff_parse(struct roff *, char *, int *,
                                 int, int);                                  int, int);
Line 898  roff_alloc(struct mparse *parse, const struct mchars *
Line 901  roff_alloc(struct mparse *parse, const struct mchars *
         return(r);          return(r);
 }  }
   
   static void
   roff_man_free1(struct roff_man *man)
   {
   
           if (man->first != NULL) {
                   if (man->macroset == MACROSET_MDOC)
                           mdoc_node_delete(man, man->first);
                   else
                           man_node_delete(man, man->first);
           }
           free(man->meta.msec);
           free(man->meta.vol);
           free(man->meta.os);
           free(man->meta.arch);
           free(man->meta.title);
           free(man->meta.name);
           free(man->meta.date);
   }
   
   static void
   roff_man_alloc1(struct roff_man *man)
   {
   
           memset(&man->meta, 0, sizeof(man->meta));
           man->first = mandoc_calloc(1, sizeof(*man->first));
           man->first->type = ROFFT_ROOT;
           man->last = man->first;
           man->last_es = NULL;
           man->flags = 0;
           man->macroset = MACROSET_NONE;
           man->lastsec = man->lastnamed = SEC_NONE;
           man->next = ROFF_NEXT_CHILD;
   }
   
   void
   roff_man_reset(struct roff_man *man)
   {
   
           roff_man_free1(man);
           roff_man_alloc1(man);
   }
   
   void
   roff_man_free(struct roff_man *man)
   {
   
           roff_man_free1(man);
           free(man);
   }
   
   struct roff_man *
   roff_man_alloc(struct roff *roff, struct mparse *parse,
           const char *defos, int quick)
   {
           struct roff_man *man;
   
           man = mandoc_calloc(1, sizeof(*man));
           man->parse = parse;
           man->roff = roff;
           man->defos = defos;
           man->quick = quick;
           roff_man_alloc1(man);
           return(man);
   }
   
 /*  /*
  * In the current line, expand escape sequences that tend to get   * In the current line, expand escape sequences that tend to get
  * used in numerical expressions and conditional requests.   * used in numerical expressions and conditional requests.
Line 1128  roff_parsetext(struct buf *buf, int pos, int *offs)
Line 1196  roff_parsetext(struct buf *buf, int pos, int *offs)
                         esc = mandoc_escape((const char **)&p, NULL, NULL);                          esc = mandoc_escape((const char **)&p, NULL, NULL);
                         if (esc == ESCAPE_ERROR)                          if (esc == ESCAPE_ERROR)
                                 break;                                  break;
                           while (*p == '-')
                                   p++;
                         continue;                          continue;
                 } else if (p == start) {                  } else if (p == start) {
                         p++;                          p++;
Line 2337  roff_it(ROFF_ARGS)
Line 2407  roff_it(ROFF_ARGS)
                 return(ROFF_IGN);                  return(ROFF_IGN);
         }          }
   
         /* Arm the input line trap. */          while (isspace((unsigned char)buf->buf[pos]))
                   pos++;
   
           /*
            * Arm the input line trap.
            * Special-casing "an-trap" is an ugly workaround to cope
            * with DocBook stupidly fiddling with man(7) internals.
            */
   
         roffit_lines = iv;          roffit_lines = iv;
         roffit_macro = mandoc_strdup(buf->buf + pos);          roffit_macro = mandoc_strdup(iv != 1 ||
               strcmp(buf->buf + pos, "an-trap") ?
               buf->buf + pos : "br");
         return(ROFF_IGN);          return(ROFF_IGN);
 }  }
   
Line 2644  roff_so(ROFF_ARGS)
Line 2723  roff_so(ROFF_ARGS)
 static enum rofferr  static enum rofferr
 roff_userdef(ROFF_ARGS)  roff_userdef(ROFF_ARGS)
 {  {
         const char       *arg[9];          const char       *arg[9], *ap;
         char             *cp, *n1, *n2;          char             *cp, *n1, *n2;
         int               i;          int               i;
           size_t            asz, rsz;
   
         /*          /*
          * Collect pointers to macro argument strings           * Collect pointers to macro argument strings
          * and NUL-terminate them.           * and NUL-terminate them.
          */           */
   
         cp = buf->buf + pos;          cp = buf->buf + pos;
         for (i = 0; i < 9; i++)          for (i = 0; i < 9; i++)
                 arg[i] = *cp == '\0' ? "" :                  arg[i] = *cp == '\0' ? "" :
Line 2660  roff_userdef(ROFF_ARGS)
Line 2741  roff_userdef(ROFF_ARGS)
         /*          /*
          * Expand macro arguments.           * Expand macro arguments.
          */           */
         buf->sz = 0;  
         n1 = cp = mandoc_strdup(r->current_string);          buf->sz = strlen(r->current_string) + 1;
         while ((cp = strstr(cp, "\\$")) != NULL) {          n1 = cp = mandoc_malloc(buf->sz);
                 i = cp[2] - '1';          memcpy(n1, r->current_string, buf->sz);
                 if (0 > i || 8 < i) {          while (*cp != '\0') {
                         /* Not an argument invocation. */  
                         cp += 2;                  /* Scan ahead for the next argument invocation. */
   
                   if (*cp++ != '\\')
                         continue;                          continue;
                   if (*cp++ != '$')
                           continue;
                   i = *cp - '1';
                   if (0 > i || 8 < i)
                           continue;
                   cp -= 2;
   
                   /*
                    * Determine the size of the expanded argument,
                    * taking escaping of quotes into account.
                    */
   
                   asz = 0;
                   for (ap = arg[i]; *ap != '\0'; ap++) {
                           asz++;
                           if (*ap == '"')
                                   asz += 3;
                 }                  }
                 *cp = '\0';                  if (asz != 3) {
                 buf->sz = mandoc_asprintf(&n2, "%s%s%s",  
                     n1, arg[i], cp + 3) + 1;                          /*
                 cp = n2 + (cp - n1);                           * Determine the size of the rest of the
                 free(n1);                           * unexpanded macro, including the NUL.
                 n1 = n2;                           */
   
                           rsz = buf->sz - (cp - n1) - 3;
   
                           /*
                            * When shrinking, move before
                            * releasing the storage.
                            */
   
                           if (asz < 3)
                                   memmove(cp + asz, cp + 3, rsz);
   
                           /*
                            * Resize the storage for the macro
                            * and readjust the parse pointer.
                            */
   
                           buf->sz += asz - 3;
                           n2 = mandoc_realloc(n1, buf->sz);
                           cp = n2 + (cp - n1);
                           n1 = n2;
   
                           /*
                            * When growing, make room
                            * for the expanded argument.
                            */
   
                           if (asz > 3)
                                   memmove(cp + asz, cp + 3, rsz);
                   }
   
                   /* Copy the expanded argument, escaping quotes. */
   
                   n2 = cp;
                   for (ap = arg[i]; *ap != '\0'; ap++) {
                           if (*ap == '"') {
                                   memcpy(n2, "\\(dq", 4);
                                   n2 += 4;
                           } else
                                   *n2++ = *ap;
                   }
         }          }
   
         /*          /*
          * Replace the macro invocation           * Replace the macro invocation
          * by the expanded macro.           * by the expanded macro.
          */           */
   
         free(buf->buf);          free(buf->buf);
         buf->buf = n1;          buf->buf = n1;
         if (buf->sz == 0)  
                 buf->sz = strlen(buf->buf) + 1;  
         *offs = 0;          *offs = 0;
   
         return(buf->sz > 1 && buf->buf[buf->sz - 2] == '\n' ?          return(buf->sz > 1 && buf->buf[buf->sz - 2] == '\n' ?

Legend:
Removed from v.1.261  
changed lines
  Added in v.1.265

CVSweb