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

Diff for /mandoc/mandoc.c between version 1.63 and 1.64

version 1.63, 2012/05/31 22:29:13 version 1.64, 2012/05/31 22:34:06
Line 37 
Line 37 
   
 static  int      a2time(time_t *, const char *, const char *);  static  int      a2time(time_t *, const char *, const char *);
 static  char    *time2a(time_t);  static  char    *time2a(time_t);
 static  int      numescape(const char *);  
   
 /*  
  * Pass over recursive numerical expressions.  This context of this  
  * function is important: it's only called within character-terminating  
  * escapes (e.g., \s[xxxyyy]), so all we need to do is handle initial  
  * recursion: we don't care about what's in these blocks.  
  * This returns the number of characters skipped or -1 if an error  
  * occurs (the caller should bail).  
  */  
 static int  
 numescape(const char *start)  
 {  
         int              i;  
         size_t           sz;  
         const char      *cp;  
   
         i = 0;  
   
         /* The expression consists of a subexpression. */  
   
         if ('\\' == start[i]) {  
                 cp = &start[++i];  
                 /*  
                  * Read past the end of the subexpression.  
                  * Bail immediately on errors.  
                  */  
                 if (ESCAPE_ERROR == mandoc_escape(&cp, NULL, NULL))  
                         return(-1);  
                 return(i + cp - &start[i]);  
         }  
   
         if ('(' != start[i++])  
                 return(0);  
   
         /*  
          * A parenthesised subexpression.  Read until the closing  
          * parenthesis, making sure to handle any nested subexpressions  
          * that might ruin our parse.  
          */  
   
         while (')' != start[i]) {  
                 sz = strcspn(&start[i], ")\\");  
                 i += (int)sz;  
   
                 if ('\0' == start[i])  
                         return(-1);  
                 else if ('\\' != start[i])  
                         continue;  
   
                 cp = &start[++i];  
                 if (ESCAPE_ERROR == mandoc_escape(&cp, NULL, NULL))  
                         return(-1);  
                 i += cp - &start[i];  
         }  
   
         /* Read past the terminating ')'. */  
         return(++i);  
 }  
   
 enum mandoc_esc  enum mandoc_esc
 mandoc_escape(const char **end, const char **start, int *sz)  mandoc_escape(const char **end, const char **start, int *sz)
 {  {
         char             c, term, numeric;          char             c, term;
         int              i, lim, ssz, rlim;          int              i, rlim;
         const char      *cp, *rstart;          const char      *cp, *rstart;
         enum mandoc_esc  gly;          enum mandoc_esc  gly;
   
Line 109  mandoc_escape(const char **end, const char **start, in
Line 51  mandoc_escape(const char **end, const char **start, in
         rstart = cp;          rstart = cp;
         if (start)          if (start)
                 *start = rstart;                  *start = rstart;
         i = lim = 0;          i = rlim = 0;
         gly = ESCAPE_ERROR;          gly = ESCAPE_ERROR;
         term = numeric = '\0';          term = '\0';
   
         switch ((c = cp[i++])) {          switch ((c = cp[i++])) {
         /*          /*
Line 121  mandoc_escape(const char **end, const char **start, in
Line 63  mandoc_escape(const char **end, const char **start, in
          */           */
         case ('('):          case ('('):
                 gly = ESCAPE_SPECIAL;                  gly = ESCAPE_SPECIAL;
                 lim = 2;                  rlim = 2;
                 break;                  break;
         case ('['):          case ('['):
                 gly = ESCAPE_SPECIAL;                  gly = ESCAPE_SPECIAL;
Line 183  mandoc_escape(const char **end, const char **start, in
Line 125  mandoc_escape(const char **end, const char **start, in
   
                 switch (cp[i++]) {                  switch (cp[i++]) {
                 case ('('):                  case ('('):
                         lim = 2;                          rlim = 2;
                         break;                          break;
                 case ('['):                  case ('['):
                         term = ']';                          term = ']';
                         break;                          break;
                 default:                  default:
                         lim = 1;                          rlim = 1;
                         i--;                          i--;
                         break;                          break;
                 }                  }
Line 244  mandoc_escape(const char **end, const char **start, in
Line 186  mandoc_escape(const char **end, const char **start, in
                         gly = ESCAPE_IGNORE;                          gly = ESCAPE_IGNORE;
                 if ('\'' != cp[i++])                  if ('\'' != cp[i++])
                         return(ESCAPE_ERROR);                          return(ESCAPE_ERROR);
                 term = numeric = '\'';                  term = '\'';
                 break;                  break;
   
         /*          /*
Line 284  mandoc_escape(const char **end, const char **start, in
Line 226  mandoc_escape(const char **end, const char **start, in
   
                 switch (cp[i++]) {                  switch (cp[i++]) {
                 case ('('):                  case ('('):
                         lim = 2;                          rlim = 2;
                         break;                          break;
                 case ('['):                  case ('['):
                         term = numeric = ']';                          term = ']';
                         break;                          break;
                 case ('\''):                  case ('\''):
                         term = numeric = '\'';                          term = '\'';
                         break;                          break;
                 default:                  default:
                         lim = 1;                          rlim = 1;
                         i--;                          i--;
                         break;                          break;
                 }                  }
Line 310  mandoc_escape(const char **end, const char **start, in
Line 252  mandoc_escape(const char **end, const char **start, in
          */           */
         default:          default:
                 gly = ESCAPE_SPECIAL;                  gly = ESCAPE_SPECIAL;
                 lim = 1;                  rlim = 1;
                 i--;                  i--;
                 break;                  break;
         }          }
   
         assert(ESCAPE_ERROR != gly);          assert(ESCAPE_ERROR != gly);
   
         rstart = &cp[i];          *end = rstart = &cp[i];
         if (start)          if (start)
                 *start = rstart;                  *start = rstart;
   
         /*          /*
          * If a terminating block has been specified, we need to           * Read up to the terminating character,
          * handle the case of recursion, which could have their           * paying attention to nested escapes.
          * own terminating blocks that mess up our parse.  This, by the  
          * way, means that the "start" and "size" values will be  
          * effectively meaningless.  
          */           */
   
         ssz = 0;  
         if (numeric && -1 == (ssz = numescape(&cp[i])))  
                 return(ESCAPE_ERROR);  
   
         i += ssz;  
         rlim = -1;  
   
         /*  
          * We have a character terminator.  Try to read up to that  
          * character.  If we can't (i.e., we hit the nil), then return  
          * an error; if we can, calculate our length, read past the  
          * terminating character, and exit.  
          */  
   
         if ('\0' != term) {          if ('\0' != term) {
                 *end = strchr(&cp[i], term);                  while (**end != term) {
                 if ('\0' == *end)                          switch (**end) {
                           case ('\0'):
                                   return(ESCAPE_ERROR);
                           case ('\\'):
                                   (*end)++;
                                   if (ESCAPE_ERROR ==
                                       mandoc_escape(end, NULL, NULL))
                                           return(ESCAPE_ERROR);
                                   break;
                           default:
                                   (*end)++;
                                   break;
                           }
                   }
                   rlim = (*end)++ - rstart;
           } else {
                   assert(rlim > 0);
                   if ((size_t)rlim > strlen(rstart))
                         return(ESCAPE_ERROR);                          return(ESCAPE_ERROR);
                   *end += rlim;
                 rlim = *end - &cp[i];  
                 if (sz)  
                         *sz = rlim;  
                 (*end)++;  
                 goto out;  
         }          }
   
         assert(lim > 0);  
   
         /*  
          * We have a numeric limit.  If the string is shorter than that,  
          * stop and return an error.  Else adjust our endpoint, length,  
          * and return the current glyph.  
          */  
   
         if ((size_t)lim > strlen(&cp[i]))  
                 return(ESCAPE_ERROR);  
   
         rlim = lim;  
         if (sz)          if (sz)
                 *sz = rlim;                  *sz = rlim;
   
         *end = &cp[i] + lim;  
   
 out:  
         assert(rlim >= 0 && rstart);  
   
         /* Run post-processors. */          /* Run post-processors. */
   

Legend:
Removed from v.1.63  
changed lines
  Added in v.1.64

CVSweb