[BACK]Return to tbl_data.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mandoc

Diff for /src/usr.bin/mandoc/tbl_data.c between version 1.3 and 1.4

version 1.3, 2010/10/15 23:19:40 version 1.4, 2011/01/04 22:28:17
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>   * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  *   *
  * 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 14 
Line 14 
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */   */
 #include <sys/queue.h>  
 #include <sys/types.h>  
   
 #include <assert.h>  #include <assert.h>
 #include <ctype.h>  #include <ctype.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   #include <time.h>
   
 #include "out.h"  #include "mandoc.h"
 #include "term.h"  #include "libmandoc.h"
 #include "tbl_extern.h"  #include "libroff.h"
   
 /* FIXME: warn about losing data contents if cell is HORIZ. */  static  int     data(struct tbl_node *, struct tbl_span *,
                           int, const char *, int *);
   
 static  int             data(struct tbl *, struct tbl_span *,  static int
                                 const char *, int, int,  data(struct tbl_node *tbl, struct tbl_span *dp,
                                 const char *, int, int);                  int ln, const char *p, int *pos)
   {
           struct tbl_dat  *dat;
           struct tbl_cell *cp;
           int              sv;
   
           cp = NULL;
           if (dp->last && dp->last->layout)
                   cp = dp->last->layout->next;
           else if (NULL == dp->last)
                   cp = dp->layout->first;
   
 int          /* Skip over spanners to data formats. */
 data(struct tbl *tbl, struct tbl_span *dp,  
                 const char *f, int ln, int pos,  
                 const char *p, int start, int end)  
 {  
         struct tbl_data *dat;  
   
         if (NULL == (dat = tbl_data_alloc(dp)))          while (cp && (TBL_CELL_VERT == cp->pos ||
                 return(0);                                  TBL_CELL_DVERT == cp->pos))
                   cp = cp->next;
   
         if (NULL == dat->cell)          dat = mandoc_calloc(1, sizeof(struct tbl_dat));
                 if ( ! tbl_warnx(tbl, ERR_SYNTAX, f, ln, pos))          dat->layout = cp;
                         return(0);          dat->pos = TBL_DATA_NONE;
   
         assert(end >= start);          if (NULL == dat->layout)
         if (NULL == (dat->string = malloc((size_t)(end - start + 1))))                  TBL_MSG(tbl, MANDOCERR_TBLEXTRADAT, ln, *pos);
                 return(tbl_err(tbl));  
   
         (void)memcpy(dat->string, &p[start], (size_t)(end - start));          if (dp->last) {
         dat->string[end - start] = 0;                  dp->last->next = dat;
                   dp->last = dat;
           } else
                   dp->last = dp->first = dat;
   
         /* XXX: do the strcmps, then malloc(). */          sv = *pos;
           while (p[*pos] && p[*pos] != tbl->opts.tab)
                   (*pos)++;
   
           /*
            * Check for a continued-data scope opening.  This consists of a
            * trailing `T{' at the end of the line.  Subsequent lines,
            * until a standalone `T}', are included in our cell.
            */
   
           if (*pos - sv == 2 && 'T' == p[sv] && '{' == p[sv + 1]) {
                   tbl->part = TBL_PART_CDATA;
                   return(0);
           }
   
           dat->string = mandoc_malloc(*pos - sv + 1);
           memcpy(dat->string, &p[sv], *pos - sv);
           dat->string[*pos - sv] = '\0';
   
           if (p[*pos])
                   (*pos)++;
   
         if ( ! strcmp(dat->string, "_"))          if ( ! strcmp(dat->string, "_"))
                 dat->flags |= TBL_DATA_HORIZ;                  dat->pos = TBL_DATA_HORIZ;
         else if ( ! strcmp(dat->string, "="))          else if ( ! strcmp(dat->string, "="))
                 dat->flags |= TBL_DATA_DHORIZ;                  dat->pos = TBL_DATA_DHORIZ;
         else if ( ! strcmp(dat->string, "\\_"))          else if ( ! strcmp(dat->string, "\\_"))
                 dat->flags |= TBL_DATA_NHORIZ;                  dat->pos = TBL_DATA_NHORIZ;
         else if ( ! strcmp(dat->string, "\\="))          else if ( ! strcmp(dat->string, "\\="))
                 dat->flags |= TBL_DATA_NDHORIZ;                  dat->pos = TBL_DATA_NDHORIZ;
         else          else
                   dat->pos = TBL_DATA_DATA;
   
           if (NULL == dat->layout)
                 return(1);                  return(1);
   
         free(dat->string);          if (TBL_CELL_HORIZ == dat->layout->pos ||
         dat->string = NULL;                          TBL_CELL_DHORIZ == dat->layout->pos)
                   if (TBL_DATA_DATA == dat->pos && '\0' != *dat->string)
                           TBL_MSG(tbl, MANDOCERR_TBLIGNDATA, ln, sv);
   
         return(1);          return(1);
 }  }
   
   int
   tbl_cdata(struct tbl_node *tbl, int ln, const char *p)
   {
           struct tbl_dat  *dat;
           size_t           sz;
   
           if (0 == strcmp(p, "T}")) {
                   tbl->part = TBL_PART_DATA;
                   return(1);
           }
   
           dat = tbl->last_span->last;
           dat->pos = TBL_DATA_DATA;
   
           if (dat->string) {
                   sz = strlen(p) + strlen(dat->string) + 2;
                   dat->string = mandoc_realloc(dat->string, sz);
                   strlcat(dat->string, " ", sz);
                   strlcat(dat->string, p, sz);
           } else
                   dat->string = mandoc_strdup(p);
   
           return(0);
   }
   
 int  int
 tbl_data(struct tbl *tbl, const char *f, int ln, const char *p)  tbl_data(struct tbl_node *tbl, int ln, const char *p)
 {  {
         struct tbl_span *dp;          struct tbl_span *dp;
         int              i, j;          struct tbl_row  *rp;
           int              pos;
   
         if ('.' == p[0] && ! isdigit((u_char)p[1])) {          pos = 0;
                 /* Comment lines end up here with just a dot. */  
                 if ('\0' == p[1])  
                         return(1);  
                 /*  
                  * XXX: departs from tbl convention in that we disallow  
                  * macros in the data body.  
                  */  
                 if (strncasecmp(p, ".T&", 3))  
                         return(tbl_errx(tbl, ERR_SYNTAX, f, ln, 0));  
                 return(tbl_data_close(tbl, f, ln));  
         }  
   
         if (NULL == (dp = tbl_span_alloc(tbl)))          if ('\0' == p[pos]) {
                   TBL_MSG(tbl, MANDOCERR_TBL, ln, pos);
                 return(0);                  return(0);
           }
   
           /*
            * Choose a layout row: take the one following the last parsed
            * span's.  If that doesn't exist, use the last parsed span's.
            * If there's no last parsed span, use the first row.  This can
            * be NULL!
            */
   
           if (tbl->last_span) {
                   assert(tbl->last_span->layout);
                   rp = tbl->last_span->layout->next;
                   if (NULL == rp)
                           rp = tbl->last_span->layout;
           } else
                   rp = tbl->first_row;
   
           dp = mandoc_calloc(1, sizeof(struct tbl_span));
           dp->tbl = &tbl->opts;
           dp->layout = rp;
           dp->head = tbl->first_head;
   
           if (tbl->last_span) {
                   tbl->last_span->next = dp;
                   tbl->last_span = dp;
           } else {
                   tbl->last_span = tbl->first_span = dp;
                   dp->flags |= TBL_SPAN_FIRST;
           }
   
         if ( ! strcmp(p, "_")) {          if ( ! strcmp(p, "_")) {
                 dp->flags |= TBL_SPAN_HORIZ;                  dp->pos = TBL_SPAN_HORIZ;
                 return(1);                  return(1);
         } else if ( ! strcmp(p, "=")) {          } else if ( ! strcmp(p, "=")) {
                 dp->flags |= TBL_SPAN_DHORIZ;                  dp->pos = TBL_SPAN_DHORIZ;
                 return(1);                  return(1);
         }          }
   
         for (j = i = 0; p[i]; i++) {          dp->pos = TBL_SPAN_DATA;
                 if (p[i] != tbl->tab)  
                         continue;  
                 if ( ! data(tbl, dp, f, ln, i, p, j, i))  
                         return(0);  
                 j = i + 1;  
         }  
   
         return(data(tbl, dp, f, ln, i, p, j, i));          /* This returns 0 when TBL_PART_CDATA is entered. */
 }  
   
           while ('\0' != p[pos])
                   if ( ! data(tbl, dp, ln, p, &pos))
                           return(0);
   
 int  
 tbl_data_close(struct tbl *tbl, const char *f, int ln)  
 {  
         struct tbl_span *span;  
   
         /* LINTED */  
         span = TAILQ_LAST(&tbl->span, tbl_spanh);  
         if (NULL == span)  
                 return(tbl_errx(tbl, ERR_SYNTAX, f, ln, 0));  
         if (TAILQ_NEXT(span->row, entries))  
                 return(tbl_errx(tbl, ERR_SYNTAX, f, ln, 0));  
   
         tbl->part = TBL_PART_LAYOUT;  
         return(1);          return(1);
 }  }

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4