X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/blobdiff_plain/5b1d0032b0eb6f4a347c0c2cfdbe6e4bb4f959ab..2e78832ed88bc518b46e0b248d22da061bea46ed:/bk_info.c diff --git a/bk_info.c b/bk_info.c index 5c05817..5b82177 100644 --- a/bk_info.c +++ b/bk_info.c @@ -39,6 +39,7 @@ typedef struct { wchar_t *lquote, *rquote; wchar_t *sectsuffix, *underline; wchar_t *rule; + wchar_t *index_text; } infoconfig; typedef struct { @@ -84,7 +85,8 @@ static int info_check_index(word *, node *, indexdata *); static int info_rdaddwc(info_data *, word *, word *, int, infoconfig *); static node *info_node_new(char *name, int charset); -static char *info_node_name(paragraph *p, infoconfig *); +static char *info_node_name_for_para(paragraph *p, infoconfig *); +static char *info_node_name_for_text(wchar_t *text, infoconfig *); static infoconfig info_configure(paragraph *source) { infoconfig ret; @@ -110,6 +112,7 @@ static infoconfig info_configure(paragraph *source) { ret.rquote = uadv(ret.lquote); ret.sectsuffix = L": "; ret.underline = L"\x203E\0-\0\0"; + ret.index_text = L"Index"; /* * Two-pass configuration so that we can pick up global config @@ -124,6 +127,8 @@ static infoconfig info_configure(paragraph *source) { ret.lquote = uadv(p->keyword); ret.rquote = uadv(ret.lquote); } + } else if (!ustricmp(p->keyword, L"index")) { + ret.index_text = uadv(p->keyword); } } } @@ -134,9 +139,7 @@ static infoconfig info_configure(paragraph *source) { sfree(ret.filename); ret.filename = dupstr(adv(p->origkeyword)); } else if (!ustricmp(p->keyword, L"info-charset")) { - char *csname = utoa_dup(uadv(p->keyword), CS_ASCII); - ret.charset = charset_from_localenc(csname); - sfree(csname); + ret.charset = charset_from_ustr(&p->fpos, uadv(p->keyword)); } else if (!ustricmp(p->keyword, L"info-max-file-size")) { ret.maxfilesize = utoi(uadv(p->keyword)); } else if (!ustricmp(p->keyword, L"info-width")) { @@ -249,7 +252,7 @@ void info_backend(paragraph *sourceform, keywordlist *keywords, node *newnode, *upnode; char *nodename; - nodename = info_node_name(p, &conf); + nodename = info_node_name_for_para(p, &conf); newnode = info_node_new(nodename, conf.charset); sfree(nodename); @@ -269,6 +272,9 @@ void info_backend(paragraph *sourceform, keywordlist *keywords, currnode = newnode; } break; + default: + p->private_data = NULL; + break; } /* @@ -279,7 +285,7 @@ void info_backend(paragraph *sourceform, keywordlist *keywords, indexentry *entry; for (i = 0; (entry = index234(idx->entries, i)) != NULL; i++) { - info_idx *ii = mknew(info_idx); + info_idx *ii = snew(info_idx); info_data id = EMPTY_INFO_DATA; id.charset = conf.charset; @@ -315,12 +321,12 @@ void info_backend(paragraph *sourceform, keywordlist *keywords, char *s; section = uadv(p->keyword); - shortname = *section ? uadv(section) : NULL; - longname = *shortname ? uadv(shortname) : NULL; - kw = *longname ? uadv(longname) : NULL; + shortname = *section ? uadv(section) : L""; + longname = *shortname ? uadv(shortname) : L""; + kw = *longname ? uadv(longname) : L""; if (!*longname) { - error(err_infodirentry, &p->fpos); + error(err_cfginsufarg, &p->fpos, p->origkeyword, 3); continue; } @@ -494,15 +500,25 @@ void info_backend(paragraph *sourceform, keywordlist *keywords, node *newnode; int i, j, k; indexentry *entry; + char *nodename; + + nodename = info_node_name_for_text(conf.index_text, &conf); + newnode = info_node_new(nodename, conf.charset); + sfree(nodename); - newnode = info_node_new("Index", conf.charset); newnode->up = topnode; currnode->next = newnode; newnode->prev = currnode; currnode->listnext = newnode; - info_rdaddsc(&newnode->text, "Index\n-----\n\n"); + k = info_rdadds(&newnode->text, conf.index_text); + info_rdaddsc(&newnode->text, "\n"); + while (k > 0) { + info_rdadds(&newnode->text, conf.underline); + k -= ustrwid(conf.underline, conf.charset); + } + info_rdaddsc(&newnode->text, "\n\n"); info_menu_item(&topnode->text, newnode, NULL, &conf); @@ -631,7 +647,7 @@ void info_backend(paragraph *sourceform, keywordlist *keywords, if (fp) fclose(fp); - fname = mknewa(char, strlen(conf.filename) + 40); + fname = snewn(strlen(conf.filename) + 40, char); sprintf(fname, "%s-%d", conf.filename, filenum); fp = fopen(fname, "w"); if (!fp) { @@ -678,7 +694,7 @@ static int info_check_index(word *w, node *n, indexdata *idx) if (ii->nnodes >= ii->nodesize) { ii->nodesize += 32; - ii->nodes = resize(ii->nodes, ii->nodesize); + ii->nodes = sresize(ii->nodes, ii->nodesize, node *); } ii->nodes[ii->nnodes++] = n; @@ -708,7 +724,7 @@ static word *info_transform_wordlist(word *words, keywordlist *keywords) * In Info, we do nothing special for xrefs to * numbered list items or bibliography entries. */ - break; + continue; } else { /* * An xref to a different section has its text @@ -1024,7 +1040,7 @@ static node *info_node_new(char *name, int charset) { node *n; - n = mknew(node); + n = snew(node); n->text = empty_info_data; n->text.charset = charset; n->up = n->next = n->prev = n->lastchild = n->listnext = NULL; @@ -1034,32 +1050,49 @@ static node *info_node_new(char *name, int charset) return n; } -static char *info_node_name(paragraph *par, infoconfig *cfg) +static char *info_node_name_core(info_data *id, filepos *fpos) { - info_data id = EMPTY_INFO_DATA; char *p, *q; - id.charset = cfg->charset; - info_rdaddwc(&id, par->kwtext ? par->kwtext : par->words, - NULL, FALSE, cfg); - info_rdaddsc(&id, NULL); - /* - * We cannot have commas or colons in a node name. Remove any - * that we find, with a warning. + * We cannot have commas, colons or parentheses in a node name. + * Remove any that we find, with a warning. */ - p = q = id.output.text; + p = q = id->output.text; while (*p) { - if (*p == ':' || *p == ',') { - error(err_infonodechar, &par->fpos, *p); + if (*p == ':' || *p == ',' || *p == '(' || *p == ')') { + error(err_infonodechar, fpos, *p); } else { *q++ = *p; } p++; } - *p = '\0'; + *q = '\0'; + + return id->output.text; +} + +static char *info_node_name_for_para(paragraph *par, infoconfig *cfg) +{ + info_data id = EMPTY_INFO_DATA; + + id.charset = cfg->charset; + info_rdaddwc(&id, par->kwtext ? par->kwtext : par->words, + NULL, FALSE, cfg); + info_rdaddsc(&id, NULL); + + return info_node_name_core(&id, &par->fpos); +} + +static char *info_node_name_for_text(wchar_t *text, infoconfig *cfg) +{ + info_data id = EMPTY_INFO_DATA; + + id.charset = cfg->charset; + info_rdadds(&id, text); + info_rdaddsc(&id, NULL); - return id.output.text; + return info_node_name_core(&id, NULL); } static void info_menu_item(info_data *text, node *n, paragraph *p,