Print this page
Update to 1.12.3.
   1 /*      $Id: tbl_data.c,v 1.24 2011/03/20 16:02:05 kristaps Exp $ */
   2 /*
   3  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
   4  * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
   5  *
   6  * Permission to use, copy, modify, and distribute this software for any
   7  * purpose with or without fee is hereby granted, provided that the above
   8  * copyright notice and this permission notice appear in all copies.
   9  *
  10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17  */
  18 #ifdef HAVE_CONFIG_H
  19 #include "config.h"
  20 #endif
  21 


  32 static  int              data(struct tbl_node *, struct tbl_span *, 
  33                                 int, const char *, int *);
  34 static  struct tbl_span *newspan(struct tbl_node *, int, 
  35                                 struct tbl_row *);
  36 
  37 static int
  38 data(struct tbl_node *tbl, struct tbl_span *dp, 
  39                 int ln, const char *p, int *pos)
  40 {
  41         struct tbl_dat  *dat;
  42         struct tbl_cell *cp;
  43         int              sv, spans;
  44 
  45         cp = NULL;
  46         if (dp->last && dp->last->layout)
  47                 cp = dp->last->layout->next;
  48         else if (NULL == dp->last)
  49                 cp = dp->layout->first;
  50 
  51         /* 
  52          * Skip over spanners and vertical lines to data formats, since
  53          * we want to match data with data layout cells in the header.
  54          */
  55 
  56         while (cp && (TBL_CELL_VERT == cp->pos || 
  57                                 TBL_CELL_DVERT == cp->pos ||
  58                                 TBL_CELL_SPAN == cp->pos))
  59                 cp = cp->next;
  60 
  61         /*
  62          * Stop processing when we reach the end of the available layout
  63          * cells.  This means that we have extra input.
  64          */
  65 
  66         if (NULL == cp) {
  67                 mandoc_msg(MANDOCERR_TBLEXTRADAT, 
  68                                 tbl->parse, ln, *pos, NULL);
  69                 /* Skip to the end... */
  70                 while (p[*pos])
  71                         (*pos)++;
  72                 return(1);
  73         }
  74 
  75         dat = mandoc_calloc(1, sizeof(struct tbl_dat));
  76         dat->layout = cp;
  77         dat->pos = TBL_DATA_NONE;
  78 


  87         dat->spans = spans;
  88 
  89         if (dp->last) {
  90                 dp->last->next = dat;
  91                 dp->last = dat;
  92         } else
  93                 dp->last = dp->first = dat;
  94 
  95         sv = *pos;
  96         while (p[*pos] && p[*pos] != tbl->opts.tab)
  97                 (*pos)++;
  98 
  99         /*
 100          * Check for a continued-data scope opening.  This consists of a
 101          * trailing `T{' at the end of the line.  Subsequent lines,
 102          * until a standalone `T}', are included in our cell.
 103          */
 104 
 105         if (*pos - sv == 2 && 'T' == p[sv] && '{' == p[sv + 1]) {
 106                 tbl->part = TBL_PART_CDATA;
 107                 return(0);
 108         }
 109 
 110         assert(*pos - sv >= 0);
 111 
 112         dat->string = mandoc_malloc((size_t)(*pos - sv + 1));
 113         memcpy(dat->string, &p[sv], (size_t)(*pos - sv));
 114         dat->string[*pos - sv] = '\0';
 115 
 116         if (p[*pos])
 117                 (*pos)++;
 118 
 119         if ( ! strcmp(dat->string, "_"))
 120                 dat->pos = TBL_DATA_HORIZ;
 121         else if ( ! strcmp(dat->string, "="))
 122                 dat->pos = TBL_DATA_DHORIZ;
 123         else if ( ! strcmp(dat->string, "\\_"))
 124                 dat->pos = TBL_DATA_NHORIZ;
 125         else if ( ! strcmp(dat->string, "\\="))
 126                 dat->pos = TBL_DATA_NDHORIZ;
 127         else


 170                 dat->string = mandoc_realloc(dat->string, sz);
 171                 strlcat(dat->string, " ", sz);
 172                 strlcat(dat->string, p, sz);
 173         } else
 174                 dat->string = mandoc_strdup(p);
 175 
 176         if (TBL_CELL_DOWN == dat->layout->pos) 
 177                 mandoc_msg(MANDOCERR_TBLIGNDATA, 
 178                                 tbl->parse, ln, pos, NULL);
 179 
 180         return(0);
 181 }
 182 
 183 static struct tbl_span *
 184 newspan(struct tbl_node *tbl, int line, struct tbl_row *rp)
 185 {
 186         struct tbl_span *dp;
 187 
 188         dp = mandoc_calloc(1, sizeof(struct tbl_span));
 189         dp->line = line;
 190         dp->tbl = &tbl->opts;
 191         dp->layout = rp;
 192         dp->head = tbl->first_head;
 193 
 194         if (tbl->last_span) {
 195                 tbl->last_span->next = dp;
 196                 tbl->last_span = dp;
 197         } else {
 198                 tbl->last_span = tbl->first_span = dp;
 199                 tbl->current_span = NULL;
 200                 dp->flags |= TBL_SPAN_FIRST;
 201         }
 202 
 203         return(dp);
 204 }
 205 
 206 int
 207 tbl_data(struct tbl_node *tbl, int ln, const char *p)
 208 {
 209         struct tbl_span *dp;
 210         struct tbl_row  *rp;


   1 /*      $Id: tbl_data.c,v 1.27 2013/06/01 04:56:50 schwarze Exp $ */
   2 /*
   3  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
   4  * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
   5  *
   6  * Permission to use, copy, modify, and distribute this software for any
   7  * purpose with or without fee is hereby granted, provided that the above
   8  * copyright notice and this permission notice appear in all copies.
   9  *
  10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17  */
  18 #ifdef HAVE_CONFIG_H
  19 #include "config.h"
  20 #endif
  21 


  32 static  int              data(struct tbl_node *, struct tbl_span *, 
  33                                 int, const char *, int *);
  34 static  struct tbl_span *newspan(struct tbl_node *, int, 
  35                                 struct tbl_row *);
  36 
  37 static int
  38 data(struct tbl_node *tbl, struct tbl_span *dp, 
  39                 int ln, const char *p, int *pos)
  40 {
  41         struct tbl_dat  *dat;
  42         struct tbl_cell *cp;
  43         int              sv, spans;
  44 
  45         cp = NULL;
  46         if (dp->last && dp->last->layout)
  47                 cp = dp->last->layout->next;
  48         else if (NULL == dp->last)
  49                 cp = dp->layout->first;
  50 
  51         /* 
  52          * Skip over spanners, since
  53          * we want to match data with data layout cells in the header.
  54          */
  55 
  56         while (cp && TBL_CELL_SPAN == cp->pos)


  57                 cp = cp->next;
  58 
  59         /*
  60          * Stop processing when we reach the end of the available layout
  61          * cells.  This means that we have extra input.
  62          */
  63 
  64         if (NULL == cp) {
  65                 mandoc_msg(MANDOCERR_TBLEXTRADAT, 
  66                                 tbl->parse, ln, *pos, NULL);
  67                 /* Skip to the end... */
  68                 while (p[*pos])
  69                         (*pos)++;
  70                 return(1);
  71         }
  72 
  73         dat = mandoc_calloc(1, sizeof(struct tbl_dat));
  74         dat->layout = cp;
  75         dat->pos = TBL_DATA_NONE;
  76 


  85         dat->spans = spans;
  86 
  87         if (dp->last) {
  88                 dp->last->next = dat;
  89                 dp->last = dat;
  90         } else
  91                 dp->last = dp->first = dat;
  92 
  93         sv = *pos;
  94         while (p[*pos] && p[*pos] != tbl->opts.tab)
  95                 (*pos)++;
  96 
  97         /*
  98          * Check for a continued-data scope opening.  This consists of a
  99          * trailing `T{' at the end of the line.  Subsequent lines,
 100          * until a standalone `T}', are included in our cell.
 101          */
 102 
 103         if (*pos - sv == 2 && 'T' == p[sv] && '{' == p[sv + 1]) {
 104                 tbl->part = TBL_PART_CDATA;
 105                 return(1);
 106         }
 107 
 108         assert(*pos - sv >= 0);
 109 
 110         dat->string = mandoc_malloc((size_t)(*pos - sv + 1));
 111         memcpy(dat->string, &p[sv], (size_t)(*pos - sv));
 112         dat->string[*pos - sv] = '\0';
 113 
 114         if (p[*pos])
 115                 (*pos)++;
 116 
 117         if ( ! strcmp(dat->string, "_"))
 118                 dat->pos = TBL_DATA_HORIZ;
 119         else if ( ! strcmp(dat->string, "="))
 120                 dat->pos = TBL_DATA_DHORIZ;
 121         else if ( ! strcmp(dat->string, "\\_"))
 122                 dat->pos = TBL_DATA_NHORIZ;
 123         else if ( ! strcmp(dat->string, "\\="))
 124                 dat->pos = TBL_DATA_NDHORIZ;
 125         else


 168                 dat->string = mandoc_realloc(dat->string, sz);
 169                 strlcat(dat->string, " ", sz);
 170                 strlcat(dat->string, p, sz);
 171         } else
 172                 dat->string = mandoc_strdup(p);
 173 
 174         if (TBL_CELL_DOWN == dat->layout->pos) 
 175                 mandoc_msg(MANDOCERR_TBLIGNDATA, 
 176                                 tbl->parse, ln, pos, NULL);
 177 
 178         return(0);
 179 }
 180 
 181 static struct tbl_span *
 182 newspan(struct tbl_node *tbl, int line, struct tbl_row *rp)
 183 {
 184         struct tbl_span *dp;
 185 
 186         dp = mandoc_calloc(1, sizeof(struct tbl_span));
 187         dp->line = line;
 188         dp->opts = &tbl->opts;
 189         dp->layout = rp;
 190         dp->head = tbl->first_head;
 191 
 192         if (tbl->last_span) {
 193                 tbl->last_span->next = dp;
 194                 tbl->last_span = dp;
 195         } else {
 196                 tbl->last_span = tbl->first_span = dp;
 197                 tbl->current_span = NULL;
 198                 dp->flags |= TBL_SPAN_FIRST;
 199         }
 200 
 201         return(dp);
 202 }
 203 
 204 int
 205 tbl_data(struct tbl_node *tbl, int ln, const char *p)
 206 {
 207         struct tbl_span *dp;
 208         struct tbl_row  *rp;