1*61d06d6bSBaptiste Daroussin /* $Id: roff_validate.c,v 1.9 2017/06/14 22:51:25 schwarze Exp $ */ 2*61d06d6bSBaptiste Daroussin /* 3*61d06d6bSBaptiste Daroussin * Copyright (c) 2010, 2017 Ingo Schwarze <schwarze@openbsd.org> 4*61d06d6bSBaptiste Daroussin * 5*61d06d6bSBaptiste Daroussin * Permission to use, copy, modify, and distribute this software for any 6*61d06d6bSBaptiste Daroussin * purpose with or without fee is hereby granted, provided that the above 7*61d06d6bSBaptiste Daroussin * copyright notice and this permission notice appear in all copies. 8*61d06d6bSBaptiste Daroussin * 9*61d06d6bSBaptiste Daroussin * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10*61d06d6bSBaptiste Daroussin * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*61d06d6bSBaptiste Daroussin * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12*61d06d6bSBaptiste Daroussin * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*61d06d6bSBaptiste Daroussin * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*61d06d6bSBaptiste Daroussin * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15*61d06d6bSBaptiste Daroussin * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16*61d06d6bSBaptiste Daroussin */ 17*61d06d6bSBaptiste Daroussin #include <sys/types.h> 18*61d06d6bSBaptiste Daroussin 19*61d06d6bSBaptiste Daroussin #include <assert.h> 20*61d06d6bSBaptiste Daroussin #include <stddef.h> 21*61d06d6bSBaptiste Daroussin 22*61d06d6bSBaptiste Daroussin #include "mandoc.h" 23*61d06d6bSBaptiste Daroussin #include "roff.h" 24*61d06d6bSBaptiste Daroussin #include "libmandoc.h" 25*61d06d6bSBaptiste Daroussin #include "roff_int.h" 26*61d06d6bSBaptiste Daroussin 27*61d06d6bSBaptiste Daroussin #define ROFF_VALID_ARGS struct roff_man *man, struct roff_node *n 28*61d06d6bSBaptiste Daroussin 29*61d06d6bSBaptiste Daroussin typedef void (*roff_valid_fp)(ROFF_VALID_ARGS); 30*61d06d6bSBaptiste Daroussin 31*61d06d6bSBaptiste Daroussin static void roff_valid_ft(ROFF_VALID_ARGS); 32*61d06d6bSBaptiste Daroussin 33*61d06d6bSBaptiste Daroussin static const roff_valid_fp roff_valids[ROFF_MAX] = { 34*61d06d6bSBaptiste Daroussin NULL, /* br */ 35*61d06d6bSBaptiste Daroussin NULL, /* ce */ 36*61d06d6bSBaptiste Daroussin roff_valid_ft, /* ft */ 37*61d06d6bSBaptiste Daroussin NULL, /* ll */ 38*61d06d6bSBaptiste Daroussin NULL, /* mc */ 39*61d06d6bSBaptiste Daroussin NULL, /* po */ 40*61d06d6bSBaptiste Daroussin NULL, /* rj */ 41*61d06d6bSBaptiste Daroussin NULL, /* sp */ 42*61d06d6bSBaptiste Daroussin NULL, /* ta */ 43*61d06d6bSBaptiste Daroussin NULL, /* ti */ 44*61d06d6bSBaptiste Daroussin }; 45*61d06d6bSBaptiste Daroussin 46*61d06d6bSBaptiste Daroussin 47*61d06d6bSBaptiste Daroussin void 48*61d06d6bSBaptiste Daroussin roff_validate(struct roff_man *man) 49*61d06d6bSBaptiste Daroussin { 50*61d06d6bSBaptiste Daroussin struct roff_node *n; 51*61d06d6bSBaptiste Daroussin 52*61d06d6bSBaptiste Daroussin n = man->last; 53*61d06d6bSBaptiste Daroussin assert(n->tok < ROFF_MAX); 54*61d06d6bSBaptiste Daroussin if (roff_valids[n->tok] != NULL) 55*61d06d6bSBaptiste Daroussin (*roff_valids[n->tok])(man, n); 56*61d06d6bSBaptiste Daroussin } 57*61d06d6bSBaptiste Daroussin 58*61d06d6bSBaptiste Daroussin static void 59*61d06d6bSBaptiste Daroussin roff_valid_ft(ROFF_VALID_ARGS) 60*61d06d6bSBaptiste Daroussin { 61*61d06d6bSBaptiste Daroussin char *cp; 62*61d06d6bSBaptiste Daroussin 63*61d06d6bSBaptiste Daroussin if (n->child == NULL) { 64*61d06d6bSBaptiste Daroussin man->next = ROFF_NEXT_CHILD; 65*61d06d6bSBaptiste Daroussin roff_word_alloc(man, n->line, n->pos, "P"); 66*61d06d6bSBaptiste Daroussin man->last = n; 67*61d06d6bSBaptiste Daroussin return; 68*61d06d6bSBaptiste Daroussin } 69*61d06d6bSBaptiste Daroussin 70*61d06d6bSBaptiste Daroussin cp = n->child->string; 71*61d06d6bSBaptiste Daroussin switch (*cp) { 72*61d06d6bSBaptiste Daroussin case '1': 73*61d06d6bSBaptiste Daroussin case '2': 74*61d06d6bSBaptiste Daroussin case '3': 75*61d06d6bSBaptiste Daroussin case '4': 76*61d06d6bSBaptiste Daroussin case 'I': 77*61d06d6bSBaptiste Daroussin case 'P': 78*61d06d6bSBaptiste Daroussin case 'R': 79*61d06d6bSBaptiste Daroussin if (cp[1] == '\0') 80*61d06d6bSBaptiste Daroussin return; 81*61d06d6bSBaptiste Daroussin break; 82*61d06d6bSBaptiste Daroussin case 'B': 83*61d06d6bSBaptiste Daroussin if (cp[1] == '\0' || (cp[1] == 'I' && cp[2] == '\0')) 84*61d06d6bSBaptiste Daroussin return; 85*61d06d6bSBaptiste Daroussin break; 86*61d06d6bSBaptiste Daroussin case 'C': 87*61d06d6bSBaptiste Daroussin if (cp[1] == 'W' && cp[2] == '\0') 88*61d06d6bSBaptiste Daroussin return; 89*61d06d6bSBaptiste Daroussin break; 90*61d06d6bSBaptiste Daroussin default: 91*61d06d6bSBaptiste Daroussin break; 92*61d06d6bSBaptiste Daroussin } 93*61d06d6bSBaptiste Daroussin 94*61d06d6bSBaptiste Daroussin mandoc_vmsg(MANDOCERR_FT_BAD, man->parse, 95*61d06d6bSBaptiste Daroussin n->line, n->pos, "ft %s", cp); 96*61d06d6bSBaptiste Daroussin roff_node_delete(man, n); 97*61d06d6bSBaptiste Daroussin } 98