![]() ![]() | ![]() |
version 1.9, 2017/06/14 22:51:25 | version 1.14, 2018/12/14 05:18:03 | ||
---|---|---|---|
|
|
||
/* $Id$ */ | /* $Id$ */ | ||
/* | /* | ||
* Copyright (c) 2010, 2017 Ingo Schwarze <schwarze@openbsd.org> | * Copyright (c) 2010, 2017, 2018 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 | ||
|
|
||
#include <sys/types.h> | #include <sys/types.h> | ||
#include <assert.h> | #include <assert.h> | ||
#include <stddef.h> | #include <stdio.h> | ||
#include <string.h> | |||
#include "mandoc.h" | #include "mandoc.h" | ||
#include "roff.h" | #include "roff.h" | ||
|
|
||
typedef void (*roff_valid_fp)(ROFF_VALID_ARGS); | typedef void (*roff_valid_fp)(ROFF_VALID_ARGS); | ||
static void roff_valid_br(ROFF_VALID_ARGS); | |||
static void roff_valid_ft(ROFF_VALID_ARGS); | static void roff_valid_ft(ROFF_VALID_ARGS); | ||
static void roff_valid_sp(ROFF_VALID_ARGS); | |||
static const roff_valid_fp roff_valids[ROFF_MAX] = { | static const roff_valid_fp roff_valids[ROFF_MAX] = { | ||
NULL, /* br */ | roff_valid_br, /* br */ | ||
NULL, /* ce */ | NULL, /* ce */ | ||
roff_valid_ft, /* ft */ | roff_valid_ft, /* ft */ | ||
NULL, /* ll */ | NULL, /* ll */ | ||
NULL, /* mc */ | NULL, /* mc */ | ||
NULL, /* po */ | NULL, /* po */ | ||
NULL, /* rj */ | NULL, /* rj */ | ||
NULL, /* sp */ | roff_valid_sp, /* sp */ | ||
NULL, /* ta */ | NULL, /* ta */ | ||
NULL, /* ti */ | NULL, /* ti */ | ||
}; | }; | ||
|
|
||
} | } | ||
static void | static void | ||
roff_valid_br(ROFF_VALID_ARGS) | |||
{ | |||
struct roff_node *np; | |||
if (n->child != NULL) | |||
mandoc_msg(MANDOCERR_ARG_SKIP, | |||
n->line, n->pos, "br %s", n->child->string); | |||
if (n->next != NULL && n->next->type == ROFFT_TEXT && | |||
*n->next->string == ' ') { | |||
mandoc_msg(MANDOCERR_PAR_SKIP, n->line, n->pos, | |||
"br before text line with leading blank"); | |||
roff_node_delete(man, n); | |||
return; | |||
} | |||
if ((np = n->prev) == NULL) | |||
return; | |||
switch (np->tok) { | |||
case ROFF_br: | |||
case ROFF_sp: | |||
case MDOC_Pp: | |||
mandoc_msg(MANDOCERR_PAR_SKIP, | |||
n->line, n->pos, "br after %s", roff_name[np->tok]); | |||
roff_node_delete(man, n); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
static void | |||
roff_valid_ft(ROFF_VALID_ARGS) | roff_valid_ft(ROFF_VALID_ARGS) | ||
{ | { | ||
char *cp; | const char *cp; | ||
if (n->child == NULL) { | if (n->child == NULL) { | ||
man->next = ROFF_NEXT_CHILD; | man->next = ROFF_NEXT_CHILD; | ||
|
|
||
return; | return; | ||
break; | break; | ||
case 'C': | case 'C': | ||
if (cp[1] == 'W' && cp[2] == '\0') | if (cp[1] != '\0' && cp[2] == '\0' && | ||
strchr("BIRW", cp[1]) != NULL) | |||
return; | return; | ||
break; | break; | ||
default: | default: | ||
break; | break; | ||
} | } | ||
mandoc_vmsg(MANDOCERR_FT_BAD, man->parse, | mandoc_msg(MANDOCERR_FT_BAD, n->line, n->pos, "ft %s", cp); | ||
n->line, n->pos, "ft %s", cp); | |||
roff_node_delete(man, n); | roff_node_delete(man, n); | ||
} | |||
static void | |||
roff_valid_sp(ROFF_VALID_ARGS) | |||
{ | |||
struct roff_node *np; | |||
if (n->child != NULL && n->child->next != NULL) | |||
mandoc_msg(MANDOCERR_ARG_EXCESS, | |||
n->child->next->line, n->child->next->pos, | |||
"sp ... %s", n->child->next->string); | |||
if ((np = n->prev) == NULL) | |||
return; | |||
switch (np->tok) { | |||
case ROFF_br: | |||
mandoc_msg(MANDOCERR_PAR_SKIP, | |||
np->line, np->pos, "br before sp"); | |||
roff_node_delete(man, np); | |||
break; | |||
case MDOC_Pp: | |||
mandoc_msg(MANDOCERR_PAR_SKIP, | |||
n->line, n->pos, "sp after Pp"); | |||
roff_node_delete(man, n); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | } |