summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2001-10-25 19:28:43 +0000
committerSimon Tatham <anakin@pobox.com>2001-10-25 19:28:43 +0000
commit3e043306f1594f7528788a1c593995b391fc7a5a (patch)
tree614dbae4b9d0b18ffaed645887e8243c21c809a7
parentdd9eaf09d344a4b18b2750cef08795a097891c08 (diff)
downloadhalibut-3e043306f1594f7528788a1c593995b391fc7a5a.zip
halibut-3e043306f1594f7528788a1c593995b391fc7a5a.tar.gz
halibut-3e043306f1594f7528788a1c593995b391fc7a5a.tar.bz2
halibut-3e043306f1594f7528788a1c593995b391fc7a5a.tar.xz
Enforce proper ordering of heading levels: specifically, ensure the
user doesn't skip a heading level (\H before any \C or \A, or \S straight after \C with no intervening \H). The precise criterion is that when creating section a.b.c.d, sections a.b.c, a.b and a should already exist. This ensures the section tree really is a properly formed tree with no missing nodes. [originally from svn r1329]
-rw-r--r--buttress.h3
-rw-r--r--contents.c11
-rw-r--r--error.c5
-rw-r--r--inputs/errors2.but5
-rw-r--r--keywords.c16
-rw-r--r--main.c2
6 files changed, 39 insertions, 3 deletions
diff --git a/buttress.h b/buttress.h
index b07cf0a..8f8961a 100644
--- a/buttress.h
+++ b/buttress.h
@@ -199,6 +199,7 @@ enum {
err_nosuchidxtag, /* \IM on unknown index tag (warning) */
err_cantopenw, /* can't open output file for write */
err_macroexists, /* this macro already exists */
+ err_sectjump, /* jump a heading level, eg \C -> \S */
err_whatever /* random error of another type */
};
@@ -374,7 +375,7 @@ void index_debug(index *);
*/
numberstate *number_init(void);
void number_cfg(numberstate *, paragraph *);
-word *number_mktext(numberstate *, int, int, int, word **);
+word *number_mktext(numberstate *, int, int, int, word **, filepos);
void number_free(numberstate *);
/*
diff --git a/contents.c b/contents.c
index fee45d9..7688d75 100644
--- a/contents.c
+++ b/contents.c
@@ -13,6 +13,7 @@ struct numberstate_Tag {
int appendixnum;
int ischapter;
int *sectionlevels;
+ int oklevel;
int maxsectlevel;
int listitem;
wchar_t *chaptertext; /* the word for a chapter */
@@ -25,6 +26,7 @@ numberstate *number_init(void) {
ret->chapternum = 0;
ret->appendixnum = -1;
ret->ischapter = 1;
+ ret->oklevel = -1; /* not even in a chapter yet */
ret->maxsectlevel = 32;
ret->sectionlevels = mknewa(int, ret->maxsectlevel);
ret->listitem = -1;
@@ -114,7 +116,7 @@ void number_cfg(numberstate *state, paragraph *source) {
}
word *number_mktext(numberstate *state, int para, int aux, int prev,
- word **auxret) {
+ word **auxret, filepos fpos) {
word *ret = NULL;
word **ret2 = &ret;
word **pret = &ret;
@@ -130,10 +132,16 @@ word *number_mktext(numberstate *state, int para, int aux, int prev,
ret2 = pret;
donumber(&pret, state->chapternum);
state->ischapter = 1;
+ state->oklevel = 0;
break;
case para_Heading:
case para_Subsect:
level = (para == para_Heading ? 0 : aux);
+ if (level > state->oklevel) {
+ error(err_sectjump, &fpos);
+ return NULL;
+ }
+ state->oklevel = level+1;
if (state->maxsectlevel <= level) {
state->maxsectlevel = level + 32;
state->sectionlevels = resize(state->sectionlevels,
@@ -165,6 +173,7 @@ word *number_mktext(numberstate *state, int para, int aux, int prev,
ret2 = pret;
doanumber(&pret, state->appendixnum);
state->ischapter = 0;
+ state->oklevel = 0;
break;
case para_NumberedList:
ret2 = pret;
diff --git a/error.c b/error.c
index b4a3898..c81aa8c 100644
--- a/error.c
+++ b/error.c
@@ -162,6 +162,11 @@ static void do_error(int code, va_list ap) {
sprintf(error, "macro `%.200s' already defined", sp);
flags = FILEPOS;
break;
+ case err_sectjump:
+ fpos = *va_arg(ap, filepos *);
+ sprintf(error, "expected higher heading levels before this one");
+ flags = FILEPOS;
+ break;
case err_whatever:
sp = va_arg(ap, char *);
vsprintf(error, sp, ap);
diff --git a/inputs/errors2.but b/inputs/errors2.but
new file mode 100644
index 0000000..b1a3303
--- /dev/null
+++ b/inputs/errors2.but
@@ -0,0 +1,5 @@
+\H{outofplace} Heading out of place.
+
+\C{chap} Chapter is fine
+
+\S{subsect} Subsection should have heading before it.
diff --git a/keywords.c b/keywords.c
index d0d0b4d..7dd35b1 100644
--- a/keywords.c
+++ b/keywords.c
@@ -86,6 +86,7 @@ keyword *kw_lookup(keywordlist *kl, wchar_t *str) {
* finish).
*/
keywordlist *get_keywords(paragraph *source) {
+ int errors = FALSE;
keywordlist *kl = mknew(keywordlist);
numberstate *n = number_init();
int prevpara = para_NotParaType;
@@ -102,7 +103,15 @@ keywordlist *get_keywords(paragraph *source) {
* Number the chapter / section / list-item / whatever.
*/
source->kwtext = number_mktext(n, source->type, source->aux,
- prevpara, &source->kwtext2);
+ prevpara, &source->kwtext2,
+ source->fpos);
+ if (!source->kwtext) {
+ /* There was an error collecting the section numbers.
+ * number_mktext has reported it; we record it and bail
+ * out at the end. */
+ errors = TRUE;
+ continue;
+ }
prevpara = source->type;
if (source->keyword && *source->keyword) {
@@ -128,6 +137,11 @@ keywordlist *get_keywords(paragraph *source) {
number_free(n);
+ if (errors) {
+ free_keywords(kl);
+ return NULL;
+ }
+
heap_sort(kl);
return kl;
diff --git a/main.c b/main.c
index 079aba8..b7be46f 100644
--- a/main.c
+++ b/main.c
@@ -197,6 +197,8 @@ int main(int argc, char **argv) {
sfree(infiles);
keywords = get_keywords(sourceform);
+ if (!keywords)
+ exit(EXIT_FAILURE);
gen_citations(sourceform, keywords);
subst_keywords(sourceform, keywords);