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

Diff for /mandoc/roff.c between version 1.176 and 1.179

version 1.176, 2013/05/31 22:08:09 version 1.179, 2013/10/05 20:30:05
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010, 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2010, 2011, 2012, 2013 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
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 21 
Line 21 
   
 #include <assert.h>  #include <assert.h>
 #include <ctype.h>  #include <ctype.h>
   #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   
Line 186  static void   roff_freestr(struct roffkv *);
Line 187  static void   roff_freestr(struct roffkv *);
 static  char            *roff_getname(struct roff *, char **, int, int);  static  char            *roff_getname(struct roff *, char **, int, int);
 static  const char      *roff_getstrn(const struct roff *,  static  const char      *roff_getstrn(const struct roff *,
                                 const char *, size_t);                                  const char *, size_t);
   static  enum rofferr     roff_it(ROFF_ARGS);
 static  enum rofferr     roff_line_ignore(ROFF_ARGS);  static  enum rofferr     roff_line_ignore(ROFF_ARGS);
 static  enum rofferr     roff_nr(ROFF_ARGS);  static  enum rofferr     roff_nr(ROFF_ARGS);
 static  void             roff_openeqn(struct roff *, const char *,  static  void             roff_openeqn(struct roff *, const char *,
                                 int, int, const char *);                                  int, int, const char *);
 static  enum rofft       roff_parse(struct roff *, const char *, int *);  static  enum rofft       roff_parse(struct roff *, const char *, int *);
 static  enum rofferr     roff_parsetext(char *);  static  enum rofferr     roff_parsetext(char **, size_t *, int, int *);
 static  enum rofferr     roff_res(struct roff *,  static  enum rofferr     roff_res(struct roff *,
                                 char **, size_t *, int, int);                                  char **, size_t *, int, int);
 static  enum rofferr     roff_rm(ROFF_ARGS);  static  enum rofferr     roff_rm(ROFF_ARGS);
Line 233  static struct roffmac  roffs[ROFF_MAX] = {
Line 235  static struct roffmac  roffs[ROFF_MAX] = {
         { "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },          { "ie", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
         { "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },          { "if", roff_cond, roff_cond_text, roff_cond_sub, ROFFMAC_STRUCT, NULL },
         { "ig", roff_block, roff_block_text, roff_block_sub, 0, NULL },          { "ig", roff_block, roff_block_text, roff_block_sub, 0, NULL },
         { "it", roff_line_ignore, NULL, NULL, 0, NULL },          { "it", roff_it, NULL, NULL, 0, NULL },
         { "ne", roff_line_ignore, NULL, NULL, 0, NULL },          { "ne", roff_line_ignore, NULL, NULL, 0, NULL },
         { "nh", roff_line_ignore, NULL, NULL, 0, NULL },          { "nh", roff_line_ignore, NULL, NULL, 0, NULL },
         { "nr", roff_nr, NULL, NULL, 0, NULL },          { "nr", roff_nr, NULL, NULL, 0, NULL },
Line 295  static const struct predef predefs[PREDEFS_MAX] = {
Line 297  static const struct predef predefs[PREDEFS_MAX] = {
 /* See roffhash_find() */  /* See roffhash_find() */
 #define ROFF_HASH(p)    (p[0] - ASCII_LO)  #define ROFF_HASH(p)    (p[0] - ASCII_LO)
   
   static  int      roffit_lines;  /* number of lines to delay */
   static  char    *roffit_macro;  /* nil-terminated macro line */
   
 static void  static void
 roffhash_init(void)  roffhash_init(void)
 {  {
Line 596  again:
Line 601  again:
 }  }
   
 /*  /*
  * Process text streams: convert all breakable hyphens into ASCII_HYPH.   * Process text streams:
    * Convert all breakable hyphens into ASCII_HYPH.
    * Decrement and spring input line trap.
  */   */
 static enum rofferr  static enum rofferr
 roff_parsetext(char *p)  roff_parsetext(char **bufp, size_t *szp, int pos, int *offs)
 {  {
         size_t           sz;          size_t           sz;
         const char      *start;          const char      *start;
           char            *p;
           int              isz;
         enum mandoc_esc  esc;          enum mandoc_esc  esc;
   
         start = p;          start = p = *bufp + pos;
   
         while ('\0' != *p) {          while ('\0' != *p) {
                 sz = strcspn(p, "-\\");                  sz = strcspn(p, "-\\");
Line 618  roff_parsetext(char *p)
Line 627  roff_parsetext(char *p)
                         /* Skip over escapes. */                          /* Skip over escapes. */
                         p++;                          p++;
                         esc = mandoc_escape                          esc = mandoc_escape
                                 ((const char **)&p, NULL, NULL);                                  ((const char const **)&p, NULL, NULL);
                         if (ESCAPE_ERROR == esc)                          if (ESCAPE_ERROR == esc)
                                 break;                                  break;
                         continue;                          continue;
Line 633  roff_parsetext(char *p)
Line 642  roff_parsetext(char *p)
                 p++;                  p++;
         }          }
   
           /* Spring the input line trap. */
           if (1 == roffit_lines) {
                   isz = asprintf(&p, "%s\n.%s", *bufp, roffit_macro);
                   if (-1 == isz) {
                           perror(NULL);
                           exit((int)MANDOCLEVEL_SYSERR);
                   }
                   free(*bufp);
                   *bufp = p;
                   *szp = isz + 1;
                   *offs = 0;
                   free(roffit_macro);
                   roffit_lines = 0;
                   return(ROFF_REPARSE);
           } else if (1 < roffit_lines)
                   --roffit_lines;
         return(ROFF_CONT);          return(ROFF_CONT);
 }  }
   
Line 677  roff_parseln(struct roff *r, int ln, char **bufp, 
Line 702  roff_parseln(struct roff *r, int ln, char **bufp, 
                         return(eqn_read(&r->eqn, ln, *bufp, pos, offs));                          return(eqn_read(&r->eqn, ln, *bufp, pos, offs));
                 if (r->tbl)                  if (r->tbl)
                         return(tbl_read(r->tbl, ln, *bufp, pos));                          return(tbl_read(r->tbl, ln, *bufp, pos));
                 return(roff_parsetext(*bufp + pos));                  return(roff_parsetext(bufp, szp, pos, offs));
         } else if ( ! ctl) {          } else if ( ! ctl) {
                 if (r->eqn)                  if (r->eqn)
                         return(eqn_read(&r->eqn, ln, *bufp, pos, offs));                          return(eqn_read(&r->eqn, ln, *bufp, pos, offs));
                 if (r->tbl)                  if (r->tbl)
                         return(tbl_read(r->tbl, ln, *bufp, pos));                          return(tbl_read(r->tbl, ln, *bufp, pos));
                 return(roff_parsetext(*bufp + pos));                  return(roff_parsetext(bufp, szp, pos, offs));
         } else if (r->eqn)          } else if (r->eqn)
                 return(eqn_read(&r->eqn, ln, *bufp, ppos, offs));                  return(eqn_read(&r->eqn, ln, *bufp, ppos, offs));
   
Line 1028  roff_cond_sub(ROFF_ARGS)
Line 1053  roff_cond_sub(ROFF_ARGS)
   
         rr = r->last->rule;          rr = r->last->rule;
         roffnode_cleanscope(r);          roffnode_cleanscope(r);
           t = roff_parse(r, *bufp, &pos);
   
         /*          /*
          * If the macro is unknown, first check if it contains a closing           * Fully handle known macros when they are structurally
          * delimiter `\}'.  If it does, close out our scope and return           * required or when the conditional evaluated to true.
          * the currently-scoped rule (ignore or continue).  Else, drop  
          * into the currently-scoped rule.  
          */           */
   
         if (ROFF_MAX == (t = roff_parse(r, *bufp, &pos))) {          if ((ROFF_MAX != t) &&
                 ep = &(*bufp)[pos];              (ROFF_ccond == t || ROFFRULE_ALLOW == rr ||
                 for ( ; NULL != (ep = strchr(ep, '\\')); ep++) {               ROFFMAC_STRUCT & roffs[t].flags)) {
                         ep++;                  assert(roffs[t].proc);
                         if ('}' != *ep)                  return((*roffs[t].proc)(r, t, bufp, szp,
                                 continue;                                          ln, ppos, pos, offs));
           }
   
                         /*          /* Always check for the closing delimiter `\}'. */
                          * Make the \} go away.  
                          * This is a little haphazard, as it's not quite  
                          * clear how nroff does this.  
                          * If we're at the end of line, then just chop  
                          * off the \} and resize the buffer.  
                          * If we aren't, then conver it to spaces.  
                          */  
   
                         if ('\0' == *(ep + 1)) {          ep = &(*bufp)[pos];
                                 *--ep = '\0';          while (NULL != (ep = strchr(ep, '\\'))) {
                                 *szp -= 2;                  if ('}' != *(++ep))
                         } else                          continue;
                                 *(ep - 1) = *ep = ' ';  
   
                         roff_ccond(r, ROFF_ccond, bufp, szp,                  /*
                                         ln, pos, pos + 2, offs);                   * If we're at the end of line, then just chop
                         break;                   * off the \} and resize the buffer.
                 }                   * If we aren't, then convert it to spaces.
                 return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);                   */
         }  
   
         /*                  if ('\0' == *(ep + 1)) {
          * A denied conditional must evaluate its children if and only                          *--ep = '\0';
          * if they're either structurally required (such as loops and                          *szp -= 2;
          * conditionals) or a closing macro.                  } else
          */                          *(ep - 1) = *ep = ' ';
   
         if (ROFFRULE_DENY == rr)                  roff_ccond(r, ROFF_ccond, bufp, szp,
                 if ( ! (ROFFMAC_STRUCT & roffs[t].flags))                                  ln, pos, pos + 2, offs);
                         if (ROFF_ccond != t)                  break;
                                 return(ROFF_IGN);          }
           return(ROFFRULE_DENY == rr ? ROFF_IGN : ROFF_CONT);
         assert(roffs[t].proc);  
         return((*roffs[t].proc)(r, t, bufp, szp,  
                                 ln, ppos, pos, offs));  
 }  }
   
 /* ARGSUSED */  /* ARGSUSED */
Line 1132  static enum rofferr
Line 1145  static enum rofferr
 roff_line_ignore(ROFF_ARGS)  roff_line_ignore(ROFF_ARGS)
 {  {
   
         if (ROFF_it == tok)  
                 mandoc_msg(MANDOCERR_REQUEST, r->parse, ln, ppos, "it");  
   
         return(ROFF_IGN);          return(ROFF_IGN);
 }  }
   
Line 1304  roff_rm(ROFF_ARGS)
Line 1314  roff_rm(ROFF_ARGS)
                 if ('\0' != *name)                  if ('\0' != *name)
                         roff_setstr(r, name, NULL, 0);                          roff_setstr(r, name, NULL, 0);
         }          }
           return(ROFF_IGN);
   }
   
   /* ARGSUSED */
   static enum rofferr
   roff_it(ROFF_ARGS)
   {
           char            *cp;
           size_t           len;
           int              iv;
   
           /* Parse the number of lines. */
           cp = *bufp + pos;
           len = strcspn(cp, " \t");
           cp[len] = '\0';
           if ((iv = mandoc_strntoi(cp, len, 10)) <= 0) {
                   mandoc_msg(MANDOCERR_NUMERIC, r->parse,
                                   ln, ppos, *bufp + 1);
                   return(ROFF_IGN);
           }
           cp += len + 1;
   
           /* Arm the input line trap. */
           roffit_lines = iv;
           roffit_macro = mandoc_strdup(cp);
         return(ROFF_IGN);          return(ROFF_IGN);
 }  }
   

Legend:
Removed from v.1.176  
changed lines
  Added in v.1.179

CVSweb