removed text and help file backends; added some usage crap and removed the help command line optin(who needs that)
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@1542 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
ef17957fff
commit
048c27836c
23 changed files with 7533 additions and 10037 deletions
Binary file not shown.
|
@ -1,5 +1,7 @@
|
||||||
Halibut is copyright (c) 1999-2001 Simon Tatham and James Aylett.
|
Halibut is copyright (c) 1999-2001 Simon Tatham and James Aylett.
|
||||||
|
|
||||||
|
Note: This version is modified by Robert Rainwater and Amir Szekely
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
Permission is hereby granted, free of charge, to any person
|
||||||
obtaining a copy of this software and associated documentation files
|
obtaining a copy of this software and associated documentation files
|
||||||
(the "Software"), to deal in the Software without restriction,
|
(the "Software"), to deal in the Software without restriction,
|
||||||
|
|
|
@ -5,15 +5,13 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "halibut.h"
|
#include "halibut.h"
|
||||||
|
|
||||||
static wchar_t *
|
static wchar_t *gentext(int num)
|
||||||
gentext (int num)
|
|
||||||
{
|
{
|
||||||
wchar_t text[22];
|
wchar_t text[22];
|
||||||
wchar_t *p = text + sizeof(text);
|
wchar_t *p = text + sizeof(text);
|
||||||
*--p = L'\0';
|
*--p = L'\0';
|
||||||
*--p = L']';
|
*--p = L']';
|
||||||
while (num != 0)
|
while (num != 0) {
|
||||||
{
|
|
||||||
assert(p > text);
|
assert(p > text);
|
||||||
*--p = L"0123456789"[num % 10];
|
*--p = L"0123456789"[num % 10];
|
||||||
num /= 10;
|
num /= 10;
|
||||||
|
@ -23,20 +21,17 @@ gentext (int num)
|
||||||
return ustrdup(p);
|
return ustrdup(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void cite_biblio(keywordlist * kl, wchar_t * key, filepos fpos)
|
||||||
cite_biblio (keywordlist * kl, wchar_t * key, filepos fpos)
|
|
||||||
{
|
{
|
||||||
keyword *kw = kw_lookup(kl, key);
|
keyword *kw = kw_lookup(kl, key);
|
||||||
if (!kw)
|
if (!kw)
|
||||||
error(err_nosuchkw, &fpos, key);
|
error(err_nosuchkw, &fpos, key);
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* We've found a \k reference. If it's a
|
* We've found a \k reference. If it's a
|
||||||
* bibliography entry ...
|
* bibliography entry ...
|
||||||
*/
|
*/
|
||||||
if (kw->para->type == para_Biblio)
|
if (kw->para->type == para_Biblio) {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* ... then mark the paragraph as cited.
|
* ... then mark the paragraph as cited.
|
||||||
*/
|
*/
|
||||||
|
@ -51,40 +46,29 @@ cite_biblio (keywordlist * kl, wchar_t * key, filepos fpos)
|
||||||
* entries are actually cited (or \nocite-ed).
|
* entries are actually cited (or \nocite-ed).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void gen_citations(paragraph * source, keywordlist * kl)
|
||||||
gen_citations (paragraph * source, keywordlist * kl)
|
|
||||||
{
|
{
|
||||||
paragraph *para;
|
paragraph *para;
|
||||||
int bibnum = 0;
|
int bibnum = 0;
|
||||||
|
|
||||||
for (para = source; para; para = para->next)
|
for (para = source; para; para = para->next) {
|
||||||
{
|
|
||||||
word *ptr;
|
word *ptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* \BR and \nocite paragraphs get special processing here.
|
* \BR and \nocite paragraphs get special processing here.
|
||||||
*/
|
*/
|
||||||
if (para->type == para_BR)
|
if (para->type == para_BR) {
|
||||||
{
|
|
||||||
keyword *kw = kw_lookup(kl, para->keyword);
|
keyword *kw = kw_lookup(kl, para->keyword);
|
||||||
if (!kw)
|
if (!kw) {
|
||||||
{
|
|
||||||
error(err_nosuchkw, ¶->fpos, para->keyword);
|
error(err_nosuchkw, ¶->fpos, para->keyword);
|
||||||
}
|
} else if (kw->text) {
|
||||||
else if (kw->text)
|
|
||||||
{
|
|
||||||
error(err_multiBR, ¶->fpos, para->keyword);
|
error(err_multiBR, ¶->fpos, para->keyword);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
kw->text = dup_word_list(para->words);
|
kw->text = dup_word_list(para->words);
|
||||||
}
|
}
|
||||||
}
|
} else if (para->type == para_NoCite) {
|
||||||
else if (para->type == para_NoCite)
|
|
||||||
{
|
|
||||||
wchar_t *wp = para->keyword;
|
wchar_t *wp = para->keyword;
|
||||||
while (*wp)
|
while (*wp) {
|
||||||
{
|
|
||||||
cite_biblio(kl, wp, para->fpos);
|
cite_biblio(kl, wp, para->fpos);
|
||||||
wp = uadv(wp);
|
wp = uadv(wp);
|
||||||
}
|
}
|
||||||
|
@ -93,8 +77,7 @@ gen_citations (paragraph * source, keywordlist * kl)
|
||||||
/*
|
/*
|
||||||
* Scan for keyword references.
|
* Scan for keyword references.
|
||||||
*/
|
*/
|
||||||
for (ptr = para->words; ptr; ptr = ptr->next)
|
for (ptr = para->words; ptr; ptr = ptr->next) {
|
||||||
{
|
|
||||||
if (ptr->type == word_UpperXref || ptr->type == word_LowerXref)
|
if (ptr->type == word_UpperXref || ptr->type == word_LowerXref)
|
||||||
cite_biblio(kl, ptr->text, ptr->fpos);
|
cite_biblio(kl, ptr->text, ptr->fpos);
|
||||||
}
|
}
|
||||||
|
@ -106,14 +89,11 @@ gen_citations (paragraph * source, keywordlist * kl)
|
||||||
* texts for the ones that don't already have explicitly
|
* texts for the ones that don't already have explicitly
|
||||||
* provided \BR text.
|
* provided \BR text.
|
||||||
*/
|
*/
|
||||||
for (para = source; para; para = para->next)
|
for (para = source; para; para = para->next) {
|
||||||
{
|
if (para->type == para_BiblioCited) {
|
||||||
if (para->type == para_BiblioCited)
|
|
||||||
{
|
|
||||||
keyword *kw = kw_lookup(kl, para->keyword);
|
keyword *kw = kw_lookup(kl, para->keyword);
|
||||||
assert(kw != NULL);
|
assert(kw != NULL);
|
||||||
if (!kw->text)
|
if (!kw->text) {
|
||||||
{
|
|
||||||
word *wd = smalloc(sizeof(word));
|
word *wd = smalloc(sizeof(word));
|
||||||
wd->text = gentext(++bibnum);
|
wd->text = gentext(++bibnum);
|
||||||
wd->type = word_Normal;
|
wd->type = word_Normal;
|
||||||
|
|
|
@ -1,751 +0,0 @@
|
||||||
/*
|
|
||||||
* text backend for Halibut
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "halibut.h"
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{ LEFT, LEFTPLUS, CENTRE }
|
|
||||||
alignment;
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
alignment align;
|
|
||||||
int just_numbers;
|
|
||||||
wchar_t underline;
|
|
||||||
wchar_t *number_suffix;
|
|
||||||
}
|
|
||||||
alignstruct;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int indent, indent_code;
|
|
||||||
int listindentbefore, listindentafter;
|
|
||||||
int width;
|
|
||||||
alignstruct atitle, achapter, *asect;
|
|
||||||
int nasect;
|
|
||||||
int include_version_id;
|
|
||||||
int indent_preambles;
|
|
||||||
word bullet;
|
|
||||||
}
|
|
||||||
textconfig;
|
|
||||||
|
|
||||||
static int text_convert (wchar_t *, char **);
|
|
||||||
|
|
||||||
static void text_heading (FILE *, word *, word *, word *, alignstruct, int,
|
|
||||||
int);
|
|
||||||
static void text_rule (FILE *, int, int);
|
|
||||||
static void text_para (FILE *, word *, char *, word *, int, int, int);
|
|
||||||
static void text_codepara (FILE *, word *, int, int);
|
|
||||||
static void text_versionid (FILE *, word *);
|
|
||||||
|
|
||||||
static alignment
|
|
||||||
utoalign (wchar_t * p)
|
|
||||||
{
|
|
||||||
if (!ustricmp (p, L"centre") || !ustricmp (p, L"center"))
|
|
||||||
return CENTRE;
|
|
||||||
if (!ustricmp (p, L"leftplus"))
|
|
||||||
return LEFTPLUS;
|
|
||||||
return LEFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static textconfig
|
|
||||||
text_configure (paragraph * source)
|
|
||||||
{
|
|
||||||
textconfig ret;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Non-negotiables.
|
|
||||||
*/
|
|
||||||
ret.bullet.next = NULL;
|
|
||||||
ret.bullet.alt = NULL;
|
|
||||||
ret.bullet.type = word_Normal;
|
|
||||||
ret.atitle.just_numbers = FALSE; /* ignored */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Defaults.
|
|
||||||
*/
|
|
||||||
ret.indent = 7;
|
|
||||||
ret.indent_code = 2;
|
|
||||||
ret.listindentbefore = 1;
|
|
||||||
ret.listindentafter = 3;
|
|
||||||
ret.width = 68;
|
|
||||||
ret.atitle.align = CENTRE;
|
|
||||||
ret.atitle.underline = L'=';
|
|
||||||
ret.achapter.align = LEFT;
|
|
||||||
ret.achapter.just_numbers = FALSE;
|
|
||||||
ret.achapter.number_suffix = ustrdup (L": ");
|
|
||||||
ret.achapter.underline = L'-';
|
|
||||||
ret.nasect = 1;
|
|
||||||
ret.asect = mknewa (alignstruct, ret.nasect);
|
|
||||||
ret.asect[0].align = LEFTPLUS;
|
|
||||||
ret.asect[0].just_numbers = TRUE;
|
|
||||||
ret.asect[0].number_suffix = ustrdup (L" ");
|
|
||||||
ret.asect[0].underline = L'\0';
|
|
||||||
ret.include_version_id = TRUE;
|
|
||||||
ret.indent_preambles = FALSE;
|
|
||||||
ret.bullet.text = ustrdup (L"-");
|
|
||||||
|
|
||||||
for (; source; source = source->next)
|
|
||||||
{
|
|
||||||
if (source->type == para_Config)
|
|
||||||
{
|
|
||||||
if (!ustricmp (source->keyword, L"text-indent"))
|
|
||||||
{
|
|
||||||
ret.indent = utoi (uadv (source->keyword));
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-indent-code"))
|
|
||||||
{
|
|
||||||
ret.indent_code = utoi (uadv (source->keyword));
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-width"))
|
|
||||||
{
|
|
||||||
ret.width = utoi (uadv (source->keyword));
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-list-indent"))
|
|
||||||
{
|
|
||||||
ret.listindentbefore = utoi (uadv (source->keyword));
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-listitem-indent"))
|
|
||||||
{
|
|
||||||
ret.listindentafter = utoi (uadv (source->keyword));
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-chapter-align"))
|
|
||||||
{
|
|
||||||
ret.achapter.align = utoalign (uadv (source->keyword));
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-chapter-underline"))
|
|
||||||
{
|
|
||||||
ret.achapter.underline = *uadv (source->keyword);
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-chapter-numeric"))
|
|
||||||
{
|
|
||||||
ret.achapter.just_numbers = utob (uadv (source->keyword));
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-chapter-suffix"))
|
|
||||||
{
|
|
||||||
ret.achapter.number_suffix = ustrdup (uadv (source->keyword));
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-section-align"))
|
|
||||||
{
|
|
||||||
wchar_t *p = uadv (source->keyword);
|
|
||||||
int n = 0;
|
|
||||||
if (uisdigit (*p))
|
|
||||||
{
|
|
||||||
n = utoi (p);
|
|
||||||
p = uadv (p);
|
|
||||||
}
|
|
||||||
if (n >= ret.nasect)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
ret.asect = resize (ret.asect, n + 1);
|
|
||||||
for (i = ret.nasect; i <= n; i++)
|
|
||||||
ret.asect[i] = ret.asect[ret.nasect - 1];
|
|
||||||
ret.nasect = n + 1;
|
|
||||||
}
|
|
||||||
ret.asect[n].align = utoalign (p);
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-section-underline"))
|
|
||||||
{
|
|
||||||
wchar_t *p = uadv (source->keyword);
|
|
||||||
int n = 0;
|
|
||||||
if (uisdigit (*p))
|
|
||||||
{
|
|
||||||
n = utoi (p);
|
|
||||||
p = uadv (p);
|
|
||||||
}
|
|
||||||
if (n >= ret.nasect)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
ret.asect = resize (ret.asect, n + 1);
|
|
||||||
for (i = ret.nasect; i <= n; i++)
|
|
||||||
ret.asect[i] = ret.asect[ret.nasect - 1];
|
|
||||||
ret.nasect = n + 1;
|
|
||||||
}
|
|
||||||
ret.asect[n].underline = *p;
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-section-numeric"))
|
|
||||||
{
|
|
||||||
wchar_t *p = uadv (source->keyword);
|
|
||||||
int n = 0;
|
|
||||||
if (uisdigit (*p))
|
|
||||||
{
|
|
||||||
n = utoi (p);
|
|
||||||
p = uadv (p);
|
|
||||||
}
|
|
||||||
if (n >= ret.nasect)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
ret.asect = resize (ret.asect, n + 1);
|
|
||||||
for (i = ret.nasect; i <= n; i++)
|
|
||||||
ret.asect[i] = ret.asect[ret.nasect - 1];
|
|
||||||
ret.nasect = n + 1;
|
|
||||||
}
|
|
||||||
ret.asect[n].just_numbers = utob (p);
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-section-suffix"))
|
|
||||||
{
|
|
||||||
wchar_t *p = uadv (source->keyword);
|
|
||||||
int n = 0;
|
|
||||||
if (uisdigit (*p))
|
|
||||||
{
|
|
||||||
n = utoi (p);
|
|
||||||
p = uadv (p);
|
|
||||||
}
|
|
||||||
if (n >= ret.nasect)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
ret.asect = resize (ret.asect, n + 1);
|
|
||||||
for (i = ret.nasect; i <= n; i++)
|
|
||||||
ret.asect[i] = ret.asect[ret.nasect - 1];
|
|
||||||
ret.nasect = n + 1;
|
|
||||||
}
|
|
||||||
ret.asect[n].number_suffix = ustrdup (p);
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-title-align"))
|
|
||||||
{
|
|
||||||
ret.atitle.align = utoalign (uadv (source->keyword));
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-title-underline"))
|
|
||||||
{
|
|
||||||
ret.atitle.underline = *uadv (source->keyword);
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-versionid"))
|
|
||||||
{
|
|
||||||
ret.include_version_id = utob (uadv (source->keyword));
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-indent-preamble"))
|
|
||||||
{
|
|
||||||
ret.indent_preambles = utob (uadv (source->keyword));
|
|
||||||
}
|
|
||||||
else if (!ustricmp (source->keyword, L"text-bullet"))
|
|
||||||
{
|
|
||||||
ret.bullet.text = uadv (source->keyword);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
text_backend (paragraph * sourceform, keywordlist * keywords, indexdata * idx)
|
|
||||||
{
|
|
||||||
paragraph *p;
|
|
||||||
textconfig conf;
|
|
||||||
word *prefix, *body, *wp;
|
|
||||||
word spaceword;
|
|
||||||
FILE *fp;
|
|
||||||
char *prefixextra;
|
|
||||||
int indentb, indenta;
|
|
||||||
|
|
||||||
IGNORE (keywords); /* we don't happen to need this */
|
|
||||||
IGNORE (idx); /* or this */
|
|
||||||
|
|
||||||
conf = text_configure (sourceform);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine the output file name, and open the output file
|
|
||||||
*
|
|
||||||
* FIXME: want configurable output file names here. For the
|
|
||||||
* moment, we'll just call it `output.txt'.
|
|
||||||
*/
|
|
||||||
fp = fopen ("output.txt", "w");
|
|
||||||
if (!fp)
|
|
||||||
{
|
|
||||||
error (err_cantopenw, "output.txt");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do the title */
|
|
||||||
for (p = sourceform; p; p = p->next)
|
|
||||||
if (p->type == para_Title)
|
|
||||||
text_heading (fp, NULL, NULL, p->words,
|
|
||||||
conf.atitle, conf.indent, conf.width);
|
|
||||||
|
|
||||||
/* Do the preamble and copyright */
|
|
||||||
for (p = sourceform; p; p = p->next)
|
|
||||||
if (p->type == para_Preamble)
|
|
||||||
text_para (fp, NULL, NULL, p->words,
|
|
||||||
conf.indent_preambles ? conf.indent : 0, 0,
|
|
||||||
conf.width + (conf.indent_preambles ? 0 : conf.indent));
|
|
||||||
for (p = sourceform; p; p = p->next)
|
|
||||||
if (p->type == para_Copyright)
|
|
||||||
text_para (fp, NULL, NULL, p->words,
|
|
||||||
conf.indent_preambles ? conf.indent : 0, 0,
|
|
||||||
conf.width + (conf.indent_preambles ? 0 : conf.indent));
|
|
||||||
|
|
||||||
/* Do the main document */
|
|
||||||
for (p = sourceform; p; p = p->next)
|
|
||||||
switch (p->type)
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Things we ignore because we've already processed them or
|
|
||||||
* aren't going to touch them in this pass.
|
|
||||||
*/
|
|
||||||
case para_IM:
|
|
||||||
case para_BR:
|
|
||||||
case para_Biblio: /* only touch BiblioCited */
|
|
||||||
case para_VersionID:
|
|
||||||
case para_Copyright:
|
|
||||||
case para_Preamble:
|
|
||||||
case para_NoCite:
|
|
||||||
case para_Title:
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Chapter titles.
|
|
||||||
*/
|
|
||||||
case para_Chapter:
|
|
||||||
case para_Appendix:
|
|
||||||
case para_UnnumberedChapter:
|
|
||||||
text_heading (fp, p->kwtext, p->kwtext2, p->words,
|
|
||||||
conf.achapter, conf.indent, conf.width);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case para_Heading:
|
|
||||||
case para_Subsect:
|
|
||||||
text_heading (fp, p->kwtext, p->kwtext2, p->words,
|
|
||||||
conf.asect[p->aux >=
|
|
||||||
conf.nasect ? conf.nasect - 1 : p->aux],
|
|
||||||
conf.indent, conf.width);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case para_Rule:
|
|
||||||
text_rule (fp, conf.indent, conf.width);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case para_Normal:
|
|
||||||
case para_BiblioCited:
|
|
||||||
case para_Bullet:
|
|
||||||
case para_NumberedList:
|
|
||||||
if (p->type == para_Bullet)
|
|
||||||
{
|
|
||||||
prefix = &conf.bullet;
|
|
||||||
prefixextra = NULL;
|
|
||||||
indentb = conf.listindentbefore;
|
|
||||||
indenta = conf.listindentafter;
|
|
||||||
}
|
|
||||||
else if (p->type == para_NumberedList)
|
|
||||||
{
|
|
||||||
prefix = p->kwtext;
|
|
||||||
prefixextra = "."; /* FIXME: configurability */
|
|
||||||
indentb = conf.listindentbefore;
|
|
||||||
indenta = conf.listindentafter;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prefix = NULL;
|
|
||||||
prefixextra = NULL;
|
|
||||||
indentb = indenta = 0;
|
|
||||||
}
|
|
||||||
if (p->type == para_BiblioCited)
|
|
||||||
{
|
|
||||||
body = dup_word_list (p->kwtext);
|
|
||||||
for (wp = body; wp->next; wp = wp->next);
|
|
||||||
wp->next = &spaceword;
|
|
||||||
spaceword.next = p->words;
|
|
||||||
spaceword.alt = NULL;
|
|
||||||
spaceword.type = word_WhiteSpace;
|
|
||||||
spaceword.text = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wp = NULL;
|
|
||||||
body = p->words;
|
|
||||||
}
|
|
||||||
text_para (fp, prefix, prefixextra, body,
|
|
||||||
conf.indent + indentb, indenta,
|
|
||||||
conf.width - indentb - indenta);
|
|
||||||
if (wp)
|
|
||||||
{
|
|
||||||
wp->next = NULL;
|
|
||||||
free_word_list (body);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case para_Code:
|
|
||||||
text_codepara (fp, p->words, conf.indent + conf.indent_code,
|
|
||||||
conf.width - 2 * conf.indent_code);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do the version ID */
|
|
||||||
if (conf.include_version_id)
|
|
||||||
{
|
|
||||||
for (p = sourceform; p; p = p->next)
|
|
||||||
if (p->type == para_VersionID)
|
|
||||||
text_versionid (fp, p->words);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tidy up
|
|
||||||
*/
|
|
||||||
fclose (fp);
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
sfree (conf.achapter.number_suffix);
|
|
||||||
for (i = 0; i < conf.nasect; i++)
|
|
||||||
sfree (conf.asect[i].number_suffix);
|
|
||||||
sfree (conf.asect);
|
|
||||||
sfree (conf.bullet.text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert a wide string into a string of chars. If `result' is
|
|
||||||
* non-NULL, mallocs the resulting string and stores a pointer to
|
|
||||||
* it in `*result'. If `result' is NULL, merely checks whether all
|
|
||||||
* characters in the string are feasible for the output character
|
|
||||||
* set.
|
|
||||||
*
|
|
||||||
* Return is nonzero if all characters are OK. If not all
|
|
||||||
* characters are OK but `result' is non-NULL, a result _will_
|
|
||||||
* still be generated!
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
text_convert (wchar_t * s, char **result)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* FIXME. Currently this is ISO8859-1 only.
|
|
||||||
*/
|
|
||||||
int doing = (result != 0);
|
|
||||||
int ok = TRUE;
|
|
||||||
char *p = NULL;
|
|
||||||
int plen = 0, psize = 0;
|
|
||||||
|
|
||||||
for (; *s; s++)
|
|
||||||
{
|
|
||||||
wchar_t c = *s;
|
|
||||||
char outc;
|
|
||||||
|
|
||||||
if ((c >= 32 && c <= 126) || (c >= 160 && c <= 255))
|
|
||||||
{
|
|
||||||
/* Char is OK. */
|
|
||||||
outc = (char) c;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Char is not OK. */
|
|
||||||
ok = FALSE;
|
|
||||||
outc = 0xBF; /* approximate the good old DEC `uh?' */
|
|
||||||
}
|
|
||||||
if (doing)
|
|
||||||
{
|
|
||||||
if (plen >= psize)
|
|
||||||
{
|
|
||||||
psize = plen + 256;
|
|
||||||
p = resize (p, psize);
|
|
||||||
}
|
|
||||||
p[plen++] = outc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (doing)
|
|
||||||
{
|
|
||||||
p = resize (p, plen + 1);
|
|
||||||
p[plen] = '\0';
|
|
||||||
*result = p;
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
text_rdaddwc (rdstringc * rs, word * text, word * end)
|
|
||||||
{
|
|
||||||
char *c;
|
|
||||||
|
|
||||||
for (; text && text != end; text = text->next)
|
|
||||||
switch (text->type)
|
|
||||||
{
|
|
||||||
case word_HyperLink:
|
|
||||||
case word_HyperEnd:
|
|
||||||
case word_UpperXref:
|
|
||||||
case word_LowerXref:
|
|
||||||
case word_XrefEnd:
|
|
||||||
case word_IndexRef:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case word_Normal:
|
|
||||||
case word_Emph:
|
|
||||||
case word_Code:
|
|
||||||
case word_WeakCode:
|
|
||||||
case word_WhiteSpace:
|
|
||||||
case word_EmphSpace:
|
|
||||||
case word_CodeSpace:
|
|
||||||
case word_WkCodeSpace:
|
|
||||||
case word_Quote:
|
|
||||||
case word_EmphQuote:
|
|
||||||
case word_CodeQuote:
|
|
||||||
case word_WkCodeQuote:
|
|
||||||
assert (text->type != word_CodeQuote &&
|
|
||||||
text->type != word_WkCodeQuote);
|
|
||||||
if (towordstyle (text->type) == word_Emph &&
|
|
||||||
(attraux (text->aux) == attr_First ||
|
|
||||||
attraux (text->aux) == attr_Only))
|
|
||||||
rdaddc (rs, '_'); /* FIXME: configurability */
|
|
||||||
else if (towordstyle (text->type) == word_Code &&
|
|
||||||
(attraux (text->aux) == attr_First ||
|
|
||||||
attraux (text->aux) == attr_Only))
|
|
||||||
rdaddc (rs, '`'); /* FIXME: configurability */
|
|
||||||
if (removeattr (text->type) == word_Normal)
|
|
||||||
{
|
|
||||||
if (text_convert (text->text, &c))
|
|
||||||
rdaddsc (rs, c);
|
|
||||||
else
|
|
||||||
text_rdaddwc (rs, text->alt, NULL);
|
|
||||||
sfree (c);
|
|
||||||
}
|
|
||||||
else if (removeattr (text->type) == word_WhiteSpace)
|
|
||||||
{
|
|
||||||
rdaddc (rs, ' ');
|
|
||||||
}
|
|
||||||
else if (removeattr (text->type) == word_Quote)
|
|
||||||
{
|
|
||||||
rdaddc (rs, quoteaux (text->aux) == quote_Open ? '`' : '\'');
|
|
||||||
/* FIXME: configurability */
|
|
||||||
}
|
|
||||||
if (towordstyle (text->type) == word_Emph &&
|
|
||||||
(attraux (text->aux) == attr_Last ||
|
|
||||||
attraux (text->aux) == attr_Only))
|
|
||||||
rdaddc (rs, '_'); /* FIXME: configurability */
|
|
||||||
else if (towordstyle (text->type) == word_Code &&
|
|
||||||
(attraux (text->aux) == attr_Last ||
|
|
||||||
attraux (text->aux) == attr_Only))
|
|
||||||
rdaddc (rs, '\''); /* FIXME: configurability */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int text_width (word *);
|
|
||||||
|
|
||||||
static int
|
|
||||||
text_width_list (word * text)
|
|
||||||
{
|
|
||||||
int w = 0;
|
|
||||||
while (text)
|
|
||||||
{
|
|
||||||
w += text_width (text);
|
|
||||||
text = text->next;
|
|
||||||
}
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
text_width (word * text)
|
|
||||||
{
|
|
||||||
switch (text->type)
|
|
||||||
{
|
|
||||||
case word_HyperLink:
|
|
||||||
case word_HyperEnd:
|
|
||||||
case word_UpperXref:
|
|
||||||
case word_LowerXref:
|
|
||||||
case word_XrefEnd:
|
|
||||||
case word_IndexRef:
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case word_Normal:
|
|
||||||
case word_Emph:
|
|
||||||
case word_Code:
|
|
||||||
case word_WeakCode:
|
|
||||||
return (((text->type == word_Emph ||
|
|
||||||
text->type == word_Code)
|
|
||||||
? (attraux (text->aux) == attr_Only ? 2 :
|
|
||||||
attraux (text->aux) == attr_Always ? 0 : 1)
|
|
||||||
: 0) +
|
|
||||||
(text_convert (text->text, NULL) ?
|
|
||||||
ustrlen (text->text) : text_width_list (text->alt)));
|
|
||||||
|
|
||||||
case word_WhiteSpace:
|
|
||||||
case word_EmphSpace:
|
|
||||||
case word_CodeSpace:
|
|
||||||
case word_WkCodeSpace:
|
|
||||||
case word_Quote:
|
|
||||||
case word_EmphQuote:
|
|
||||||
case word_CodeQuote:
|
|
||||||
case word_WkCodeQuote:
|
|
||||||
assert (text->type != word_CodeQuote && text->type != word_WkCodeQuote);
|
|
||||||
return (((towordstyle (text->type) == word_Emph ||
|
|
||||||
towordstyle (text->type) == word_Code)
|
|
||||||
? (attraux (text->aux) == attr_Only ? 2 :
|
|
||||||
attraux (text->aux) == attr_Always ? 0 : 1) : 0) + 1);
|
|
||||||
}
|
|
||||||
return 0; /* should never happen */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
text_heading (FILE * fp, word * tprefix, word * nprefix, word * text,
|
|
||||||
alignstruct align, int indent, int width)
|
|
||||||
{
|
|
||||||
rdstringc t = { 0, 0, NULL };
|
|
||||||
int margin, length;
|
|
||||||
int firstlinewidth, wrapwidth;
|
|
||||||
wrappedline *wrapping, *p;
|
|
||||||
|
|
||||||
if (align.just_numbers && nprefix)
|
|
||||||
{
|
|
||||||
char *c;
|
|
||||||
text_rdaddwc (&t, nprefix, NULL);
|
|
||||||
if (text_convert (align.number_suffix, &c))
|
|
||||||
{
|
|
||||||
rdaddsc (&t, c);
|
|
||||||
sfree (c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!align.just_numbers && tprefix)
|
|
||||||
{
|
|
||||||
char *c;
|
|
||||||
text_rdaddwc (&t, tprefix, NULL);
|
|
||||||
if (text_convert (align.number_suffix, &c))
|
|
||||||
{
|
|
||||||
rdaddsc (&t, c);
|
|
||||||
sfree (c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
margin = length = (t.text ? strlen (t.text) : 0);
|
|
||||||
|
|
||||||
if (align.align == LEFTPLUS)
|
|
||||||
{
|
|
||||||
margin = indent - margin;
|
|
||||||
if (margin < 0)
|
|
||||||
margin = 0;
|
|
||||||
firstlinewidth = indent + width - margin - length;
|
|
||||||
wrapwidth = width;
|
|
||||||
}
|
|
||||||
else if (align.align == LEFT || align.align == CENTRE)
|
|
||||||
{
|
|
||||||
margin = 0;
|
|
||||||
firstlinewidth = indent + width - length;
|
|
||||||
wrapwidth = indent + width;
|
|
||||||
}
|
|
||||||
|
|
||||||
wrapping = wrap_para (text, firstlinewidth, wrapwidth, text_width);
|
|
||||||
for (p = wrapping; p; p = p->next)
|
|
||||||
{
|
|
||||||
text_rdaddwc (&t, p->begin, p->end);
|
|
||||||
length = (t.text ? strlen (t.text) : 0);
|
|
||||||
if (align.align == CENTRE)
|
|
||||||
{
|
|
||||||
margin = (indent + width - length) / 2;
|
|
||||||
if (margin < 0)
|
|
||||||
margin = 0;
|
|
||||||
}
|
|
||||||
fprintf (fp, "%*s%s\n", margin, "", t.text);
|
|
||||||
if (align.underline != L'\0')
|
|
||||||
{
|
|
||||||
char *u, uc;
|
|
||||||
wchar_t uw[2];
|
|
||||||
uw[0] = align.underline;
|
|
||||||
uw[1] = L'\0';
|
|
||||||
text_convert (uw, &u);
|
|
||||||
uc = u[0];
|
|
||||||
sfree (u);
|
|
||||||
fprintf (fp, "%*s", margin, "");
|
|
||||||
while (length--)
|
|
||||||
putc (uc, fp);
|
|
||||||
putc ('\n', fp);
|
|
||||||
}
|
|
||||||
if (align.align == LEFTPLUS)
|
|
||||||
margin = indent;
|
|
||||||
else
|
|
||||||
margin = 0;
|
|
||||||
sfree (t.text);
|
|
||||||
t = empty_rdstringc;
|
|
||||||
}
|
|
||||||
wrap_free (wrapping);
|
|
||||||
putc ('\n', fp);
|
|
||||||
|
|
||||||
sfree (t.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
text_rule (FILE * fp, int indent, int width)
|
|
||||||
{
|
|
||||||
while (indent--)
|
|
||||||
putc (' ', fp);
|
|
||||||
while (width--)
|
|
||||||
putc ('-', fp); /* FIXME: configurability! */
|
|
||||||
putc ('\n', fp);
|
|
||||||
putc ('\n', fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
text_para (FILE * fp, word * prefix, char *prefixextra, word * text,
|
|
||||||
int indent, int extraindent, int width)
|
|
||||||
{
|
|
||||||
wrappedline *wrapping, *p;
|
|
||||||
rdstringc pfx = { 0, 0, NULL };
|
|
||||||
int e;
|
|
||||||
int firstlinewidth = width;
|
|
||||||
|
|
||||||
if (prefix)
|
|
||||||
{
|
|
||||||
text_rdaddwc (&pfx, prefix, NULL);
|
|
||||||
if (prefixextra)
|
|
||||||
rdaddsc (&pfx, prefixextra);
|
|
||||||
fprintf (fp, "%*s%s", indent, "", pfx.text);
|
|
||||||
/* If the prefix is too long, shorten the first line to fit. */
|
|
||||||
e = extraindent - strlen (pfx.text);
|
|
||||||
if (e < 0)
|
|
||||||
{
|
|
||||||
firstlinewidth += e; /* this decreases it, since e < 0 */
|
|
||||||
if (firstlinewidth < 0)
|
|
||||||
{
|
|
||||||
e = indent + extraindent;
|
|
||||||
firstlinewidth = width;
|
|
||||||
fprintf (fp, "\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
e = 0;
|
|
||||||
}
|
|
||||||
sfree (pfx.text);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
e = indent + extraindent;
|
|
||||||
|
|
||||||
wrapping = wrap_para (text, firstlinewidth, width, text_width);
|
|
||||||
for (p = wrapping; p; p = p->next)
|
|
||||||
{
|
|
||||||
rdstringc t = { 0, 0, NULL };
|
|
||||||
text_rdaddwc (&t, p->begin, p->end);
|
|
||||||
fprintf (fp, "%*s%s\n", e, "", t.text);
|
|
||||||
e = indent + extraindent;
|
|
||||||
sfree (t.text);
|
|
||||||
}
|
|
||||||
wrap_free (wrapping);
|
|
||||||
putc ('\n', fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
text_codepara (FILE * fp, word * text, int indent, int width)
|
|
||||||
{
|
|
||||||
for (; text; text = text->next)
|
|
||||||
if (text->type == word_WeakCode)
|
|
||||||
{
|
|
||||||
char *c;
|
|
||||||
text_convert (text->text, &c);
|
|
||||||
if (strlen (c) > (size_t) width)
|
|
||||||
{
|
|
||||||
/* FIXME: warn */
|
|
||||||
}
|
|
||||||
fprintf (fp, "%*s%s\n", indent, "", c);
|
|
||||||
sfree (c);
|
|
||||||
}
|
|
||||||
|
|
||||||
putc ('\n', fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
text_versionid (FILE * fp, word * text)
|
|
||||||
{
|
|
||||||
rdstringc t = { 0, 0, NULL };
|
|
||||||
|
|
||||||
rdaddc (&t, '['); /* FIXME: configurability */
|
|
||||||
text_rdaddwc (&t, text, NULL);
|
|
||||||
rdaddc (&t, ']'); /* FIXME: configurability */
|
|
||||||
|
|
||||||
fprintf (fp, "%s\n", t.text);
|
|
||||||
sfree (t.text);
|
|
||||||
}
|
|
|
@ -1,711 +0,0 @@
|
||||||
/*
|
|
||||||
* Windows Help backend for Halibut
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* - allow user to specify section contexts.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "halibut.h"
|
|
||||||
#include "winhelp.h"
|
|
||||||
|
|
||||||
struct bk_whlp_state
|
|
||||||
{
|
|
||||||
WHLP h;
|
|
||||||
indexdata *idx;
|
|
||||||
keywordlist *keywords;
|
|
||||||
WHLP_TOPIC curr_topic;
|
|
||||||
FILE *cntfp;
|
|
||||||
int cnt_last_level, cnt_workaround;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Indexes of fonts in our standard font descriptor set.
|
|
||||||
*/
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
FONT_NORMAL,
|
|
||||||
FONT_EMPH,
|
|
||||||
FONT_CODE,
|
|
||||||
FONT_TITLE,
|
|
||||||
FONT_TITLE_EMPH,
|
|
||||||
FONT_TITLE_CODE,
|
|
||||||
FONT_RULE
|
|
||||||
};
|
|
||||||
|
|
||||||
static void whlp_rdaddwc (rdstringc * rs, word * text);
|
|
||||||
static int whlp_convert (wchar_t * s, char **result, int hard_spaces);
|
|
||||||
static void whlp_mkparagraph (struct bk_whlp_state *state,
|
|
||||||
int font, word * text, int subsidiary);
|
|
||||||
static void whlp_navmenu (struct bk_whlp_state *state, paragraph * p);
|
|
||||||
static void whlp_contents_write (struct bk_whlp_state *state,
|
|
||||||
int level, char *text, WHLP_TOPIC topic);
|
|
||||||
|
|
||||||
void
|
|
||||||
whlp_backend (paragraph * sourceform, keywordlist * keywords, indexdata * idx)
|
|
||||||
{
|
|
||||||
WHLP h;
|
|
||||||
char *filename, *cntname;
|
|
||||||
paragraph *p, *lastsect;
|
|
||||||
struct bk_whlp_state state;
|
|
||||||
WHLP_TOPIC contents_topic;
|
|
||||||
int i;
|
|
||||||
indexentry *ie;
|
|
||||||
|
|
||||||
filename = "output.hlp"; /* FIXME: configurability */
|
|
||||||
cntname = "output.cnt"; /* corresponding contents file */
|
|
||||||
|
|
||||||
state.cntfp = fopen (cntname, "wb");
|
|
||||||
state.cnt_last_level = -1;
|
|
||||||
state.cnt_workaround = 0;
|
|
||||||
|
|
||||||
h = state.h = whlp_new ();
|
|
||||||
state.keywords = keywords;
|
|
||||||
state.idx = idx;
|
|
||||||
|
|
||||||
whlp_start_macro (h, "CB(\"btn_about\",\"&About\",\"About()\")");
|
|
||||||
whlp_start_macro (h, "CB(\"btn_up\",\"&Up\",\"Contents()\")");
|
|
||||||
whlp_start_macro (h, "BrowseButtons()");
|
|
||||||
|
|
||||||
whlp_create_font (h, "Times New Roman", WHLP_FONTFAM_SERIF, 24, 0, 0, 0, 0);
|
|
||||||
whlp_create_font (h, "Times New Roman", WHLP_FONTFAM_SERIF, 24,
|
|
||||||
WHLP_FONT_ITALIC, 0, 0, 0);
|
|
||||||
whlp_create_font (h, "Courier New", WHLP_FONTFAM_FIXED, 24, 0, 0, 0, 0);
|
|
||||||
whlp_create_font (h, "Arial", WHLP_FONTFAM_SERIF, 30,
|
|
||||||
WHLP_FONT_BOLD, 0, 0, 0);
|
|
||||||
whlp_create_font (h, "Arial", WHLP_FONTFAM_SERIF, 30,
|
|
||||||
WHLP_FONT_BOLD | WHLP_FONT_ITALIC, 0, 0, 0);
|
|
||||||
whlp_create_font (h, "Courier New", WHLP_FONTFAM_FIXED, 30,
|
|
||||||
WHLP_FONT_BOLD, 0, 0, 0);
|
|
||||||
whlp_create_font (h, "Courier New", WHLP_FONTFAM_SANS, 18,
|
|
||||||
WHLP_FONT_STRIKEOUT, 0, 0, 0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Loop over the source form finding out whether the user has
|
|
||||||
* specified particular help topic names for anything.
|
|
||||||
*/
|
|
||||||
for (p = sourceform; p; p = p->next)
|
|
||||||
{
|
|
||||||
p->private_data = NULL;
|
|
||||||
if (p->type == para_Config && p->parent)
|
|
||||||
{
|
|
||||||
if (!ustricmp (p->keyword, L"winhelp-topic"))
|
|
||||||
{
|
|
||||||
char *topicname;
|
|
||||||
whlp_convert (uadv (p->keyword), &topicname, 0);
|
|
||||||
/* Store the topic name in the private_data field of the
|
|
||||||
* containing section. */
|
|
||||||
p->parent->private_data = topicname;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Loop over the source form registering WHLP_TOPICs for
|
|
||||||
* everything.
|
|
||||||
*/
|
|
||||||
|
|
||||||
contents_topic = whlp_register_topic (h, "Top", NULL);
|
|
||||||
whlp_primary_topic (h, contents_topic);
|
|
||||||
for (p = sourceform; p; p = p->next)
|
|
||||||
{
|
|
||||||
if (p->type == para_Chapter ||
|
|
||||||
p->type == para_Appendix ||
|
|
||||||
p->type == para_UnnumberedChapter ||
|
|
||||||
p->type == para_Heading || p->type == para_Subsect)
|
|
||||||
{
|
|
||||||
char *topicid = p->private_data;
|
|
||||||
char *errstr;
|
|
||||||
|
|
||||||
p->private_data = whlp_register_topic (h, topicid, &errstr);
|
|
||||||
if (!p->private_data)
|
|
||||||
{
|
|
||||||
p->private_data = whlp_register_topic (h, NULL, NULL);
|
|
||||||
error (err_winhelp_ctxclash, &p->fpos, topicid, errstr);
|
|
||||||
}
|
|
||||||
sfree (topicid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Loop over the index entries, preparing final text forms for
|
|
||||||
* each one.
|
|
||||||
*/
|
|
||||||
for (i = 0; (ie = index234 (idx->entries, i)) != NULL; i++)
|
|
||||||
{
|
|
||||||
rdstringc rs = { 0, 0, NULL };
|
|
||||||
whlp_rdaddwc (&rs, ie->text);
|
|
||||||
ie->backend_data = rs.text;
|
|
||||||
}
|
|
||||||
|
|
||||||
whlp_prepare (h);
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------
|
|
||||||
* Do the contents page, containing title, preamble and
|
|
||||||
* copyright.
|
|
||||||
*/
|
|
||||||
|
|
||||||
whlp_begin_topic (h, contents_topic, "Contents", "DB(\"btn_up\")", NULL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The manual title goes in the non-scroll region, and also
|
|
||||||
* goes into the system title slot.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
rdstringc rs = { 0, 0, NULL };
|
|
||||||
for (p = sourceform; p; p = p->next)
|
|
||||||
{
|
|
||||||
if (p->type == para_Title)
|
|
||||||
{
|
|
||||||
whlp_begin_para (h, WHLP_PARA_NONSCROLL);
|
|
||||||
whlp_mkparagraph (&state, FONT_TITLE, p->words, FALSE);
|
|
||||||
whlp_rdaddwc (&rs, p->words);
|
|
||||||
whlp_end_para (h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rs.text)
|
|
||||||
{
|
|
||||||
whlp_title (h, rs.text);
|
|
||||||
fprintf (state.cntfp, ":Title %s\r\n", rs.text);
|
|
||||||
sfree (rs.text);
|
|
||||||
}
|
|
||||||
whlp_contents_write (&state, 1, "Title page", contents_topic);
|
|
||||||
/* FIXME: configurability in that string */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Next comes the preamble, which just goes into the ordinary
|
|
||||||
* scrolling region.
|
|
||||||
*/
|
|
||||||
for (p = sourceform; p; p = p->next)
|
|
||||||
{
|
|
||||||
if (p->type == para_Preamble)
|
|
||||||
{
|
|
||||||
whlp_para_attr (h, WHLP_PARA_SPACEBELOW, 12);
|
|
||||||
whlp_begin_para (h, WHLP_PARA_SCROLL);
|
|
||||||
whlp_mkparagraph (&state, FONT_NORMAL, p->words, FALSE);
|
|
||||||
whlp_end_para (h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The copyright goes to two places, again: into the contents
|
|
||||||
* page and also into the system section.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
rdstringc rs = { 0, 0, NULL };
|
|
||||||
for (p = sourceform; p; p = p->next)
|
|
||||||
{
|
|
||||||
if (p->type == para_Copyright)
|
|
||||||
{
|
|
||||||
whlp_para_attr (h, WHLP_PARA_SPACEBELOW, 12);
|
|
||||||
whlp_begin_para (h, WHLP_PARA_SCROLL);
|
|
||||||
whlp_mkparagraph (&state, FONT_NORMAL, p->words, FALSE);
|
|
||||||
whlp_end_para (h);
|
|
||||||
whlp_rdaddwc (&rs, p->words);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rs.text)
|
|
||||||
{
|
|
||||||
whlp_copyright (h, rs.text);
|
|
||||||
sfree (rs.text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now do the primary navigation menu.
|
|
||||||
*/
|
|
||||||
for (p = sourceform; p; p = p->next)
|
|
||||||
{
|
|
||||||
if (p->type == para_Chapter ||
|
|
||||||
p->type == para_Appendix || p->type == para_UnnumberedChapter)
|
|
||||||
whlp_navmenu (&state, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
state.curr_topic = contents_topic;
|
|
||||||
lastsect = NULL;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------
|
|
||||||
* Now we've done the contents page, we're ready to go through
|
|
||||||
* and do the main manual text. Ooh.
|
|
||||||
*/
|
|
||||||
for (p = sourceform; p; p = p->next)
|
|
||||||
switch (p->type)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Things we ignore because we've already processed them or
|
|
||||||
* aren't going to touch them in this pass.
|
|
||||||
*/
|
|
||||||
case para_IM:
|
|
||||||
case para_BR:
|
|
||||||
case para_Biblio: /* only touch BiblioCited */
|
|
||||||
case para_VersionID:
|
|
||||||
case para_Copyright:
|
|
||||||
case para_Preamble:
|
|
||||||
case para_NoCite:
|
|
||||||
case para_Title:
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Chapter and section titles: start a new Help topic.
|
|
||||||
*/
|
|
||||||
case para_Chapter:
|
|
||||||
case para_Appendix:
|
|
||||||
case para_UnnumberedChapter:
|
|
||||||
case para_Heading:
|
|
||||||
case para_Subsect:
|
|
||||||
if (lastsect && lastsect->child)
|
|
||||||
{
|
|
||||||
paragraph *q;
|
|
||||||
/*
|
|
||||||
* Do a navigation menu for the previous section we
|
|
||||||
* were in.
|
|
||||||
*/
|
|
||||||
for (q = lastsect->child; q; q = q->sibling)
|
|
||||||
whlp_navmenu (&state, q);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
rdstringc rs = { 0, 0, NULL };
|
|
||||||
WHLP_TOPIC new_topic, parent_topic;
|
|
||||||
char *macro, *topicid;
|
|
||||||
|
|
||||||
new_topic = p->private_data;
|
|
||||||
whlp_browse_link (h, state.curr_topic, new_topic);
|
|
||||||
state.curr_topic = new_topic;
|
|
||||||
|
|
||||||
if (p->kwtext)
|
|
||||||
{
|
|
||||||
whlp_rdaddwc (&rs, p->kwtext);
|
|
||||||
rdaddsc (&rs, ": "); /* FIXME: configurability */
|
|
||||||
}
|
|
||||||
whlp_rdaddwc (&rs, p->words);
|
|
||||||
if (p->parent == NULL)
|
|
||||||
parent_topic = contents_topic;
|
|
||||||
else
|
|
||||||
parent_topic = (WHLP_TOPIC) p->parent->private_data;
|
|
||||||
topicid = whlp_topic_id (parent_topic);
|
|
||||||
macro = smalloc (100 + strlen (topicid));
|
|
||||||
sprintf (macro,
|
|
||||||
"CBB(\"btn_up\",\"JI(`',`%s')\");EB(\"btn_up\")", topicid);
|
|
||||||
whlp_begin_topic (h, new_topic,
|
|
||||||
rs.text ? rs.text : "", macro, NULL);
|
|
||||||
sfree (macro);
|
|
||||||
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Output the .cnt entry.
|
|
||||||
*
|
|
||||||
* WinHelp has a bug involving having an internal
|
|
||||||
* node followed by a leaf at the same level: the
|
|
||||||
* leaf is output at the wrong level. We can mostly
|
|
||||||
* work around this by modifying the leaf level
|
|
||||||
* itself (see whlp_contents_write), but this
|
|
||||||
* doesn't work for top-level sections since we
|
|
||||||
* can't turn a level-1 leaf into a level-0 one. So
|
|
||||||
* for top-level leaf sections (Bibliography
|
|
||||||
* springs to mind), we output an internal node
|
|
||||||
* containing only the leaf for that section.
|
|
||||||
*/
|
|
||||||
int i;
|
|
||||||
paragraph *q;
|
|
||||||
|
|
||||||
/* Count up the level. */
|
|
||||||
i = 1;
|
|
||||||
for (q = p; q->parent; q = q->parent)
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if (p->child || !p->parent)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If p has children then it needs to be a
|
|
||||||
* folder; if it has no parent then it needs to
|
|
||||||
* be a folder to work around the bug.
|
|
||||||
*/
|
|
||||||
whlp_contents_write (&state, i, rs.text, NULL);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
whlp_contents_write (&state, i, rs.text, new_topic);
|
|
||||||
}
|
|
||||||
|
|
||||||
sfree (rs.text);
|
|
||||||
|
|
||||||
whlp_begin_para (h, WHLP_PARA_NONSCROLL);
|
|
||||||
if (p->kwtext)
|
|
||||||
{
|
|
||||||
whlp_mkparagraph (&state, FONT_TITLE, p->kwtext, FALSE);
|
|
||||||
whlp_set_font (h, FONT_TITLE);
|
|
||||||
whlp_text (h, ": "); /* FIXME: configurability */
|
|
||||||
}
|
|
||||||
whlp_mkparagraph (&state, FONT_TITLE, p->words, FALSE);
|
|
||||||
whlp_end_para (h);
|
|
||||||
|
|
||||||
lastsect = p;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case para_Rule:
|
|
||||||
whlp_para_attr (h, WHLP_PARA_SPACEBELOW, 12);
|
|
||||||
whlp_para_attr (h, WHLP_PARA_ALIGNMENT, WHLP_ALIGN_CENTRE);
|
|
||||||
whlp_begin_para (h, WHLP_PARA_SCROLL);
|
|
||||||
whlp_set_font (h, FONT_RULE);
|
|
||||||
#define TEN "\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0"
|
|
||||||
#define TWENTY TEN TEN
|
|
||||||
#define FORTY TWENTY TWENTY
|
|
||||||
#define EIGHTY FORTY FORTY
|
|
||||||
whlp_text (h, EIGHTY);
|
|
||||||
#undef TEN
|
|
||||||
#undef TWENTY
|
|
||||||
#undef FORTY
|
|
||||||
#undef EIGHTY
|
|
||||||
whlp_end_para (h);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case para_Normal:
|
|
||||||
case para_BiblioCited:
|
|
||||||
case para_Bullet:
|
|
||||||
case para_NumberedList:
|
|
||||||
whlp_para_attr (h, WHLP_PARA_SPACEBELOW, 12);
|
|
||||||
if (p->type == para_Bullet || p->type == para_NumberedList)
|
|
||||||
{
|
|
||||||
whlp_para_attr (h, WHLP_PARA_LEFTINDENT, 72);
|
|
||||||
whlp_para_attr (h, WHLP_PARA_FIRSTLINEINDENT, -36);
|
|
||||||
whlp_set_tabstop (h, 72, WHLP_ALIGN_LEFT);
|
|
||||||
whlp_begin_para (h, WHLP_PARA_SCROLL);
|
|
||||||
whlp_set_font (h, FONT_NORMAL);
|
|
||||||
if (p->type == para_Bullet)
|
|
||||||
{
|
|
||||||
whlp_text (h, "\x95");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
whlp_mkparagraph (&state, FONT_NORMAL, p->kwtext, FALSE);
|
|
||||||
whlp_text (h, ".");
|
|
||||||
}
|
|
||||||
whlp_tab (h);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
whlp_begin_para (h, WHLP_PARA_SCROLL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p->type == para_BiblioCited)
|
|
||||||
{
|
|
||||||
whlp_mkparagraph (&state, FONT_NORMAL, p->kwtext, FALSE);
|
|
||||||
whlp_text (h, " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
whlp_mkparagraph (&state, FONT_NORMAL, p->words, FALSE);
|
|
||||||
whlp_end_para (h);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case para_Code:
|
|
||||||
/*
|
|
||||||
* In a code paragraph, each individual word is a line. For
|
|
||||||
* Help files, we will have to output this as a set of
|
|
||||||
* paragraphs, all but the last of which don't set
|
|
||||||
* SPACEBELOW.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
word *w;
|
|
||||||
char *c;
|
|
||||||
for (w = p->words; w; w = w->next)
|
|
||||||
{
|
|
||||||
if (!w->next)
|
|
||||||
whlp_para_attr (h, WHLP_PARA_SPACEBELOW, 12);
|
|
||||||
whlp_begin_para (h, WHLP_PARA_SCROLL);
|
|
||||||
whlp_set_font (h, FONT_CODE);
|
|
||||||
whlp_convert (w->text, &c, FALSE);
|
|
||||||
whlp_text (h, c);
|
|
||||||
sfree (c);
|
|
||||||
whlp_end_para (h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose (state.cntfp);
|
|
||||||
whlp_close (h, filename);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Loop over the index entries, cleaning up our final text
|
|
||||||
* forms.
|
|
||||||
*/
|
|
||||||
for (i = 0; (ie = index234 (idx->entries, i)) != NULL; i++)
|
|
||||||
{
|
|
||||||
sfree (ie->backend_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
whlp_contents_write (struct bk_whlp_state *state,
|
|
||||||
int level, char *text, WHLP_TOPIC topic)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Horrifying bug in WinHelp. When dropping a section level or
|
|
||||||
* more without using a folder-type entry, WinHelp accidentally
|
|
||||||
* adds one to the section level. So we correct for that here.
|
|
||||||
*/
|
|
||||||
if (state->cnt_last_level > level && topic)
|
|
||||||
state->cnt_workaround = -1;
|
|
||||||
else if (!topic)
|
|
||||||
state->cnt_workaround = 0;
|
|
||||||
state->cnt_last_level = level;
|
|
||||||
|
|
||||||
fprintf (state->cntfp, "%d ", level + state->cnt_workaround);
|
|
||||||
while (*text)
|
|
||||||
{
|
|
||||||
if (*text == '=')
|
|
||||||
fputc ('\\', state->cntfp);
|
|
||||||
fputc (*text, state->cntfp);
|
|
||||||
text++;
|
|
||||||
}
|
|
||||||
if (topic)
|
|
||||||
fprintf (state->cntfp, "=%s", whlp_topic_id (topic));
|
|
||||||
fputc ('\n', state->cntfp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
whlp_navmenu (struct bk_whlp_state *state, paragraph * p)
|
|
||||||
{
|
|
||||||
whlp_begin_para (state->h, WHLP_PARA_NONSCROLL);
|
|
||||||
whlp_start_hyperlink (state->h, (WHLP_TOPIC) p->private_data);
|
|
||||||
if (p->kwtext)
|
|
||||||
{
|
|
||||||
whlp_mkparagraph (state, FONT_NORMAL, p->kwtext, TRUE);
|
|
||||||
whlp_set_font (state->h, FONT_NORMAL);
|
|
||||||
whlp_text (state->h, ": "); /* FIXME: configurability */
|
|
||||||
}
|
|
||||||
whlp_mkparagraph (state, FONT_NORMAL, p->words, TRUE);
|
|
||||||
whlp_end_hyperlink (state->h);
|
|
||||||
whlp_end_para (state->h);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
whlp_mkparagraph (struct bk_whlp_state *state,
|
|
||||||
int font, word * text, int subsidiary)
|
|
||||||
{
|
|
||||||
keyword *kwl;
|
|
||||||
int deffont = font;
|
|
||||||
int currfont = -1;
|
|
||||||
int newfont;
|
|
||||||
char *c;
|
|
||||||
paragraph *xref_target = NULL;
|
|
||||||
|
|
||||||
for (; text; text = text->next)
|
|
||||||
switch (text->type)
|
|
||||||
{
|
|
||||||
case word_HyperLink:
|
|
||||||
case word_HyperEnd:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case word_IndexRef:
|
|
||||||
if (subsidiary)
|
|
||||||
break; /* disabled in subsidiary bits */
|
|
||||||
{
|
|
||||||
indextag *tag = index_findtag (state->idx, text->text);
|
|
||||||
int i;
|
|
||||||
if (!tag)
|
|
||||||
break;
|
|
||||||
for (i = 0; i < tag->nrefs; i++)
|
|
||||||
whlp_index_term (state->h, tag->refs[i]->backend_data,
|
|
||||||
state->curr_topic);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case word_UpperXref:
|
|
||||||
case word_LowerXref:
|
|
||||||
if (subsidiary)
|
|
||||||
break; /* disabled in subsidiary bits */
|
|
||||||
kwl = kw_lookup (state->keywords, text->text);
|
|
||||||
assert (xref_target == NULL);
|
|
||||||
if (kwl->para->type == para_NumberedList)
|
|
||||||
{
|
|
||||||
break; /* don't xref to numbered list items */
|
|
||||||
}
|
|
||||||
else if (kwl->para->type == para_BiblioCited)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* An xref to a bibliography item jumps to the section
|
|
||||||
* containing it.
|
|
||||||
*/
|
|
||||||
if (kwl->para->parent)
|
|
||||||
xref_target = kwl->para->parent;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
xref_target = kwl->para;
|
|
||||||
}
|
|
||||||
whlp_start_hyperlink (state->h,
|
|
||||||
(WHLP_TOPIC) xref_target->private_data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case word_XrefEnd:
|
|
||||||
if (subsidiary)
|
|
||||||
break; /* disabled in subsidiary bits */
|
|
||||||
if (xref_target)
|
|
||||||
whlp_end_hyperlink (state->h);
|
|
||||||
xref_target = NULL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case word_Normal:
|
|
||||||
case word_Emph:
|
|
||||||
case word_Code:
|
|
||||||
case word_WeakCode:
|
|
||||||
case word_WhiteSpace:
|
|
||||||
case word_EmphSpace:
|
|
||||||
case word_CodeSpace:
|
|
||||||
case word_WkCodeSpace:
|
|
||||||
case word_Quote:
|
|
||||||
case word_EmphQuote:
|
|
||||||
case word_CodeQuote:
|
|
||||||
case word_WkCodeQuote:
|
|
||||||
if (towordstyle (text->type) == word_Emph)
|
|
||||||
newfont = deffont + FONT_EMPH;
|
|
||||||
else if (towordstyle (text->type) == word_Code ||
|
|
||||||
towordstyle (text->type) == word_WeakCode)
|
|
||||||
newfont = deffont + FONT_CODE;
|
|
||||||
else
|
|
||||||
newfont = deffont;
|
|
||||||
if (newfont != currfont)
|
|
||||||
{
|
|
||||||
currfont = newfont;
|
|
||||||
whlp_set_font (state->h, newfont);
|
|
||||||
}
|
|
||||||
if (removeattr (text->type) == word_Normal)
|
|
||||||
{
|
|
||||||
if (whlp_convert (text->text, &c, TRUE))
|
|
||||||
whlp_text (state->h, c);
|
|
||||||
else
|
|
||||||
whlp_mkparagraph (state, deffont, text->alt, FALSE);
|
|
||||||
sfree (c);
|
|
||||||
}
|
|
||||||
else if (removeattr (text->type) == word_WhiteSpace)
|
|
||||||
{
|
|
||||||
whlp_text (state->h, " ");
|
|
||||||
}
|
|
||||||
else if (removeattr (text->type) == word_Quote)
|
|
||||||
{
|
|
||||||
whlp_text (state->h,
|
|
||||||
quoteaux (text->aux) == quote_Open ? "\x91" : "\x92");
|
|
||||||
/* FIXME: configurability */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
whlp_rdaddwc (rdstringc * rs, word * text)
|
|
||||||
{
|
|
||||||
char *c;
|
|
||||||
|
|
||||||
for (; text; text = text->next)
|
|
||||||
switch (text->type)
|
|
||||||
{
|
|
||||||
case word_HyperLink:
|
|
||||||
case word_HyperEnd:
|
|
||||||
case word_UpperXref:
|
|
||||||
case word_LowerXref:
|
|
||||||
case word_XrefEnd:
|
|
||||||
case word_IndexRef:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case word_Normal:
|
|
||||||
case word_Emph:
|
|
||||||
case word_Code:
|
|
||||||
case word_WeakCode:
|
|
||||||
case word_WhiteSpace:
|
|
||||||
case word_EmphSpace:
|
|
||||||
case word_CodeSpace:
|
|
||||||
case word_WkCodeSpace:
|
|
||||||
case word_Quote:
|
|
||||||
case word_EmphQuote:
|
|
||||||
case word_CodeQuote:
|
|
||||||
case word_WkCodeQuote:
|
|
||||||
assert (text->type != word_CodeQuote &&
|
|
||||||
text->type != word_WkCodeQuote);
|
|
||||||
if (removeattr (text->type) == word_Normal)
|
|
||||||
{
|
|
||||||
if (whlp_convert (text->text, &c, FALSE))
|
|
||||||
rdaddsc (rs, c);
|
|
||||||
else
|
|
||||||
whlp_rdaddwc (rs, text->alt);
|
|
||||||
sfree (c);
|
|
||||||
}
|
|
||||||
else if (removeattr (text->type) == word_WhiteSpace)
|
|
||||||
{
|
|
||||||
rdaddc (rs, ' ');
|
|
||||||
}
|
|
||||||
else if (removeattr (text->type) == word_Quote)
|
|
||||||
{
|
|
||||||
rdaddc (rs, quoteaux (text->aux) == quote_Open ? '\x91' : '\x92');
|
|
||||||
/* FIXME: configurability */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert a wide string into a string of chars. If `result' is
|
|
||||||
* non-NULL, mallocs the resulting string and stores a pointer to
|
|
||||||
* it in `*result'. If `result' is NULL, merely checks whether all
|
|
||||||
* characters in the string are feasible for the output character
|
|
||||||
* set.
|
|
||||||
*
|
|
||||||
* Return is nonzero if all characters are OK. If not all
|
|
||||||
* characters are OK but `result' is non-NULL, a result _will_
|
|
||||||
* still be generated!
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
whlp_convert (wchar_t * s, char **result, int hard_spaces)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* FIXME. Currently this is ISO8859-1 only.
|
|
||||||
*/
|
|
||||||
int doing = (result != 0);
|
|
||||||
int ok = TRUE;
|
|
||||||
char *p = NULL;
|
|
||||||
int plen = 0, psize = 0;
|
|
||||||
|
|
||||||
for (; *s; s++)
|
|
||||||
{
|
|
||||||
wchar_t c = *s;
|
|
||||||
char outc;
|
|
||||||
|
|
||||||
if ((c >= 32 && c <= 126) || (c >= 160 && c <= 255))
|
|
||||||
{
|
|
||||||
/* Char is OK. */
|
|
||||||
if (c == 32 && hard_spaces)
|
|
||||||
outc = '\240';
|
|
||||||
else
|
|
||||||
outc = (char) c;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Char is not OK. */
|
|
||||||
ok = FALSE;
|
|
||||||
outc = 0xBF; /* approximate the good old DEC `uh?' */
|
|
||||||
}
|
|
||||||
if (doing)
|
|
||||||
{
|
|
||||||
if (plen >= psize)
|
|
||||||
{
|
|
||||||
psize = plen + 256;
|
|
||||||
p = resize (p, psize);
|
|
||||||
}
|
|
||||||
p[plen++] = outc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (doing)
|
|
||||||
{
|
|
||||||
p = resize (p, plen + 1);
|
|
||||||
p[plen] = '\0';
|
|
||||||
*result = p;
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,8 +8,7 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "halibut.h"
|
#include "halibut.h"
|
||||||
|
|
||||||
struct numberstate_Tag
|
struct numberstate_Tag {
|
||||||
{
|
|
||||||
int chapternum;
|
int chapternum;
|
||||||
int appendixnum;
|
int appendixnum;
|
||||||
int ischapter;
|
int ischapter;
|
||||||
|
@ -24,8 +23,7 @@ struct numberstate_Tag
|
||||||
wchar_t *apptext; /* the word for an appendix */
|
wchar_t *apptext; /* the word for an appendix */
|
||||||
};
|
};
|
||||||
|
|
||||||
numberstate *
|
numberstate *number_init(void)
|
||||||
number_init (void)
|
|
||||||
{
|
{
|
||||||
numberstate *ret = mknew(numberstate);
|
numberstate *ret = mknew(numberstate);
|
||||||
ret->chapternum = 0;
|
ret->chapternum = 0;
|
||||||
|
@ -42,16 +40,14 @@ number_init (void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void number_free(numberstate * state)
|
||||||
number_free (numberstate * state)
|
|
||||||
{
|
{
|
||||||
sfree(state->sectionlevels);
|
sfree(state->sectionlevels);
|
||||||
sfree(state->currentsects);
|
sfree(state->currentsects);
|
||||||
sfree(state);
|
sfree(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void dotext(word *** wret, wchar_t * text)
|
||||||
dotext (word *** wret, wchar_t * text)
|
|
||||||
{
|
{
|
||||||
word *mnewword = mknew(word);
|
word *mnewword = mknew(word);
|
||||||
mnewword->text = ustrdup(text);
|
mnewword->text = ustrdup(text);
|
||||||
|
@ -62,8 +58,7 @@ dotext (word *** wret, wchar_t * text)
|
||||||
*wret = &mnewword->next;
|
*wret = &mnewword->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void dospace(word *** wret)
|
||||||
dospace (word *** wret)
|
|
||||||
{
|
{
|
||||||
word *mnewword = mknew(word);
|
word *mnewword = mknew(word);
|
||||||
mnewword->text = NULL;
|
mnewword->text = NULL;
|
||||||
|
@ -74,14 +69,12 @@ dospace (word *** wret)
|
||||||
*wret = &mnewword->next;
|
*wret = &mnewword->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void donumber(word *** wret, int num)
|
||||||
donumber (word *** wret, int num)
|
|
||||||
{
|
{
|
||||||
wchar_t text[20];
|
wchar_t text[20];
|
||||||
wchar_t *p = text + sizeof(text);
|
wchar_t *p = text + sizeof(text);
|
||||||
*--p = L'\0';
|
*--p = L'\0';
|
||||||
while (num != 0)
|
while (num != 0) {
|
||||||
{
|
|
||||||
assert(p > text);
|
assert(p > text);
|
||||||
*--p = L"0123456789"[num % 10];
|
*--p = L"0123456789"[num % 10];
|
||||||
num /= 10;
|
num /= 10;
|
||||||
|
@ -89,16 +82,14 @@ donumber (word *** wret, int num)
|
||||||
dotext(wret, p);
|
dotext(wret, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void doanumber(word *** wret, int num)
|
||||||
doanumber (word *** wret, int num)
|
|
||||||
{
|
{
|
||||||
wchar_t text[20];
|
wchar_t text[20];
|
||||||
wchar_t *p;
|
wchar_t *p;
|
||||||
int nletters, aton;
|
int nletters, aton;
|
||||||
nletters = 1;
|
nletters = 1;
|
||||||
aton = 25;
|
aton = 25;
|
||||||
while (num > aton)
|
while (num > aton) {
|
||||||
{
|
|
||||||
nletters++;
|
nletters++;
|
||||||
num -= aton + 1;
|
num -= aton + 1;
|
||||||
if (aton < INT_MAX / 26)
|
if (aton < INT_MAX / 26)
|
||||||
|
@ -108,8 +99,7 @@ doanumber (word *** wret, int num)
|
||||||
}
|
}
|
||||||
p = text + sizeof(text);
|
p = text + sizeof(text);
|
||||||
*--p = L'\0';
|
*--p = L'\0';
|
||||||
while (nletters--)
|
while (nletters--) {
|
||||||
{
|
|
||||||
assert(p > text);
|
assert(p > text);
|
||||||
*--p = L"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[num % 26];
|
*--p = L"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[num % 26];
|
||||||
num /= 26;
|
num /= 26;
|
||||||
|
@ -117,8 +107,7 @@ doanumber (word *** wret, int num)
|
||||||
dotext(wret, p);
|
dotext(wret, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void number_cfg(numberstate * state, paragraph * source)
|
||||||
number_cfg (numberstate * state, paragraph * source)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Defaults
|
* Defaults
|
||||||
|
@ -127,28 +116,20 @@ number_cfg (numberstate * state, paragraph * source)
|
||||||
state->sectiontext = L"Section";
|
state->sectiontext = L"Section";
|
||||||
state->apptext = L"Appendix";
|
state->apptext = L"Appendix";
|
||||||
|
|
||||||
for (; source; source = source->next)
|
for (; source; source = source->next) {
|
||||||
{
|
if (source->type == para_Config) {
|
||||||
if (source->type == para_Config)
|
if (!ustricmp(source->keyword, L"chapter")) {
|
||||||
{
|
|
||||||
if (!ustricmp (source->keyword, L"chapter"))
|
|
||||||
{
|
|
||||||
state->chaptertext = uadv(source->keyword);
|
state->chaptertext = uadv(source->keyword);
|
||||||
}
|
} else if (!ustricmp(source->keyword, L"section")) {
|
||||||
else if (!ustricmp (source->keyword, L"section"))
|
|
||||||
{
|
|
||||||
state->sectiontext = uadv(source->keyword);
|
state->sectiontext = uadv(source->keyword);
|
||||||
}
|
} else if (!ustricmp(source->keyword, L"appendix")) {
|
||||||
else if (!ustricmp (source->keyword, L"appendix"))
|
|
||||||
{
|
|
||||||
state->apptext = uadv(source->keyword);
|
state->apptext = uadv(source->keyword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
word *
|
word *number_mktext(numberstate * state, paragraph * p, wchar_t * category,
|
||||||
number_mktext (numberstate * state, paragraph * p, wchar_t * category,
|
|
||||||
int prev, int *errflag)
|
int prev, int *errflag)
|
||||||
{
|
{
|
||||||
word *ret = NULL;
|
word *ret = NULL;
|
||||||
|
@ -157,8 +138,7 @@ number_mktext (numberstate * state, paragraph * p, wchar_t * category,
|
||||||
int i, level;
|
int i, level;
|
||||||
|
|
||||||
level = -2; /* default for non-section-heading */
|
level = -2; /* default for non-section-heading */
|
||||||
switch (p->type)
|
switch (p->type) {
|
||||||
{
|
|
||||||
case para_Chapter:
|
case para_Chapter:
|
||||||
state->chapternum++;
|
state->chapternum++;
|
||||||
for (i = 0; i < state->maxsectlevel; i++)
|
for (i = 0; i < state->maxsectlevel; i++)
|
||||||
|
@ -174,16 +154,14 @@ number_mktext (numberstate * state, paragraph * p, wchar_t * category,
|
||||||
case para_Heading:
|
case para_Heading:
|
||||||
case para_Subsect:
|
case para_Subsect:
|
||||||
level = (p->type == para_Heading ? 0 : p->aux);
|
level = (p->type == para_Heading ? 0 : p->aux);
|
||||||
if (level > state->oklevel)
|
if (level > state->oklevel) {
|
||||||
{
|
|
||||||
error(err_sectjump, &p->fpos);
|
error(err_sectjump, &p->fpos);
|
||||||
*errflag = TRUE;
|
*errflag = TRUE;
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
state->oklevel = level + 1;
|
state->oklevel = level + 1;
|
||||||
if (state->maxsectlevel <= level)
|
if (state->maxsectlevel <= level) {
|
||||||
{
|
|
||||||
state->maxsectlevel = level + 32;
|
state->maxsectlevel = level + 32;
|
||||||
state->sectionlevels = resize(state->sectionlevels,
|
state->sectionlevels = resize(state->sectionlevels,
|
||||||
state->maxsectlevel);
|
state->maxsectlevel);
|
||||||
|
@ -198,8 +176,7 @@ number_mktext (numberstate * state, paragraph * p, wchar_t * category,
|
||||||
donumber(&pret, state->chapternum);
|
donumber(&pret, state->chapternum);
|
||||||
else
|
else
|
||||||
doanumber(&pret, state->appendixnum);
|
doanumber(&pret, state->appendixnum);
|
||||||
for (i = 0; i <= level; i++)
|
for (i = 0; i <= level; i++) {
|
||||||
{
|
|
||||||
dotext(&pret, L".");
|
dotext(&pret, L".");
|
||||||
if (state->sectionlevels[i] == 0)
|
if (state->sectionlevels[i] == 0)
|
||||||
state->sectionlevels[i] = 1;
|
state->sectionlevels[i] = 1;
|
||||||
|
@ -234,12 +211,10 @@ number_mktext (numberstate * state, paragraph * p, wchar_t * category,
|
||||||
* Now set up parent, child and sibling links.
|
* Now set up parent, child and sibling links.
|
||||||
*/
|
*/
|
||||||
p->parent = p->child = p->sibling = NULL;
|
p->parent = p->child = p->sibling = NULL;
|
||||||
if (level != -2)
|
if (level != -2) {
|
||||||
{
|
|
||||||
if (state->currentsects[level + 1])
|
if (state->currentsects[level + 1])
|
||||||
state->currentsects[level + 1]->sibling = p;
|
state->currentsects[level + 1]->sibling = p;
|
||||||
if (level >= 0 && state->currentsects[level])
|
if (level >= 0 && state->currentsects[level]) {
|
||||||
{
|
|
||||||
p->parent = state->currentsects[level];
|
p->parent = state->currentsects[level];
|
||||||
if (!state->currentsects[level]->child)
|
if (!state->currentsects[level]->child)
|
||||||
state->currentsects[level]->child = p;
|
state->currentsects[level]->child = p;
|
||||||
|
@ -247,9 +222,7 @@ number_mktext (numberstate * state, paragraph * p, wchar_t * category,
|
||||||
state->currentsects[level + 1] = state->lastsect = p;
|
state->currentsects[level + 1] = state->lastsect = p;
|
||||||
for (i = level + 2; i < state->maxsectlevel + 1; i++)
|
for (i = level + 2; i < state->maxsectlevel + 1; i++)
|
||||||
state->currentsects[i] = NULL;
|
state->currentsects[i] = NULL;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
p->parent = state->lastsect;
|
p->parent = state->lastsect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,7 @@
|
||||||
#define PREFIX 0x0001 /* give `halibut:' prefix */
|
#define PREFIX 0x0001 /* give `halibut:' prefix */
|
||||||
#define FILEPOS 0x0002 /* give file position prefix */
|
#define FILEPOS 0x0002 /* give file position prefix */
|
||||||
|
|
||||||
static void
|
static void do_error(int code, va_list ap)
|
||||||
do_error (int code, va_list ap)
|
|
||||||
{
|
{
|
||||||
char error[1024];
|
char error[1024];
|
||||||
char auxbuf[256];
|
char auxbuf[256];
|
||||||
|
@ -23,8 +22,7 @@ do_error (int code, va_list ap)
|
||||||
filepos fpos, fpos2;
|
filepos fpos, fpos2;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
switch (code)
|
switch (code) {
|
||||||
{
|
|
||||||
case err_nomemory: /* no arguments */
|
case err_nomemory: /* no arguments */
|
||||||
sprintf(error, "out of memory");
|
sprintf(error, "out of memory");
|
||||||
flags = PREFIX;
|
flags = PREFIX;
|
||||||
|
@ -54,7 +52,8 @@ do_error (int code, va_list ap)
|
||||||
break;
|
break;
|
||||||
case err_brokencodepara:
|
case err_brokencodepara:
|
||||||
fpos = *va_arg(ap, filepos *);
|
fpos = *va_arg(ap, filepos *);
|
||||||
sprintf (error, "every line of a code paragraph should begin `\\c'");
|
sprintf(error,
|
||||||
|
"every line of a code paragraph should begin `\\c'");
|
||||||
flags = FILEPOS;
|
flags = FILEPOS;
|
||||||
break;
|
break;
|
||||||
case err_kwunclosed:
|
case err_kwunclosed:
|
||||||
|
@ -136,7 +135,8 @@ do_error (int code, va_list ap)
|
||||||
fpos = *va_arg(ap, filepos *);
|
fpos = *va_arg(ap, filepos *);
|
||||||
wsp = va_arg(ap, wchar_t *);
|
wsp = va_arg(ap, wchar_t *);
|
||||||
sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
|
sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
|
||||||
sprintf (error, "unable to resolve cross-reference to `%.200s'", sp);
|
sprintf(error, "unable to resolve cross-reference to `%.200s'",
|
||||||
|
sp);
|
||||||
flags = FILEPOS;
|
flags = FILEPOS;
|
||||||
break;
|
break;
|
||||||
case err_multiBR:
|
case err_multiBR:
|
||||||
|
@ -183,8 +183,10 @@ do_error (int code, va_list ap)
|
||||||
fpos2 = *va_arg(ap, filepos *);
|
fpos2 = *va_arg(ap, filepos *);
|
||||||
wsp = va_arg(ap, wchar_t *);
|
wsp = va_arg(ap, wchar_t *);
|
||||||
sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
|
sp = ustrtoa(wsp, auxbuf, sizeof(auxbuf));
|
||||||
sprintf (error, "paragraph keyword `%.200s' already defined at ", sp);
|
sprintf(error, "paragraph keyword `%.200s' already defined at ",
|
||||||
sprintf (error + strlen (error), "%s:%d", fpos2.filename, fpos2.line);
|
sp);
|
||||||
|
sprintf(error + strlen(error), "%s:%d", fpos2.filename,
|
||||||
|
fpos2.line);
|
||||||
flags = FILEPOS;
|
flags = FILEPOS;
|
||||||
break;
|
break;
|
||||||
case err_whatever:
|
case err_whatever:
|
||||||
|
@ -196,8 +198,7 @@ do_error (int code, va_list ap)
|
||||||
|
|
||||||
if (flags & PREFIX)
|
if (flags & PREFIX)
|
||||||
fputs("halibut: ", stderr);
|
fputs("halibut: ", stderr);
|
||||||
if (flags & FILEPOS)
|
if (flags & FILEPOS) {
|
||||||
{
|
|
||||||
fprintf(stderr, "%s:%d:", fpos.filename, fpos.line);
|
fprintf(stderr, "%s:%d:", fpos.filename, fpos.line);
|
||||||
if (fpos.col > 0)
|
if (fpos.col > 0)
|
||||||
fprintf(stderr, "%d:", fpos.col);
|
fprintf(stderr, "%d:", fpos.col);
|
||||||
|
@ -207,8 +208,7 @@ do_error (int code, va_list ap)
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void fatal(int code, ...)
|
||||||
fatal (int code, ...)
|
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, code);
|
va_start(ap, code);
|
||||||
|
@ -217,8 +217,7 @@ fatal (int code, ...)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void error(int code, ...)
|
||||||
error (int code, ...)
|
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, code);
|
va_start(ap, code);
|
||||||
|
|
|
@ -43,8 +43,7 @@ typedef struct macrostack_Tag macrostack;
|
||||||
* Data structure to hold a file name and index, a line and a
|
* Data structure to hold a file name and index, a line and a
|
||||||
* column number, for reporting errors
|
* column number, for reporting errors
|
||||||
*/
|
*/
|
||||||
struct filepos_Tag
|
struct filepos_Tag {
|
||||||
{
|
|
||||||
char *filename;
|
char *filename;
|
||||||
int line, col;
|
int line, col;
|
||||||
};
|
};
|
||||||
|
@ -52,14 +51,11 @@ struct filepos_Tag
|
||||||
/*
|
/*
|
||||||
* Data structure to hold all the file names etc for input
|
* Data structure to hold all the file names etc for input
|
||||||
*/
|
*/
|
||||||
typedef struct pushback_Tag
|
typedef struct pushback_Tag {
|
||||||
{
|
|
||||||
int chr;
|
int chr;
|
||||||
filepos pos;
|
filepos pos;
|
||||||
}
|
} pushback;
|
||||||
pushback;
|
struct input_Tag {
|
||||||
struct input_Tag
|
|
||||||
{
|
|
||||||
char **filenames; /* complete list of input files */
|
char **filenames; /* complete list of input files */
|
||||||
int nfiles; /* how many in the list */
|
int nfiles; /* how many in the list */
|
||||||
FILE *currfp; /* the currently open one */
|
FILE *currfp; /* the currently open one */
|
||||||
|
@ -75,8 +71,7 @@ struct input_Tag
|
||||||
* Data structure to hold the input form of the source, ie a linked
|
* Data structure to hold the input form of the source, ie a linked
|
||||||
* list of paragraphs
|
* list of paragraphs
|
||||||
*/
|
*/
|
||||||
struct paragraph_Tag
|
struct paragraph_Tag {
|
||||||
{
|
|
||||||
paragraph *next;
|
paragraph *next;
|
||||||
int type;
|
int type;
|
||||||
wchar_t *keyword; /* for most special paragraphs */
|
wchar_t *keyword; /* for most special paragraphs */
|
||||||
|
@ -92,8 +87,7 @@ struct paragraph_Tag
|
||||||
|
|
||||||
void *private_data; /* for temp use in backends */
|
void *private_data; /* for temp use in backends */
|
||||||
};
|
};
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
para_IM, /* index merge */
|
para_IM, /* index merge */
|
||||||
para_BR, /* bibliography rewrite */
|
para_BR, /* bibliography rewrite */
|
||||||
para_Rule, /* random horizontal rule */
|
para_Rule, /* random horizontal rule */
|
||||||
|
@ -120,8 +114,7 @@ enum
|
||||||
/*
|
/*
|
||||||
* Data structure to hold an individual word
|
* Data structure to hold an individual word
|
||||||
*/
|
*/
|
||||||
struct word_Tag
|
struct word_Tag {
|
||||||
{
|
|
||||||
word *next, *alt;
|
word *next, *alt;
|
||||||
int type;
|
int type;
|
||||||
int aux;
|
int aux;
|
||||||
|
@ -129,8 +122,7 @@ struct word_Tag
|
||||||
wchar_t *text;
|
wchar_t *text;
|
||||||
filepos fpos;
|
filepos fpos;
|
||||||
};
|
};
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
/* ORDERING CONSTRAINT: these normal-word types ... */
|
/* ORDERING CONSTRAINT: these normal-word types ... */
|
||||||
word_Normal,
|
word_Normal,
|
||||||
word_Emph,
|
word_Emph,
|
||||||
|
@ -156,8 +148,7 @@ enum
|
||||||
word_HyperEnd /* (also invisible; no text) */
|
word_HyperEnd /* (also invisible; no text) */
|
||||||
};
|
};
|
||||||
/* aux values for attributed words */
|
/* aux values for attributed words */
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
attr_Only = 0x0000, /* a lone word with the attribute */
|
attr_Only = 0x0000, /* a lone word with the attribute */
|
||||||
attr_First = 0x0001, /* the first of a series */
|
attr_First = 0x0001, /* the first of a series */
|
||||||
attr_Last = 0x0002, /* the last of a series */
|
attr_Last = 0x0002, /* the last of a series */
|
||||||
|
@ -165,8 +156,7 @@ enum
|
||||||
attr_mask = 0x0003,
|
attr_mask = 0x0003,
|
||||||
};
|
};
|
||||||
/* aux values for quote-type words */
|
/* aux values for quote-type words */
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
quote_Open = 0x0010,
|
quote_Open = 0x0010,
|
||||||
quote_Close = 0x0020,
|
quote_Close = 0x0020,
|
||||||
quote_mask = 0x0030,
|
quote_mask = 0x0030,
|
||||||
|
@ -185,12 +175,9 @@ enum
|
||||||
/*
|
/*
|
||||||
* error.c
|
* error.c
|
||||||
*/
|
*/
|
||||||
void
|
void fatal(int code, ...) NORETURN;
|
||||||
fatal (int code, ...)
|
|
||||||
NORETURN;
|
|
||||||
void error(int code, ...);
|
void error(int code, ...);
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
err_nomemory, /* out of memory */
|
err_nomemory, /* out of memory */
|
||||||
err_optnoarg, /* option `-%s' requires an argument */
|
err_optnoarg, /* option `-%s' requires an argument */
|
||||||
err_nosuchopt, /* unrecognised option `-%s' */
|
err_nosuchopt, /* unrecognised option `-%s' */
|
||||||
|
@ -268,7 +255,6 @@ fatal (int code, ...)
|
||||||
/*
|
/*
|
||||||
* help.c
|
* help.c
|
||||||
*/
|
*/
|
||||||
void help (void);
|
|
||||||
void usage(void);
|
void usage(void);
|
||||||
void showversion(void);
|
void showversion(void);
|
||||||
|
|
||||||
|
@ -292,14 +278,12 @@ fatal (int code, ...)
|
||||||
void *stk_pop(stack);
|
void *stk_pop(stack);
|
||||||
|
|
||||||
typedef struct tagRdstring rdstring;
|
typedef struct tagRdstring rdstring;
|
||||||
struct tagRdstring
|
struct tagRdstring {
|
||||||
{
|
|
||||||
int pos, size;
|
int pos, size;
|
||||||
wchar_t *text;
|
wchar_t *text;
|
||||||
};
|
};
|
||||||
typedef struct tagRdstringc rdstringc;
|
typedef struct tagRdstringc rdstringc;
|
||||||
struct tagRdstringc
|
struct tagRdstringc {
|
||||||
{
|
|
||||||
int pos, size;
|
int pos, size;
|
||||||
char *text;
|
char *text;
|
||||||
};
|
};
|
||||||
|
@ -317,8 +301,7 @@ fatal (int code, ...)
|
||||||
void mark_attr_ends(paragraph * sourceform);
|
void mark_attr_ends(paragraph * sourceform);
|
||||||
|
|
||||||
typedef struct tagWrappedLine wrappedline;
|
typedef struct tagWrappedLine wrappedline;
|
||||||
struct tagWrappedLine
|
struct tagWrappedLine {
|
||||||
{
|
|
||||||
wrappedline *next;
|
wrappedline *next;
|
||||||
word *begin, *end; /* first & last words of line */
|
word *begin, *end; /* first & last words of line */
|
||||||
int nspaces; /* number of whitespaces in line */
|
int nspaces; /* number of whitespaces in line */
|
||||||
|
@ -335,8 +318,7 @@ fatal (int code, ...)
|
||||||
/*
|
/*
|
||||||
* keywords.c
|
* keywords.c
|
||||||
*/
|
*/
|
||||||
struct keywordlist_Tag
|
struct keywordlist_Tag {
|
||||||
{
|
|
||||||
int nkeywords;
|
int nkeywords;
|
||||||
int size;
|
int size;
|
||||||
tree234 *keys; /* sorted by `key' field */
|
tree234 *keys; /* sorted by `key' field */
|
||||||
|
@ -344,8 +326,7 @@ fatal (int code, ...)
|
||||||
int nlooseends;
|
int nlooseends;
|
||||||
int looseendssize;
|
int looseendssize;
|
||||||
};
|
};
|
||||||
struct keyword_Tag
|
struct keyword_Tag {
|
||||||
{
|
|
||||||
wchar_t *key; /* the keyword itself */
|
wchar_t *key; /* the keyword itself */
|
||||||
word *text; /* "Chapter 2", "Appendix Q"... */
|
word *text; /* "Chapter 2", "Appendix Q"... */
|
||||||
/* (NB: filepos are not set) */
|
/* (NB: filepos are not set) */
|
||||||
|
@ -363,8 +344,7 @@ fatal (int code, ...)
|
||||||
/*
|
/*
|
||||||
* Data structure to hold both sides of the index.
|
* Data structure to hold both sides of the index.
|
||||||
*/
|
*/
|
||||||
struct indexdata_Tag
|
struct indexdata_Tag {
|
||||||
{
|
|
||||||
tree234 *tags; /* holds type `indextag' */
|
tree234 *tags; /* holds type `indextag' */
|
||||||
tree234 *entries; /* holds type `indexentry' */
|
tree234 *entries; /* holds type `indexentry' */
|
||||||
};
|
};
|
||||||
|
@ -372,8 +352,7 @@ fatal (int code, ...)
|
||||||
/*
|
/*
|
||||||
* Data structure to hold an index tag (LHS of index).
|
* Data structure to hold an index tag (LHS of index).
|
||||||
*/
|
*/
|
||||||
struct indextag_Tag
|
struct indextag_Tag {
|
||||||
{
|
|
||||||
wchar_t *name;
|
wchar_t *name;
|
||||||
word *implicit_text;
|
word *implicit_text;
|
||||||
word **explicit_texts;
|
word **explicit_texts;
|
||||||
|
@ -385,8 +364,7 @@ fatal (int code, ...)
|
||||||
/*
|
/*
|
||||||
* Data structure to hold an index entry (RHS of index).
|
* Data structure to hold an index entry (RHS of index).
|
||||||
*/
|
*/
|
||||||
struct indexentry_Tag
|
struct indexentry_Tag {
|
||||||
{
|
|
||||||
word *text;
|
word *text;
|
||||||
void *backend_data; /* private to back end */
|
void *backend_data; /* private to back end */
|
||||||
};
|
};
|
||||||
|
@ -416,23 +394,12 @@ fatal (int code, ...)
|
||||||
/*
|
/*
|
||||||
* style.c
|
* style.c
|
||||||
*/
|
*/
|
||||||
struct userstyle_Tag
|
struct userstyle_Tag {
|
||||||
{
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* bk_text.c
|
|
||||||
*/
|
|
||||||
void text_backend (paragraph *, keywordlist *, indexdata *);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* bk_xhtml.c
|
* bk_xhtml.c
|
||||||
*/
|
*/
|
||||||
void xhtml_backend(paragraph *, keywordlist *, indexdata *);
|
void xhtml_backend(paragraph *, keywordlist *, indexdata *);
|
||||||
|
|
||||||
/*
|
|
||||||
* bk_whlp.c
|
|
||||||
*/
|
|
||||||
void whlp_backend (paragraph *, keywordlist *, indexdata *);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,34 +5,19 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "halibut.h"
|
#include "halibut.h"
|
||||||
|
|
||||||
static char *helptext[] = {
|
|
||||||
"FIXME: help text goes here",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static char *usagetext[] = {
|
static char *usagetext[] = {
|
||||||
"FIXME: usage text goes here",
|
"halibut.exe file1 [file2 ...]",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void usage(void)
|
||||||
help (void)
|
|
||||||
{
|
|
||||||
char **p;
|
|
||||||
for (p = helptext; *p; p++)
|
|
||||||
puts (*p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
usage (void)
|
|
||||||
{
|
{
|
||||||
char **p;
|
char **p;
|
||||||
for (p = usagetext; *p; p++)
|
for (p = usagetext; *p; p++)
|
||||||
puts(*p);
|
puts(*p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void showversion(void)
|
||||||
showversion (void)
|
|
||||||
{
|
{
|
||||||
printf("Halibut, %s\n", version);
|
printf("Halibut, %s\n", version);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
static int compare_tags(void *av, void *bv);
|
static int compare_tags(void *av, void *bv);
|
||||||
static int compare_entries(void *av, void *bv);
|
static int compare_entries(void *av, void *bv);
|
||||||
|
|
||||||
indexdata *
|
indexdata *make_index(void)
|
||||||
make_index (void)
|
|
||||||
{
|
{
|
||||||
indexdata *ret = mknew(indexdata);
|
indexdata *ret = mknew(indexdata);
|
||||||
ret->tags = newtree234(compare_tags);
|
ret->tags = newtree234(compare_tags);
|
||||||
|
@ -18,8 +17,7 @@ make_index (void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static indextag *
|
static indextag *make_indextag(void)
|
||||||
make_indextag (void)
|
|
||||||
{
|
{
|
||||||
indextag *ret = mknew(indextag);
|
indextag *ret = mknew(indextag);
|
||||||
ret->name = NULL;
|
ret->name = NULL;
|
||||||
|
@ -30,23 +28,20 @@ make_indextag (void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int compare_tags(void *av, void *bv)
|
||||||
compare_tags (void *av, void *bv)
|
|
||||||
{
|
{
|
||||||
indextag *a = (indextag *) av, *b = (indextag *) bv;
|
indextag *a = (indextag *) av, *b = (indextag *) bv;
|
||||||
return ustricmp(a->name, b->name);
|
return ustricmp(a->name, b->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int compare_to_find_tag(void *av, void *bv)
|
||||||
compare_to_find_tag (void *av, void *bv)
|
|
||||||
{
|
{
|
||||||
wchar_t *a = (wchar_t *) av;
|
wchar_t *a = (wchar_t *) av;
|
||||||
indextag *b = (indextag *) bv;
|
indextag *b = (indextag *) bv;
|
||||||
return ustricmp(a, b->name);
|
return ustricmp(a, b->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int compare_entries(void *av, void *bv)
|
||||||
compare_entries (void *av, void *bv)
|
|
||||||
{
|
{
|
||||||
indexentry *a = (indexentry *) av, *b = (indexentry *) bv;
|
indexentry *a = (indexentry *) av, *b = (indexentry *) bv;
|
||||||
return compare_wordlists(a->text, b->text);
|
return compare_wordlists(a->text, b->text);
|
||||||
|
@ -55,8 +50,7 @@ compare_entries (void *av, void *bv)
|
||||||
/*
|
/*
|
||||||
* Back-end utility: find the indextag with a given name.
|
* Back-end utility: find the indextag with a given name.
|
||||||
*/
|
*/
|
||||||
indextag *
|
indextag *index_findtag(indexdata * idx, wchar_t * name)
|
||||||
index_findtag (indexdata * idx, wchar_t * name)
|
|
||||||
{
|
{
|
||||||
return find234(idx->tags, name, compare_to_find_tag);
|
return find234(idx->tags, name, compare_to_find_tag);
|
||||||
}
|
}
|
||||||
|
@ -77,13 +71,11 @@ index_merge (indexdata * idx, int is_explicit, wchar_t * tags, word * text)
|
||||||
/*
|
/*
|
||||||
* FIXME: want to warn on overlapping source sets.
|
* FIXME: want to warn on overlapping source sets.
|
||||||
*/
|
*/
|
||||||
for (; *tags; tags = uadv (tags))
|
for (; *tags; tags = uadv(tags)) {
|
||||||
{
|
|
||||||
t = make_indextag();
|
t = make_indextag();
|
||||||
t->name = tags;
|
t->name = tags;
|
||||||
existing = add234(idx->tags, t);
|
existing = add234(idx->tags, t);
|
||||||
if (existing == t)
|
if (existing == t) {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* Duplicate this so we can free it independently.
|
* Duplicate this so we can free it independently.
|
||||||
*/
|
*/
|
||||||
|
@ -94,8 +86,7 @@ index_merge (indexdata * idx, int is_explicit, wchar_t * tags, word * text)
|
||||||
* doesn't exist and we're explicit, then we should
|
* doesn't exist and we're explicit, then we should
|
||||||
* warn (and drop it, since it won't be referenced).
|
* warn (and drop it, since it won't be referenced).
|
||||||
*/
|
*/
|
||||||
if (is_explicit)
|
if (is_explicit) {
|
||||||
{
|
|
||||||
error(err_nosuchidxtag, tags);
|
error(err_nosuchidxtag, tags);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -104,13 +95,10 @@ index_merge (indexdata * idx, int is_explicit, wchar_t * tags, word * text)
|
||||||
* Otherwise, this is a new tag with an implicit \IM.
|
* Otherwise, this is a new tag with an implicit \IM.
|
||||||
*/
|
*/
|
||||||
t->implicit_text = text;
|
t->implicit_text = text;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
sfree(t);
|
sfree(t);
|
||||||
t = existing;
|
t = existing;
|
||||||
if (!is_explicit)
|
if (!is_explicit) {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* An implicit \IM for a tag that's had an implicit
|
* An implicit \IM for a tag that's had an implicit
|
||||||
* \IM before. FIXME: we should check the text
|
* \IM before. FIXME: we should check the text
|
||||||
|
@ -118,21 +106,17 @@ index_merge (indexdata * idx, int is_explicit, wchar_t * tags, word * text)
|
||||||
* differences. And check the tag for case match
|
* differences. And check the tag for case match
|
||||||
* against the existing tag, likewise.
|
* against the existing tag, likewise.
|
||||||
*/
|
*/
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* An explicit \IM added to a valid tag. In
|
* An explicit \IM added to a valid tag. In
|
||||||
* particular, this removes the implicit \IM if
|
* particular, this removes the implicit \IM if
|
||||||
* present.
|
* present.
|
||||||
*/
|
*/
|
||||||
if (t->implicit_text)
|
if (t->implicit_text) {
|
||||||
{
|
|
||||||
free_word_list(t->implicit_text);
|
free_word_list(t->implicit_text);
|
||||||
t->implicit_text = NULL;
|
t->implicit_text = NULL;
|
||||||
}
|
}
|
||||||
if (t->nexplicit >= t->explicit_size)
|
if (t->nexplicit >= t->explicit_size) {
|
||||||
{
|
|
||||||
t->explicit_size = t->nexplicit + 8;
|
t->explicit_size = t->nexplicit + 8;
|
||||||
t->explicit_texts = resize(t->explicit_texts,
|
t->explicit_texts = resize(t->explicit_texts,
|
||||||
t->explicit_size);
|
t->explicit_size);
|
||||||
|
@ -150,31 +134,24 @@ index_merge (indexdata * idx, int is_explicit, wchar_t * tags, word * text)
|
||||||
* entries in the original 2-3 tree with pointers to the RHS
|
* entries in the original 2-3 tree with pointers to the RHS
|
||||||
* entries.
|
* entries.
|
||||||
*/
|
*/
|
||||||
void
|
void build_index(indexdata * i)
|
||||||
build_index (indexdata * i)
|
|
||||||
{
|
{
|
||||||
indextag *t;
|
indextag *t;
|
||||||
word **ta;
|
word **ta;
|
||||||
int ti;
|
int ti;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (ti = 0; (t = (indextag *) index234 (i->tags, ti)) != NULL; ti++)
|
for (ti = 0; (t = (indextag *) index234(i->tags, ti)) != NULL; ti++) {
|
||||||
{
|
if (t->implicit_text) {
|
||||||
if (t->implicit_text)
|
|
||||||
{
|
|
||||||
t->nrefs = 1;
|
t->nrefs = 1;
|
||||||
ta = &t->implicit_text;
|
ta = &t->implicit_text;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
t->nrefs = t->nexplicit;
|
t->nrefs = t->nexplicit;
|
||||||
ta = t->explicit_texts;
|
ta = t->explicit_texts;
|
||||||
}
|
}
|
||||||
if (t->nrefs)
|
if (t->nrefs) {
|
||||||
{
|
|
||||||
t->refs = mknewa(indexentry *, t->nrefs);
|
t->refs = mknewa(indexentry *, t->nrefs);
|
||||||
for (j = 0; j < t->nrefs; j++)
|
for (j = 0; j < t->nrefs; j++) {
|
||||||
{
|
|
||||||
indexentry *ent = mknew(indexentry);
|
indexentry *ent = mknew(indexentry);
|
||||||
ent->text = *ta++;
|
ent->text = *ta++;
|
||||||
t->refs[j] = add234(i->entries, ent);
|
t->refs[j] = add234(i->entries, ent);
|
||||||
|
@ -185,15 +162,13 @@ build_index (indexdata * i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void cleanup_index(indexdata * i)
|
||||||
cleanup_index (indexdata * i)
|
|
||||||
{
|
{
|
||||||
indextag *t;
|
indextag *t;
|
||||||
indexentry *ent;
|
indexentry *ent;
|
||||||
int ti;
|
int ti;
|
||||||
|
|
||||||
for (ti = 0; (t = (indextag *) index234 (i->tags, ti)) != NULL; ti++)
|
for (ti = 0; (t = (indextag *) index234(i->tags, ti)) != NULL; ti++) {
|
||||||
{
|
|
||||||
sfree(t->name);
|
sfree(t->name);
|
||||||
free_word_list(t->implicit_text);
|
free_word_list(t->implicit_text);
|
||||||
sfree(t->explicit_texts);
|
sfree(t->explicit_texts);
|
||||||
|
@ -201,8 +176,8 @@ cleanup_index (indexdata * i)
|
||||||
sfree(t);
|
sfree(t);
|
||||||
}
|
}
|
||||||
freetree234(i->tags);
|
freetree234(i->tags);
|
||||||
for (ti = 0; (ent = (indexentry *) index234 (i->entries, ti)) != NULL; ti++)
|
for (ti = 0; (ent = (indexentry *) index234(i->entries, ti)) != NULL;
|
||||||
{
|
ti++) {
|
||||||
sfree(ent);
|
sfree(ent);
|
||||||
}
|
}
|
||||||
freetree234(i->entries);
|
freetree234(i->entries);
|
||||||
|
@ -212,8 +187,7 @@ cleanup_index (indexdata * i)
|
||||||
static void dbg_prtwordlist(int level, word * w);
|
static void dbg_prtwordlist(int level, word * w);
|
||||||
static void dbg_prtmerge(int is_explicit, wchar_t * tag, word * text);
|
static void dbg_prtmerge(int is_explicit, wchar_t * tag, word * text);
|
||||||
|
|
||||||
void
|
void index_debug(indexdata * i)
|
||||||
index_debug (indexdata * i)
|
|
||||||
{
|
{
|
||||||
indextag *t;
|
indextag *t;
|
||||||
indexentry *y;
|
indexentry *y;
|
||||||
|
@ -221,8 +195,7 @@ index_debug (indexdata * i)
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
printf("\nINDEX TAGS\n==========\n\n");
|
printf("\nINDEX TAGS\n==========\n\n");
|
||||||
for (ti = 0; (t = (indextag *) index234 (i->tags, ti)) != NULL; ti++)
|
for (ti = 0; (t = (indextag *) index234(i->tags, ti)) != NULL; ti++) {
|
||||||
{
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
if (t->implicit_text)
|
if (t->implicit_text)
|
||||||
dbg_prtmerge(0, t->name, t->implicit_text);
|
dbg_prtmerge(0, t->name, t->implicit_text);
|
||||||
|
@ -231,8 +204,8 @@ index_debug (indexdata * i)
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\nINDEX ENTRIES\n=============\n\n");
|
printf("\nINDEX ENTRIES\n=============\n\n");
|
||||||
for (ti = 0; (y = (indexentry *) index234 (i->entries, ti)) != NULL; ti++)
|
for (ti = 0; (y = (indexentry *) index234(i->entries, ti)) != NULL;
|
||||||
{
|
ti++) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("{\n");
|
printf("{\n");
|
||||||
dbg_prtwordlist(1, y->text);
|
dbg_prtwordlist(1, y->text);
|
||||||
|
@ -240,8 +213,7 @@ index_debug (indexdata * i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void dbg_prtmerge(int is_explicit, wchar_t * tag, word * text)
|
||||||
dbg_prtmerge (int is_explicit, wchar_t * tag, word * text)
|
|
||||||
{
|
{
|
||||||
printf("\\IM: %splicit: \"", is_explicit ? "ex" : "im");
|
printf("\\IM: %splicit: \"", is_explicit ? "ex" : "im");
|
||||||
for (; *tag; tag++)
|
for (; *tag; tag++)
|
||||||
|
@ -251,24 +223,19 @@ dbg_prtmerge (int is_explicit, wchar_t * tag, word * text)
|
||||||
printf("}\n");
|
printf("}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void dbg_prtwordlist(int level, word * w)
|
||||||
dbg_prtwordlist (int level, word * w)
|
|
||||||
{
|
|
||||||
for (; w; w = w->next)
|
|
||||||
{
|
{
|
||||||
|
for (; w; w = w->next) {
|
||||||
wchar_t *wp;
|
wchar_t *wp;
|
||||||
printf("%*sword %d ", level * 4, "", w->type);
|
printf("%*sword %d ", level * 4, "", w->type);
|
||||||
if (w->text)
|
if (w->text) {
|
||||||
{
|
|
||||||
printf("\"");
|
printf("\"");
|
||||||
for (wp = w->text; *wp; wp++)
|
for (wp = w->text; *wp; wp++)
|
||||||
putchar(*wp);
|
putchar(*wp);
|
||||||
printf("\"");
|
printf("\"");
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
printf("(no text)");
|
printf("(no text)");
|
||||||
if (w->alt)
|
if (w->alt) {
|
||||||
{
|
|
||||||
printf(" alt = {\n");
|
printf(" alt = {\n");
|
||||||
dbg_prtwordlist(level + 1, w->alt);
|
dbg_prtwordlist(level + 1, w->alt);
|
||||||
printf("%*s}", level * 4, "");
|
printf("%*s}", level * 4, "");
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -7,24 +7,21 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "halibut.h"
|
#include "halibut.h"
|
||||||
|
|
||||||
static int
|
static int kwcmp(void *av, void *bv)
|
||||||
kwcmp (void *av, void *bv)
|
|
||||||
{
|
{
|
||||||
const keyword *a = (const keyword *) av;
|
const keyword *a = (const keyword *) av;
|
||||||
const keyword *b = (const keyword *) bv;
|
const keyword *b = (const keyword *) bv;
|
||||||
return ustrcmp(a->key, b->key);
|
return ustrcmp(a->key, b->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int kwfind(void *av, void *bv)
|
||||||
kwfind (void *av, void *bv)
|
|
||||||
{
|
{
|
||||||
wchar_t *a = (wchar_t *) av;
|
wchar_t *a = (wchar_t *) av;
|
||||||
const keyword *b = (const keyword *) bv;
|
const keyword *b = (const keyword *) bv;
|
||||||
return ustrcmp(a, b->key);
|
return ustrcmp(a, b->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
keyword *
|
keyword *kw_lookup(keywordlist * kl, wchar_t * str)
|
||||||
kw_lookup (keywordlist * kl, wchar_t * str)
|
|
||||||
{
|
{
|
||||||
return find234(kl->keys, str, kwfind);
|
return find234(kl->keys, str, kwfind);
|
||||||
}
|
}
|
||||||
|
@ -35,8 +32,7 @@ kw_lookup (keywordlist * kl, wchar_t * str)
|
||||||
* collation, last at the top (so that we can Heapsort them when we
|
* collation, last at the top (so that we can Heapsort them when we
|
||||||
* finish).
|
* finish).
|
||||||
*/
|
*/
|
||||||
keywordlist *
|
keywordlist *get_keywords(paragraph * source)
|
||||||
get_keywords (paragraph * source)
|
|
||||||
{
|
{
|
||||||
int errors = FALSE;
|
int errors = FALSE;
|
||||||
keywordlist *kl = mknew(keywordlist);
|
keywordlist *kl = mknew(keywordlist);
|
||||||
|
@ -49,8 +45,7 @@ get_keywords (paragraph * source)
|
||||||
kl->keys = newtree234(kwcmp);
|
kl->keys = newtree234(kwcmp);
|
||||||
kl->nlooseends = kl->looseendssize = 0;
|
kl->nlooseends = kl->looseendssize = 0;
|
||||||
kl->looseends = NULL;
|
kl->looseends = NULL;
|
||||||
for (; source; source = source->next)
|
for (; source; source = source->next) {
|
||||||
{
|
|
||||||
wchar_t *p, *q;
|
wchar_t *p, *q;
|
||||||
p = q = source->keyword;
|
p = q = source->keyword;
|
||||||
|
|
||||||
|
@ -59,8 +54,7 @@ get_keywords (paragraph * source)
|
||||||
* `question' or whatever - to replace `chapter' or
|
* `question' or whatever - to replace `chapter' or
|
||||||
* `section' on a per-section basis).
|
* `section' on a per-section basis).
|
||||||
*/
|
*/
|
||||||
if (q)
|
if (q) {
|
||||||
{
|
|
||||||
q = uadv(q); /* point q at the word beyond */
|
q = uadv(q); /* point q at the word beyond */
|
||||||
if (!*q)
|
if (!*q)
|
||||||
q = NULL;
|
q = NULL;
|
||||||
|
@ -74,10 +68,8 @@ get_keywords (paragraph * source)
|
||||||
source->kwtext = number_mktext(n, source, q, prevpara, &errors);
|
source->kwtext = number_mktext(n, source, q, prevpara, &errors);
|
||||||
prevpara = source->type;
|
prevpara = source->type;
|
||||||
|
|
||||||
if (p && *p)
|
if (p && *p) {
|
||||||
{
|
if (source->kwtext || source->type == para_Biblio) {
|
||||||
if (source->kwtext || source->type == para_Biblio)
|
|
||||||
{
|
|
||||||
keyword *kw, *ret;
|
keyword *kw, *ret;
|
||||||
|
|
||||||
kw = mknew(keyword);
|
kw = mknew(keyword);
|
||||||
|
@ -85,18 +77,14 @@ get_keywords (paragraph * source)
|
||||||
kw->text = source->kwtext;
|
kw->text = source->kwtext;
|
||||||
kw->para = source;
|
kw->para = source;
|
||||||
ret = add234(kl->keys, kw);
|
ret = add234(kl->keys, kw);
|
||||||
if (ret != kw)
|
if (ret != kw) {
|
||||||
{
|
|
||||||
error(err_multikw, &source->fpos, &ret->para->fpos, p);
|
error(err_multikw, &source->fpos, &ret->para->fpos, p);
|
||||||
sfree(kw);
|
sfree(kw);
|
||||||
/* FIXME: what happens to kw->text? Does it leak? */
|
/* FIXME: what happens to kw->text? Does it leak? */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if (kl->nlooseends >= kl->looseendssize) {
|
||||||
{
|
|
||||||
if (kl->nlooseends >= kl->looseendssize)
|
|
||||||
{
|
|
||||||
kl->looseendssize = kl->nlooseends + 32;
|
kl->looseendssize = kl->nlooseends + 32;
|
||||||
kl->looseends = resize(kl->looseends, kl->looseendssize);
|
kl->looseends = resize(kl->looseends, kl->looseendssize);
|
||||||
}
|
}
|
||||||
|
@ -106,8 +94,7 @@ get_keywords (paragraph * source)
|
||||||
|
|
||||||
number_free(n);
|
number_free(n);
|
||||||
|
|
||||||
if (errors)
|
if (errors) {
|
||||||
{
|
|
||||||
free_keywords(kl);
|
free_keywords(kl);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -115,15 +102,13 @@ get_keywords (paragraph * source)
|
||||||
return kl;
|
return kl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void free_keywords(keywordlist * kl)
|
||||||
free_keywords (keywordlist * kl)
|
|
||||||
{
|
{
|
||||||
keyword *kw;
|
keyword *kw;
|
||||||
while (kl->nlooseends)
|
while (kl->nlooseends)
|
||||||
free_word_list(kl->looseends[--kl->nlooseends]);
|
free_word_list(kl->looseends[--kl->nlooseends]);
|
||||||
sfree(kl->looseends);
|
sfree(kl->looseends);
|
||||||
while ((kw = index234 (kl->keys, 0)) != NULL)
|
while ((kw = index234(kl->keys, 0)) != NULL) {
|
||||||
{
|
|
||||||
delpos234(kl->keys, 0);
|
delpos234(kl->keys, 0);
|
||||||
free_word_list(kw->text);
|
free_word_list(kw->text);
|
||||||
sfree(kw);
|
sfree(kw);
|
||||||
|
@ -132,26 +117,20 @@ free_keywords (keywordlist * kl)
|
||||||
sfree(kl);
|
sfree(kl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void subst_keywords(paragraph * source, keywordlist * kl)
|
||||||
subst_keywords (paragraph * source, keywordlist * kl)
|
|
||||||
{
|
|
||||||
for (; source; source = source->next)
|
|
||||||
{
|
{
|
||||||
|
for (; source; source = source->next) {
|
||||||
word *ptr;
|
word *ptr;
|
||||||
for (ptr = source->words; ptr; ptr = ptr->next)
|
for (ptr = source->words; ptr; ptr = ptr->next) {
|
||||||
{
|
if (ptr->type == word_UpperXref || ptr->type == word_LowerXref) {
|
||||||
if (ptr->type == word_UpperXref || ptr->type == word_LowerXref)
|
|
||||||
{
|
|
||||||
keyword *kw;
|
keyword *kw;
|
||||||
word **endptr, *close, *subst;
|
word **endptr, *close, *subst;
|
||||||
|
|
||||||
kw = kw_lookup(kl, ptr->text);
|
kw = kw_lookup(kl, ptr->text);
|
||||||
if (!kw)
|
if (!kw) {
|
||||||
{
|
|
||||||
error(err_nosuchkw, &ptr->fpos, ptr->text);
|
error(err_nosuchkw, &ptr->fpos, ptr->text);
|
||||||
subst = NULL;
|
subst = NULL;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
subst = dup_word_list(kw->text);
|
subst = dup_word_list(kw->text);
|
||||||
|
|
||||||
if (subst && ptr->type == word_LowerXref &&
|
if (subst && ptr->type == word_LowerXref &&
|
||||||
|
@ -168,7 +147,8 @@ subst_keywords (paragraph * source, keywordlist * kl)
|
||||||
close->next = ptr->next;
|
close->next = ptr->next;
|
||||||
ptr->next = subst;
|
ptr->next = subst;
|
||||||
|
|
||||||
for (endptr = &ptr->next; *endptr; endptr = &(*endptr)->next)
|
for (endptr = &ptr->next; *endptr;
|
||||||
|
endptr = &(*endptr)->next)
|
||||||
(*endptr)->fpos = ptr->fpos;
|
(*endptr)->fpos = ptr->fpos;
|
||||||
|
|
||||||
*endptr = close;
|
*endptr = close;
|
||||||
|
|
|
@ -9,8 +9,7 @@ static char *licencetext[] = {
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void licence(void)
|
||||||
licence (void)
|
|
||||||
{
|
{
|
||||||
char **p;
|
char **p;
|
||||||
for (p = licencetext; *p; p++)
|
for (p = licencetext; *p; p++)
|
||||||
|
|
|
@ -10,8 +10,7 @@ static void dbg_prtsource (paragraph * sourceform);
|
||||||
static void dbg_prtwordlist(int level, word * w);
|
static void dbg_prtwordlist(int level, word * w);
|
||||||
static void dbg_prtkws(keywordlist * kws);
|
static void dbg_prtkws(keywordlist * kws);
|
||||||
|
|
||||||
int
|
int main(int argc, char **argv)
|
||||||
main (int argc, char **argv)
|
|
||||||
{
|
{
|
||||||
char **infiles;
|
char **infiles;
|
||||||
char *outfile;
|
char *outfile;
|
||||||
|
@ -31,8 +30,7 @@ main (int argc, char **argv)
|
||||||
reportcols = 0;
|
reportcols = 0;
|
||||||
debug = 0;
|
debug = 0;
|
||||||
|
|
||||||
if (argc == 1)
|
if (argc == 1) {
|
||||||
{
|
|
||||||
usage();
|
usage();
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -40,19 +38,15 @@ main (int argc, char **argv)
|
||||||
/*
|
/*
|
||||||
* Parse command line arguments.
|
* Parse command line arguments.
|
||||||
*/
|
*/
|
||||||
while (--argc)
|
while (--argc) {
|
||||||
{
|
|
||||||
char *p = *++argv;
|
char *p = *++argv;
|
||||||
if (*p == '-')
|
if (*p == '-') {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* An option.
|
* An option.
|
||||||
*/
|
*/
|
||||||
while (p && *++p)
|
while (p && *++p) {
|
||||||
{
|
|
||||||
char c = *p;
|
char c = *p;
|
||||||
switch (c)
|
switch (c) {
|
||||||
{
|
|
||||||
case '-':
|
case '-':
|
||||||
/*
|
/*
|
||||||
* Long option.
|
* Long option.
|
||||||
|
@ -62,48 +56,31 @@ main (int argc, char **argv)
|
||||||
opt = p++; /* opt will have _one_ leading - */
|
opt = p++; /* opt will have _one_ leading - */
|
||||||
while (*p && *p != '=')
|
while (*p && *p != '=')
|
||||||
p++; /* find end of option */
|
p++; /* find end of option */
|
||||||
if (*p == '=')
|
if (*p == '=') {
|
||||||
{
|
|
||||||
*p++ = '\0';
|
*p++ = '\0';
|
||||||
val = p;
|
val = p;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
val = NULL;
|
val = NULL;
|
||||||
if (!strcmp (opt, "-help"))
|
if (!strcmp(opt, "-version")) {
|
||||||
{
|
|
||||||
help ();
|
|
||||||
nogo = TRUE;
|
|
||||||
}
|
|
||||||
else if (!strcmp (opt, "-version"))
|
|
||||||
{
|
|
||||||
showversion();
|
showversion();
|
||||||
nogo = TRUE;
|
nogo = TRUE;
|
||||||
}
|
} else if (!strcmp(opt, "-licence") ||
|
||||||
else if (!strcmp (opt, "-licence") ||
|
!strcmp(opt, "-license")) {
|
||||||
!strcmp (opt, "-license"))
|
|
||||||
{
|
|
||||||
licence();
|
licence();
|
||||||
nogo = TRUE;
|
nogo = TRUE;
|
||||||
}
|
} else if (!strcmp(opt, "-output")) {
|
||||||
else if (!strcmp (opt, "-output"))
|
|
||||||
{
|
|
||||||
if (!val)
|
if (!val)
|
||||||
errs = TRUE, error(err_optnoarg, opt);
|
errs = TRUE, error(err_optnoarg, opt);
|
||||||
else
|
else
|
||||||
outfile = val;
|
outfile = val;
|
||||||
}
|
} else if (!strcmp(opt, "-precise")) {
|
||||||
else if (!strcmp (opt, "-precise"))
|
|
||||||
{
|
|
||||||
reportcols = 1;
|
reportcols = 1;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
errs = TRUE, error(err_nosuchopt, opt);
|
errs = TRUE, error(err_nosuchopt, opt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p = NULL;
|
p = NULL;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
|
||||||
case 'V':
|
case 'V':
|
||||||
case 'L':
|
case 'L':
|
||||||
case 'P':
|
case 'P':
|
||||||
|
@ -111,12 +88,7 @@ main (int argc, char **argv)
|
||||||
/*
|
/*
|
||||||
* Option requiring no parameter.
|
* Option requiring no parameter.
|
||||||
*/
|
*/
|
||||||
switch (c)
|
switch (c) {
|
||||||
{
|
|
||||||
case 'h':
|
|
||||||
help ();
|
|
||||||
nogo = TRUE;
|
|
||||||
break;
|
|
||||||
case 'V':
|
case 'V':
|
||||||
showversion();
|
showversion();
|
||||||
nogo = TRUE;
|
nogo = TRUE;
|
||||||
|
@ -140,8 +112,7 @@ main (int argc, char **argv)
|
||||||
p++;
|
p++;
|
||||||
if (!*p && argc > 1)
|
if (!*p && argc > 1)
|
||||||
--argc, p = *++argv;
|
--argc, p = *++argv;
|
||||||
else if (!*p)
|
else if (!*p) {
|
||||||
{
|
|
||||||
char opt[2];
|
char opt[2];
|
||||||
opt[0] = c;
|
opt[0] = c;
|
||||||
opt[1] = '\0';
|
opt[1] = '\0';
|
||||||
|
@ -150,8 +121,7 @@ main (int argc, char **argv)
|
||||||
/*
|
/*
|
||||||
* Now c is the option and p is the parameter.
|
* Now c is the option and p is the parameter.
|
||||||
*/
|
*/
|
||||||
switch (c)
|
switch (c) {
|
||||||
{
|
|
||||||
case 'o':
|
case 'o':
|
||||||
outfile = p;
|
outfile = p;
|
||||||
break;
|
break;
|
||||||
|
@ -170,9 +140,7 @@ main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* A non-option argument.
|
* A non-option argument.
|
||||||
*/
|
*/
|
||||||
|
@ -188,8 +156,7 @@ main (int argc, char **argv)
|
||||||
/*
|
/*
|
||||||
* Do the work.
|
* Do the work.
|
||||||
*/
|
*/
|
||||||
if (nfiles == 0)
|
if (nfiles == 0) {
|
||||||
{
|
|
||||||
error(err_noinput);
|
error(err_noinput);
|
||||||
usage();
|
usage();
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -234,16 +201,13 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
build_index(idx);
|
build_index(idx);
|
||||||
|
|
||||||
if (debug)
|
if (debug) {
|
||||||
{
|
|
||||||
index_debug(idx);
|
index_debug(idx);
|
||||||
dbg_prtkws(keywords);
|
dbg_prtkws(keywords);
|
||||||
dbg_prtsource(sourceform);
|
dbg_prtsource(sourceform);
|
||||||
}
|
}
|
||||||
|
|
||||||
text_backend (sourceform, keywords, idx);
|
|
||||||
xhtml_backend(sourceform, keywords, idx);
|
xhtml_backend(sourceform, keywords, idx);
|
||||||
whlp_backend (sourceform, keywords, idx);
|
|
||||||
|
|
||||||
free_para_list(sourceform);
|
free_para_list(sourceform);
|
||||||
free_keywords(keywords);
|
free_keywords(keywords);
|
||||||
|
@ -253,23 +217,19 @@ main (int argc, char **argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void dbg_prtsource(paragraph * sourceform)
|
||||||
dbg_prtsource (paragraph * sourceform)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Output source form in debugging format.
|
* Output source form in debugging format.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
paragraph *p;
|
paragraph *p;
|
||||||
for (p = sourceform; p; p = p->next)
|
for (p = sourceform; p; p = p->next) {
|
||||||
{
|
|
||||||
wchar_t *wp;
|
wchar_t *wp;
|
||||||
printf("para %d ", p->type);
|
printf("para %d ", p->type);
|
||||||
if (p->keyword)
|
if (p->keyword) {
|
||||||
{
|
|
||||||
wp = p->keyword;
|
wp = p->keyword;
|
||||||
while (*wp)
|
while (*wp) {
|
||||||
{
|
|
||||||
putchar('\"');
|
putchar('\"');
|
||||||
for (; *wp; wp++)
|
for (; *wp; wp++)
|
||||||
putchar(*wp);
|
putchar(*wp);
|
||||||
|
@ -277,8 +237,7 @@ dbg_prtsource (paragraph * sourceform)
|
||||||
if (*++wp)
|
if (*++wp)
|
||||||
printf(", ");
|
printf(", ");
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
printf("(no keyword)");
|
printf("(no keyword)");
|
||||||
printf(" {\n");
|
printf(" {\n");
|
||||||
dbg_prtwordlist(1, p->words);
|
dbg_prtwordlist(1, p->words);
|
||||||
|
@ -286,8 +245,7 @@ dbg_prtsource (paragraph * sourceform)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void dbg_prtkws(keywordlist * kws)
|
||||||
dbg_prtkws (keywordlist * kws)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Output keywords in debugging format.
|
* Output keywords in debugging format.
|
||||||
|
@ -296,13 +254,11 @@ dbg_prtkws (keywordlist * kws)
|
||||||
int i;
|
int i;
|
||||||
keyword *kw;
|
keyword *kw;
|
||||||
|
|
||||||
for (i = 0; (kw = index234 (kws->keys, i)) != NULL; i++)
|
for (i = 0; (kw = index234(kws->keys, i)) != NULL; i++) {
|
||||||
{
|
|
||||||
wchar_t *wp;
|
wchar_t *wp;
|
||||||
printf("keyword ");
|
printf("keyword ");
|
||||||
wp = kw->key;
|
wp = kw->key;
|
||||||
while (*wp)
|
while (*wp) {
|
||||||
{
|
|
||||||
putchar('\"');
|
putchar('\"');
|
||||||
for (; *wp; wp++)
|
for (; *wp; wp++)
|
||||||
putchar(*wp);
|
putchar(*wp);
|
||||||
|
@ -316,24 +272,19 @@ dbg_prtkws (keywordlist * kws)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void dbg_prtwordlist(int level, word * w)
|
||||||
dbg_prtwordlist (int level, word * w)
|
|
||||||
{
|
|
||||||
for (; w; w = w->next)
|
|
||||||
{
|
{
|
||||||
|
for (; w; w = w->next) {
|
||||||
wchar_t *wp;
|
wchar_t *wp;
|
||||||
printf("%*sword %d ", level * 4, "", w->type);
|
printf("%*sword %d ", level * 4, "", w->type);
|
||||||
if (w->text)
|
if (w->text) {
|
||||||
{
|
|
||||||
printf("\"");
|
printf("\"");
|
||||||
for (wp = w->text; *wp; wp++)
|
for (wp = w->text; *wp; wp++)
|
||||||
putchar(*wp);
|
putchar(*wp);
|
||||||
printf("\"");
|
printf("\"");
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
printf("(no text)");
|
printf("(no text)");
|
||||||
if (w->alt)
|
if (w->alt) {
|
||||||
{
|
|
||||||
printf(" alt = {\n");
|
printf(" alt = {\n");
|
||||||
dbg_prtwordlist(level + 1, w->alt);
|
dbg_prtwordlist(level + 1, w->alt);
|
||||||
printf("%*s}", level * 4, "");
|
printf("%*s}", level * 4, "");
|
||||||
|
|
|
@ -1,17 +1,12 @@
|
||||||
OBJS = biblio.o bk_text.o bk_whlp.o bk_xhtml.o contents.o error.o help.o index.o input.o keywords.o licence.o main.o malloc.o misc.o style.o tree234.o ustring.o version.o winhelp.o
|
OBJS = biblio.o bk_xhtml.o contents.o error.o help.o index.o input.o keywords.o licence.o main.o malloc.o misc.o style.o tree234.o ustring.o version.o winhelp.o
|
||||||
LIBS =
|
LIBS =
|
||||||
|
|
||||||
# -- Programs --
|
|
||||||
MAKE = make
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
RM = del
|
RM = del
|
||||||
|
DEFINES = -DVERSION="\"1.0 (NSIS Custom Build)\""
|
||||||
# -- Compilers and linker flags --
|
|
||||||
DEFINES =
|
|
||||||
CFLAGS = -Wall -W $(DEFINES)
|
CFLAGS = -Wall -W $(DEFINES)
|
||||||
LFLAGS = -s
|
LFLAGS = -s
|
||||||
|
|
||||||
|
|
||||||
all : halibut
|
all : halibut
|
||||||
|
|
||||||
halibut : $(OBJS)
|
halibut : $(OBJS)
|
||||||
|
|
|
@ -10,18 +10,14 @@
|
||||||
#define LOGPARAMS char *file, int line,
|
#define LOGPARAMS char *file, int line,
|
||||||
static FILE *logallocfp = NULL;
|
static FILE *logallocfp = NULL;
|
||||||
static int logline = 2; /* off by 1: `null pointer is' */
|
static int logline = 2; /* off by 1: `null pointer is' */
|
||||||
static void
|
static void loginc(void)
|
||||||
loginc (void)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
static void
|
static void logallocinit(void)
|
||||||
logallocinit (void)
|
|
||||||
{
|
|
||||||
if (!logallocfp)
|
|
||||||
{
|
{
|
||||||
|
if (!logallocfp) {
|
||||||
logallocfp = fopen("malloc.log", "w");
|
logallocfp = fopen("malloc.log", "w");
|
||||||
if (!logallocfp)
|
if (!logallocfp) {
|
||||||
{
|
|
||||||
fprintf(stderr, "panic: unable to open malloc.log\n");
|
fprintf(stderr, "panic: unable to open malloc.log\n");
|
||||||
exit(10);
|
exit(10);
|
||||||
}
|
}
|
||||||
|
@ -29,8 +25,7 @@ logallocinit (void)
|
||||||
fprintf(logallocfp, "null pointer is %p\n", NULL);
|
fprintf(logallocfp, "null pointer is %p\n", NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void
|
static void logprintf(char *fmt, ...)
|
||||||
logprintf (char *fmt, ...)
|
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
@ -50,8 +45,7 @@ logprintf (char *fmt, ...)
|
||||||
* smalloc should guarantee to return a useful pointer - Halibut
|
* smalloc should guarantee to return a useful pointer - Halibut
|
||||||
* can do nothing except die when it's out of memory anyway.
|
* can do nothing except die when it's out of memory anyway.
|
||||||
*/
|
*/
|
||||||
void *(smalloc) (LOGPARAMS int size)
|
void *(smalloc) (LOGPARAMS int size) {
|
||||||
{
|
|
||||||
void *p;
|
void *p;
|
||||||
LOGINC;
|
LOGINC;
|
||||||
LOGPRINT(("%s %d malloc(%ld)", file, line, (long) size));
|
LOGPRINT(("%s %d malloc(%ld)", file, line, (long) size));
|
||||||
|
@ -65,10 +59,8 @@ void *(smalloc) (LOGPARAMS int size)
|
||||||
/*
|
/*
|
||||||
* sfree should guaranteeably deal gracefully with freeing NULL
|
* sfree should guaranteeably deal gracefully with freeing NULL
|
||||||
*/
|
*/
|
||||||
void (sfree) (LOGPARAMS void *p)
|
void (sfree) (LOGPARAMS void *p) {
|
||||||
{
|
if (p) {
|
||||||
if (p)
|
|
||||||
{
|
|
||||||
LOGINC;
|
LOGINC;
|
||||||
LOGPRINT(("%s %d free(%p)\n", file, line, p));
|
LOGPRINT(("%s %d free(%p)\n", file, line, p));
|
||||||
free(p);
|
free(p);
|
||||||
|
@ -78,18 +70,14 @@ void (sfree) (LOGPARAMS void *p)
|
||||||
/*
|
/*
|
||||||
* srealloc should guaranteeably be able to realloc NULL
|
* srealloc should guaranteeably be able to realloc NULL
|
||||||
*/
|
*/
|
||||||
void *(srealloc) (LOGPARAMS void *p, int size)
|
void *(srealloc) (LOGPARAMS void *p, int size) {
|
||||||
{
|
|
||||||
void *q;
|
void *q;
|
||||||
if (p)
|
if (p) {
|
||||||
{
|
|
||||||
LOGINC;
|
LOGINC;
|
||||||
LOGPRINT(("%s %d realloc(%p,%ld)", file, line, p, (long) size));
|
LOGPRINT(("%s %d realloc(%p,%ld)", file, line, p, (long) size));
|
||||||
q = realloc(p, size);
|
q = realloc(p, size);
|
||||||
LOGPRINT((" returns %p\n", q));
|
LOGPRINT((" returns %p\n", q));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
LOGINC;
|
LOGINC;
|
||||||
LOGPRINT(("%s %d malloc(%ld)", file, line, (long) size));
|
LOGPRINT(("%s %d malloc(%ld)", file, line, (long) size));
|
||||||
q = malloc(size);
|
q = malloc(size);
|
||||||
|
@ -104,8 +92,7 @@ void *(srealloc) (LOGPARAMS void *p, int size)
|
||||||
* dupstr is like strdup, but with the never-return-NULL property
|
* dupstr is like strdup, but with the never-return-NULL property
|
||||||
* of smalloc (and also reliably defined in all environments :-)
|
* of smalloc (and also reliably defined in all environments :-)
|
||||||
*/
|
*/
|
||||||
char *
|
char *dupstr(char *s)
|
||||||
dupstr (char *s)
|
|
||||||
{
|
{
|
||||||
char *r = smalloc(1 + strlen(s));
|
char *r = smalloc(1 + strlen(s));
|
||||||
strcpy(r, s);
|
strcpy(r, s);
|
||||||
|
@ -115,13 +102,11 @@ dupstr (char *s)
|
||||||
/*
|
/*
|
||||||
* Duplicate a linked list of words
|
* Duplicate a linked list of words
|
||||||
*/
|
*/
|
||||||
word *
|
word *dup_word_list(word * w)
|
||||||
dup_word_list (word * w)
|
|
||||||
{
|
{
|
||||||
word *head, **eptr = &head;
|
word *head, **eptr = &head;
|
||||||
|
|
||||||
while (w)
|
while (w) {
|
||||||
{
|
|
||||||
word *newwd = mknew(word);
|
word *newwd = mknew(word);
|
||||||
*newwd = *w; /* structure copy */
|
*newwd = *w; /* structure copy */
|
||||||
newwd->text = ustrdup(w->text);
|
newwd->text = ustrdup(w->text);
|
||||||
|
@ -140,12 +125,10 @@ dup_word_list (word * w)
|
||||||
/*
|
/*
|
||||||
* Free a linked list of words
|
* Free a linked list of words
|
||||||
*/
|
*/
|
||||||
void
|
void free_word_list(word * w)
|
||||||
free_word_list (word * w)
|
|
||||||
{
|
{
|
||||||
word *t;
|
word *t;
|
||||||
while (w)
|
while (w) {
|
||||||
{
|
|
||||||
t = w;
|
t = w;
|
||||||
w = w->next;
|
w = w->next;
|
||||||
sfree(t->text);
|
sfree(t->text);
|
||||||
|
@ -158,12 +141,10 @@ free_word_list (word * w)
|
||||||
/*
|
/*
|
||||||
* Free a linked list of paragraphs
|
* Free a linked list of paragraphs
|
||||||
*/
|
*/
|
||||||
void
|
void free_para_list(paragraph * p)
|
||||||
free_para_list (paragraph * p)
|
|
||||||
{
|
{
|
||||||
paragraph *t;
|
paragraph *t;
|
||||||
while (p)
|
while (p) {
|
||||||
{
|
|
||||||
t = p;
|
t = p;
|
||||||
p = p->next;
|
p = p->next;
|
||||||
sfree(t->keyword);
|
sfree(t->keyword);
|
||||||
|
|
|
@ -4,15 +4,13 @@
|
||||||
|
|
||||||
#include "halibut.h"
|
#include "halibut.h"
|
||||||
|
|
||||||
struct stackTag
|
struct stackTag {
|
||||||
{
|
|
||||||
void **data;
|
void **data;
|
||||||
int sp;
|
int sp;
|
||||||
int size;
|
int size;
|
||||||
};
|
};
|
||||||
|
|
||||||
stack
|
stack stk_new(void)
|
||||||
stk_new (void)
|
|
||||||
{
|
{
|
||||||
stack s;
|
stack s;
|
||||||
|
|
||||||
|
@ -24,26 +22,22 @@ stk_new (void)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void stk_free(stack s)
|
||||||
stk_free (stack s)
|
|
||||||
{
|
{
|
||||||
sfree(s->data);
|
sfree(s->data);
|
||||||
sfree(s);
|
sfree(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void stk_push(stack s, void *item)
|
||||||
stk_push (stack s, void *item)
|
|
||||||
{
|
|
||||||
if (s->size <= s->sp)
|
|
||||||
{
|
{
|
||||||
|
if (s->size <= s->sp) {
|
||||||
s->size = s->sp + 32;
|
s->size = s->sp + 32;
|
||||||
s->data = resize(s->data, s->size);
|
s->data = resize(s->data, s->size);
|
||||||
}
|
}
|
||||||
s->data[s->sp++] = item;
|
s->data[s->sp++] = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *stk_pop(stack s)
|
||||||
stk_pop (stack s)
|
|
||||||
{
|
{
|
||||||
if (s->sp > 0)
|
if (s->sp > 0)
|
||||||
return s->data[--s->sp];
|
return s->data[--s->sp];
|
||||||
|
@ -57,11 +51,9 @@ stk_pop (stack s)
|
||||||
const rdstring empty_rdstring = { 0, 0, NULL };
|
const rdstring empty_rdstring = { 0, 0, NULL };
|
||||||
const rdstringc empty_rdstringc = { 0, 0, NULL };
|
const rdstringc empty_rdstringc = { 0, 0, NULL };
|
||||||
|
|
||||||
void
|
void rdadd(rdstring * rs, wchar_t c)
|
||||||
rdadd (rdstring * rs, wchar_t c)
|
|
||||||
{
|
|
||||||
if (rs->pos >= rs->size - 1)
|
|
||||||
{
|
{
|
||||||
|
if (rs->pos >= rs->size - 1) {
|
||||||
rs->size = rs->pos + 128;
|
rs->size = rs->pos + 128;
|
||||||
rs->text = resize(rs->text, rs->size);
|
rs->text = resize(rs->text, rs->size);
|
||||||
}
|
}
|
||||||
|
@ -69,12 +61,10 @@ rdadd (rdstring * rs, wchar_t c)
|
||||||
rs->text[rs->pos] = 0;
|
rs->text[rs->pos] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void rdadds(rdstring * rs, wchar_t * p)
|
||||||
rdadds (rdstring * rs, wchar_t * p)
|
|
||||||
{
|
{
|
||||||
int len = ustrlen(p);
|
int len = ustrlen(p);
|
||||||
if (rs->pos >= rs->size - len)
|
if (rs->pos >= rs->size - len) {
|
||||||
{
|
|
||||||
rs->size = rs->pos + len + 128;
|
rs->size = rs->pos + len + 128;
|
||||||
rs->text = resize(rs->text, rs->size);
|
rs->text = resize(rs->text, rs->size);
|
||||||
}
|
}
|
||||||
|
@ -82,18 +72,15 @@ rdadds (rdstring * rs, wchar_t * p)
|
||||||
rs->pos += len;
|
rs->pos += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *
|
wchar_t *rdtrim(rdstring * rs)
|
||||||
rdtrim (rdstring * rs)
|
|
||||||
{
|
{
|
||||||
rs->text = resize(rs->text, rs->pos + 1);
|
rs->text = resize(rs->text, rs->pos + 1);
|
||||||
return rs->text;
|
return rs->text;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void rdaddc(rdstringc * rs, char c)
|
||||||
rdaddc (rdstringc * rs, char c)
|
|
||||||
{
|
|
||||||
if (rs->pos >= rs->size - 1)
|
|
||||||
{
|
{
|
||||||
|
if (rs->pos >= rs->size - 1) {
|
||||||
rs->size = rs->pos + 128;
|
rs->size = rs->pos + 128;
|
||||||
rs->text = resize(rs->text, rs->size);
|
rs->text = resize(rs->text, rs->size);
|
||||||
}
|
}
|
||||||
|
@ -101,12 +88,10 @@ rdaddc (rdstringc * rs, char c)
|
||||||
rs->text[rs->pos] = 0;
|
rs->text[rs->pos] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void rdaddsc(rdstringc * rs, char *p)
|
||||||
rdaddsc (rdstringc * rs, char *p)
|
|
||||||
{
|
{
|
||||||
int len = strlen(p);
|
int len = strlen(p);
|
||||||
if (rs->pos >= rs->size - len)
|
if (rs->pos >= rs->size - len) {
|
||||||
{
|
|
||||||
rs->size = rs->pos + len + 128;
|
rs->size = rs->pos + len + 128;
|
||||||
rs->text = resize(rs->text, rs->size);
|
rs->text = resize(rs->text, rs->size);
|
||||||
}
|
}
|
||||||
|
@ -114,28 +99,23 @@ rdaddsc (rdstringc * rs, char *p)
|
||||||
rs->pos += len;
|
rs->pos += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *rdtrimc(rdstringc * rs)
|
||||||
rdtrimc (rdstringc * rs)
|
|
||||||
{
|
{
|
||||||
rs->text = resize(rs->text, rs->pos + 1);
|
rs->text = resize(rs->text, rs->pos + 1);
|
||||||
return rs->text;
|
return rs->text;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int compare_wordlists(word * a, word * b)
|
||||||
compare_wordlists (word * a, word * b)
|
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
while (a && b)
|
while (a && b) {
|
||||||
{
|
|
||||||
if (a->type != b->type)
|
if (a->type != b->type)
|
||||||
return (a->type < b->type ? -1 : +1); /* FIXME? */
|
return (a->type < b->type ? -1 : +1); /* FIXME? */
|
||||||
t = a->type;
|
t = a->type;
|
||||||
if ((t != word_Normal && t != word_Code &&
|
if ((t != word_Normal && t != word_Code &&
|
||||||
t != word_WeakCode && t != word_Emph) || a->alt || b->alt)
|
t != word_WeakCode && t != word_Emph) || a->alt || b->alt) {
|
||||||
{
|
|
||||||
int c;
|
int c;
|
||||||
if (a->text && b->text)
|
if (a->text && b->text) {
|
||||||
{
|
|
||||||
c = ustricmp(a->text, b->text);
|
c = ustricmp(a->text, b->text);
|
||||||
if (c)
|
if (c)
|
||||||
return c;
|
return c;
|
||||||
|
@ -145,18 +125,17 @@ compare_wordlists (word * a, word * b)
|
||||||
return c;
|
return c;
|
||||||
a = a->next;
|
a = a->next;
|
||||||
b = b->next;
|
b = b->next;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
wchar_t *ap = a->text, *bp = b->text;
|
wchar_t *ap = a->text, *bp = b->text;
|
||||||
while (*ap && *bp)
|
while (*ap && *bp) {
|
||||||
{
|
|
||||||
wchar_t ac = utolower(*ap), bc = utolower(*bp);
|
wchar_t ac = utolower(*ap), bc = utolower(*bp);
|
||||||
if (ac != bc)
|
if (ac != bc)
|
||||||
return (ac < bc ? -1 : +1);
|
return (ac < bc ? -1 : +1);
|
||||||
if (!*++ap && a->next && a->next->type == t && !a->next->alt)
|
if (!*++ap && a->next && a->next->type == t
|
||||||
|
&& !a->next->alt)
|
||||||
a = a->next, ap = a->text;
|
a = a->next, ap = a->text;
|
||||||
if (!*++bp && b->next && b->next->type == t && !b->next->alt)
|
if (!*++bp && b->next && b->next->type == t
|
||||||
|
&& !b->next->alt)
|
||||||
b = b->next, bp = b->text;
|
b = b->next, bp = b->text;
|
||||||
}
|
}
|
||||||
if (*ap || *bp)
|
if (*ap || *bp)
|
||||||
|
@ -172,18 +151,14 @@ compare_wordlists (word * a, word * b)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void mark_attr_ends(paragraph * sourceform)
|
||||||
mark_attr_ends (paragraph * sourceform)
|
|
||||||
{
|
{
|
||||||
paragraph *p;
|
paragraph *p;
|
||||||
word *w, *wp;
|
word *w, *wp;
|
||||||
for (p = sourceform; p; p = p->next)
|
for (p = sourceform; p; p = p->next) {
|
||||||
{
|
|
||||||
wp = NULL;
|
wp = NULL;
|
||||||
for (w = p->words; w; w = w->next)
|
for (w = p->words; w; w = w->next) {
|
||||||
{
|
if (isattr(w->type)) {
|
||||||
if (isattr (w->type))
|
|
||||||
{
|
|
||||||
int before = (wp && isattr(wp->type) &&
|
int before = (wp && isattr(wp->type) &&
|
||||||
sameattr(wp->type, w->type));
|
sameattr(wp->type, w->type));
|
||||||
int after = (w->next && isattr(w->next->type) &&
|
int after = (w->next && isattr(w->next->type) &&
|
||||||
|
@ -197,21 +172,18 @@ mark_attr_ends (paragraph * sourceform)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wrappedline *
|
wrappedline *wrap_para(word * text, int width, int subsequentwidth,
|
||||||
wrap_para (word * text, int width, int subsequentwidth,
|
|
||||||
int (*widthfn) (word *))
|
int (*widthfn) (word *))
|
||||||
{
|
{
|
||||||
wrappedline *head = NULL, **ptr = &head;
|
wrappedline *head = NULL, **ptr = &head;
|
||||||
int nwords, wordsize;
|
int nwords, wordsize;
|
||||||
struct wrapword
|
struct wrapword {
|
||||||
{
|
|
||||||
word *begin, *end;
|
word *begin, *end;
|
||||||
int width;
|
int width;
|
||||||
int spacewidth;
|
int spacewidth;
|
||||||
int cost;
|
int cost;
|
||||||
int nwords;
|
int nwords;
|
||||||
}
|
} *wrapwords;
|
||||||
*wrapwords;
|
|
||||||
int i, j, n;
|
int i, j, n;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -219,17 +191,14 @@ wrap_para (word * text, int width, int subsequentwidth,
|
||||||
*/
|
*/
|
||||||
nwords = wordsize = 0;
|
nwords = wordsize = 0;
|
||||||
wrapwords = NULL;
|
wrapwords = NULL;
|
||||||
while (text)
|
while (text) {
|
||||||
{
|
if (nwords >= wordsize) {
|
||||||
if (nwords >= wordsize)
|
|
||||||
{
|
|
||||||
wordsize = nwords + 64;
|
wordsize = nwords + 64;
|
||||||
wrapwords = srealloc(wrapwords, wordsize * sizeof(*wrapwords));
|
wrapwords = srealloc(wrapwords, wordsize * sizeof(*wrapwords));
|
||||||
}
|
}
|
||||||
wrapwords[nwords].width = 0;
|
wrapwords[nwords].width = 0;
|
||||||
wrapwords[nwords].begin = text;
|
wrapwords[nwords].begin = text;
|
||||||
while (text)
|
while (text) {
|
||||||
{
|
|
||||||
wrapwords[nwords].width += widthfn(text);
|
wrapwords[nwords].width += widthfn(text);
|
||||||
wrapwords[nwords].end = text->next;
|
wrapwords[nwords].end = text->next;
|
||||||
if (text->next && (text->next->type == word_WhiteSpace ||
|
if (text->next && (text->next->type == word_WhiteSpace ||
|
||||||
|
@ -239,13 +208,10 @@ wrap_para (word * text, int width, int subsequentwidth,
|
||||||
text = text->next;
|
text = text->next;
|
||||||
}
|
}
|
||||||
if (text && text->next && (text->next->type == word_WhiteSpace ||
|
if (text && text->next && (text->next->type == word_WhiteSpace ||
|
||||||
text->next->type == word_EmphSpace))
|
text->next->type == word_EmphSpace)) {
|
||||||
{
|
|
||||||
wrapwords[nwords].spacewidth = widthfn(text->next);
|
wrapwords[nwords].spacewidth = widthfn(text->next);
|
||||||
text = text->next;
|
text = text->next;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
wrapwords[nwords].spacewidth = 0;
|
wrapwords[nwords].spacewidth = 0;
|
||||||
}
|
}
|
||||||
nwords++;
|
nwords++;
|
||||||
|
@ -258,8 +224,7 @@ wrap_para (word * text, int width, int subsequentwidth,
|
||||||
* nwords-1, determining the optimal wrapping for each terminal
|
* nwords-1, determining the optimal wrapping for each terminal
|
||||||
* subsequence of the paragraph.
|
* subsequence of the paragraph.
|
||||||
*/
|
*/
|
||||||
for (i = nwords; i--;)
|
for (i = nwords; i--;) {
|
||||||
{
|
|
||||||
int best = -1;
|
int best = -1;
|
||||||
int bestcost = 0;
|
int bestcost = 0;
|
||||||
int cost;
|
int cost;
|
||||||
|
@ -269,8 +234,7 @@ wrap_para (word * text, int width, int subsequentwidth,
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
seenspace = 0;
|
seenspace = 0;
|
||||||
while (i + j < nwords)
|
while (i + j < nwords) {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* See what happens if we put j+1 words on this line.
|
* See what happens if we put j+1 words on this line.
|
||||||
*/
|
*/
|
||||||
|
@ -279,8 +243,7 @@ wrap_para (word * text, int width, int subsequentwidth,
|
||||||
linelen += spacewidth + wrapwords[i + j].width;
|
linelen += spacewidth + wrapwords[i + j].width;
|
||||||
spacewidth = wrapwords[i + j].spacewidth;
|
spacewidth = wrapwords[i + j].spacewidth;
|
||||||
j++;
|
j++;
|
||||||
if (linelen > thiswidth)
|
if (linelen > thiswidth) {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* If we're over the width limit, abandon ship,
|
* If we're over the width limit, abandon ship,
|
||||||
* _unless_ there is no best-effort yet (which will
|
* _unless_ there is no best-effort yet (which will
|
||||||
|
@ -290,17 +253,14 @@ wrap_para (word * text, int width, int subsequentwidth,
|
||||||
if (best > 0)
|
if (best > 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i + j == nwords)
|
if (i + j == nwords) {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* Special case: if we're at the very end of the
|
* Special case: if we're at the very end of the
|
||||||
* paragraph, we don't score penalty points for the
|
* paragraph, we don't score penalty points for the
|
||||||
* white space left on the line.
|
* white space left on the line.
|
||||||
*/
|
*/
|
||||||
cost = 0;
|
cost = 0;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
cost = (thiswidth - linelen) * (thiswidth - linelen);
|
cost = (thiswidth - linelen) * (thiswidth - linelen);
|
||||||
cost += wrapwords[i + j].cost;
|
cost += wrapwords[i + j].cost;
|
||||||
}
|
}
|
||||||
|
@ -313,8 +273,7 @@ wrap_para (word * text, int width, int subsequentwidth,
|
||||||
* there's no point violating the Principle of Least
|
* there's no point violating the Principle of Least
|
||||||
* Surprise if it doesn't actually gain anything.
|
* Surprise if it doesn't actually gain anything.
|
||||||
*/
|
*/
|
||||||
if (best < 0 || bestcost >= cost)
|
if (best < 0 || bestcost >= cost) {
|
||||||
{
|
|
||||||
bestcost = cost;
|
bestcost = cost;
|
||||||
best = j;
|
best = j;
|
||||||
}
|
}
|
||||||
|
@ -332,8 +291,7 @@ wrap_para (word * text, int width, int subsequentwidth,
|
||||||
* `wrappedline' list.
|
* `wrappedline' list.
|
||||||
*/
|
*/
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < nwords)
|
while (i < nwords) {
|
||||||
{
|
|
||||||
wrappedline *w = mknew(wrappedline);
|
wrappedline *w = mknew(wrappedline);
|
||||||
*ptr = w;
|
*ptr = w;
|
||||||
ptr = &w->next;
|
ptr = &w->next;
|
||||||
|
@ -348,11 +306,9 @@ wrap_para (word * text, int width, int subsequentwidth,
|
||||||
*/
|
*/
|
||||||
w->nspaces = 0;
|
w->nspaces = 0;
|
||||||
w->shortfall = width;
|
w->shortfall = width;
|
||||||
for (j = 0; j < n; j++)
|
for (j = 0; j < n; j++) {
|
||||||
{
|
|
||||||
w->shortfall -= wrapwords[i + j].width;
|
w->shortfall -= wrapwords[i + j].width;
|
||||||
if (j < n - 1 && wrapwords[i + j].spacewidth)
|
if (j < n - 1 && wrapwords[i + j].spacewidth) {
|
||||||
{
|
|
||||||
w->nspaces++;
|
w->nspaces++;
|
||||||
w->shortfall -= wrapwords[i + j].spacewidth;
|
w->shortfall -= wrapwords[i + j].spacewidth;
|
||||||
}
|
}
|
||||||
|
@ -365,11 +321,9 @@ wrap_para (word * text, int width, int subsequentwidth,
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void wrap_free(wrappedline * w)
|
||||||
wrap_free (wrappedline * w)
|
|
||||||
{
|
|
||||||
while (w)
|
|
||||||
{
|
{
|
||||||
|
while (w) {
|
||||||
wrappedline *t = w->next;
|
wrappedline *t = w->next;
|
||||||
sfree(w);
|
sfree(w);
|
||||||
w = t;
|
w = t;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -125,8 +125,7 @@ void *index234 (tree234 * t, int index);
|
||||||
* for (p = NULL; (p = findrel234(tree, p, NULL, REL234_LT)) != NULL ;)
|
* for (p = NULL; (p = findrel234(tree, p, NULL, REL234_LT)) != NULL ;)
|
||||||
* consume(p);
|
* consume(p);
|
||||||
*/
|
*/
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
REL234_EQ, REL234_LT, REL234_LE, REL234_GT, REL234_GE
|
REL234_EQ, REL234_LT, REL234_LE, REL234_GT, REL234_GE
|
||||||
};
|
};
|
||||||
void *find234(tree234 * t, void *e, cmpfn234 cmp);
|
void *find234(tree234 * t, void *e, cmpfn234 cmp);
|
||||||
|
|
|
@ -6,29 +6,23 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "halibut.h"
|
#include "halibut.h"
|
||||||
|
|
||||||
wchar_t *
|
wchar_t *ustrdup(wchar_t * s)
|
||||||
ustrdup (wchar_t * s)
|
|
||||||
{
|
{
|
||||||
wchar_t *r;
|
wchar_t *r;
|
||||||
if (s)
|
if (s) {
|
||||||
{
|
|
||||||
r = mknewa(wchar_t, 1 + ustrlen(s));
|
r = mknewa(wchar_t, 1 + ustrlen(s));
|
||||||
ustrcpy(r, s);
|
ustrcpy(r, s);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
r = mknew(wchar_t);
|
r = mknew(wchar_t);
|
||||||
*r = 0;
|
*r = 0;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *ustrtoa(wchar_t * s, char *outbuf, int size)
|
||||||
ustrtoa (wchar_t * s, char *outbuf, int size)
|
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
if (!s)
|
if (!s) {
|
||||||
{
|
|
||||||
*outbuf = '\0';
|
*outbuf = '\0';
|
||||||
return outbuf;
|
return outbuf;
|
||||||
}
|
}
|
||||||
|
@ -41,8 +35,7 @@ ustrtoa (wchar_t * s, char *outbuf, int size)
|
||||||
return outbuf;
|
return outbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int ustrlen(wchar_t * s)
|
||||||
ustrlen (wchar_t * s)
|
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
while (*s++)
|
while (*s++)
|
||||||
|
@ -50,26 +43,22 @@ ustrlen (wchar_t * s)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *
|
wchar_t *uadv(wchar_t * s)
|
||||||
uadv (wchar_t * s)
|
|
||||||
{
|
{
|
||||||
return s + 1 + ustrlen(s);
|
return s + 1 + ustrlen(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *
|
wchar_t *ustrcpy(wchar_t * dest, wchar_t * source)
|
||||||
ustrcpy (wchar_t * dest, wchar_t * source)
|
|
||||||
{
|
{
|
||||||
wchar_t *ret = dest;
|
wchar_t *ret = dest;
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
*dest++ = *source;
|
*dest++ = *source;
|
||||||
}
|
}
|
||||||
while (*source++);
|
while (*source++);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int ustrcmp(wchar_t * lhs, wchar_t * rhs)
|
||||||
ustrcmp (wchar_t * lhs, wchar_t * rhs)
|
|
||||||
{
|
{
|
||||||
if (!lhs && !rhs)
|
if (!lhs && !rhs)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -86,8 +75,7 @@ ustrcmp (wchar_t * lhs, wchar_t * rhs)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t
|
wchar_t utolower(wchar_t c)
|
||||||
utolower (wchar_t c)
|
|
||||||
{
|
{
|
||||||
if (c == L'\0')
|
if (c == L'\0')
|
||||||
return c; /* this property needed by ustricmp */
|
return c; /* this property needed by ustricmp */
|
||||||
|
@ -97,8 +85,7 @@ utolower (wchar_t c)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int ustricmp(wchar_t * lhs, wchar_t * rhs)
|
||||||
ustricmp (wchar_t * lhs, wchar_t * rhs)
|
|
||||||
{
|
{
|
||||||
wchar_t lc, rc;
|
wchar_t lc, rc;
|
||||||
while ((lc = utolower(*lhs)) == (rc = utolower(*rhs)) && lc && rc)
|
while ((lc = utolower(*lhs)) == (rc = utolower(*rhs)) && lc && rc)
|
||||||
|
@ -111,33 +98,28 @@ ustricmp (wchar_t * lhs, wchar_t * rhs)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *
|
wchar_t *ustrlow(wchar_t * s)
|
||||||
ustrlow (wchar_t * s)
|
|
||||||
{
|
{
|
||||||
wchar_t *p = s;
|
wchar_t *p = s;
|
||||||
while (*p)
|
while (*p) {
|
||||||
{
|
|
||||||
*p = utolower(*p);
|
*p = utolower(*p);
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int utoi(wchar_t * s)
|
||||||
utoi (wchar_t * s)
|
|
||||||
{
|
{
|
||||||
int sign = +1;
|
int sign = +1;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (*s == L'-')
|
if (*s == L'-') {
|
||||||
{
|
|
||||||
s++;
|
s++;
|
||||||
sign = -1;
|
sign = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
while (*s && *s >= L'0' && *s <= L'9')
|
while (*s && *s >= L'0' && *s <= L'9') {
|
||||||
{
|
|
||||||
n *= 10;
|
n *= 10;
|
||||||
n += (*s - '0');
|
n += (*s - '0');
|
||||||
s++;
|
s++;
|
||||||
|
@ -146,8 +128,7 @@ utoi (wchar_t * s)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int utob(wchar_t * s)
|
||||||
utob (wchar_t * s)
|
|
||||||
{
|
{
|
||||||
if (!ustricmp(s, L"yes") || !ustricmp(s, L"y") ||
|
if (!ustricmp(s, L"yes") || !ustricmp(s, L"y") ||
|
||||||
!ustricmp(s, L"true") || !ustricmp(s, L"t"))
|
!ustricmp(s, L"true") || !ustricmp(s, L"t"))
|
||||||
|
@ -155,15 +136,13 @@ utob (wchar_t * s)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int uisdigit(wchar_t c)
|
||||||
uisdigit (wchar_t c)
|
|
||||||
{
|
{
|
||||||
return c >= L'0' && c <= L'9';
|
return c >= L'0' && c <= L'9';
|
||||||
}
|
}
|
||||||
|
|
||||||
#define USTRFTIME_DELTA 128
|
#define USTRFTIME_DELTA 128
|
||||||
wchar_t *
|
wchar_t *ustrftime(wchar_t * wfmt, struct tm * timespec)
|
||||||
ustrftime (wchar_t * wfmt, struct tm * timespec)
|
|
||||||
{
|
{
|
||||||
void *blk = NULL;
|
void *blk = NULL;
|
||||||
wchar_t *wblk, *wp;
|
wchar_t *wblk, *wp;
|
||||||
|
@ -178,18 +157,15 @@ ustrftime (wchar_t * wfmt, struct tm * timespec)
|
||||||
* generate the empty string. Somebody throw a custard pie at
|
* generate the empty string. Somebody throw a custard pie at
|
||||||
* whoever was responsible for that. Please?
|
* whoever was responsible for that. Please?
|
||||||
*/
|
*/
|
||||||
if (wfmt)
|
if (wfmt) {
|
||||||
{
|
|
||||||
len = ustrlen(wfmt);
|
len = ustrlen(wfmt);
|
||||||
fmt = mknewa(char, 2 + len);
|
fmt = mknewa(char, 2 + len);
|
||||||
ustrtoa(wfmt, fmt + 1, len + 1);
|
ustrtoa(wfmt, fmt + 1, len + 1);
|
||||||
fmt[0] = ' ';
|
fmt[0] = ' ';
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
fmt = " %c";
|
fmt = " %c";
|
||||||
|
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
|
||||||
size += USTRFTIME_DELTA;
|
size += USTRFTIME_DELTA;
|
||||||
blk = resize((char *) blk, size);
|
blk = resize((char *) blk, size);
|
||||||
len = strftime((char *) blk, size - 1, fmt, timespec);
|
len = strftime((char *) blk, size - 1, fmt, timespec);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -118,8 +118,7 @@ void whlp_begin_topic (WHLP h, WHLP_TOPIC topic, char *title, ...);
|
||||||
* descriptor you create, but you could work this out just as
|
* descriptor you create, but you could work this out just as
|
||||||
* easily yourself by counting.
|
* easily yourself by counting.
|
||||||
*/
|
*/
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
WHLP_FONT_BOLD = 1,
|
WHLP_FONT_BOLD = 1,
|
||||||
WHLP_FONT_ITALIC = 2,
|
WHLP_FONT_ITALIC = 2,
|
||||||
WHLP_FONT_UNDERLINE = 4,
|
WHLP_FONT_UNDERLINE = 4,
|
||||||
|
@ -127,8 +126,7 @@ enum
|
||||||
WHLP_FONT_DOUBLEUND = 16,
|
WHLP_FONT_DOUBLEUND = 16,
|
||||||
WHLP_FONT_SMALLCAPS = 32
|
WHLP_FONT_SMALLCAPS = 32
|
||||||
};
|
};
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
WHLP_FONTFAM_FIXED = 1,
|
WHLP_FONTFAM_FIXED = 1,
|
||||||
WHLP_FONTFAM_SERIF = 2,
|
WHLP_FONTFAM_SERIF = 2,
|
||||||
WHLP_FONTFAM_SANS = 3,
|
WHLP_FONTFAM_SANS = 3,
|
||||||
|
@ -148,18 +146,15 @@ int whlp_create_font (WHLP h, char *font, int family, int halfpoints,
|
||||||
* whole paragraph, and finally call whlp_end_para() to finish it
|
* whole paragraph, and finally call whlp_end_para() to finish it
|
||||||
* off.
|
* off.
|
||||||
*/
|
*/
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
WHLP_PARA_SPACEABOVE = 1, WHLP_PARA_SPACEBELOW, WHLP_PARA_SPACELINES,
|
WHLP_PARA_SPACEABOVE = 1, WHLP_PARA_SPACEBELOW, WHLP_PARA_SPACELINES,
|
||||||
WHLP_PARA_LEFTINDENT, WHLP_PARA_RIGHTINDENT, WHLP_PARA_FIRSTLINEINDENT,
|
WHLP_PARA_LEFTINDENT, WHLP_PARA_RIGHTINDENT, WHLP_PARA_FIRSTLINEINDENT,
|
||||||
WHLP_PARA_ALIGNMENT
|
WHLP_PARA_ALIGNMENT
|
||||||
};
|
};
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
WHLP_ALIGN_LEFT, WHLP_ALIGN_RIGHT, WHLP_ALIGN_CENTRE
|
WHLP_ALIGN_LEFT, WHLP_ALIGN_RIGHT, WHLP_ALIGN_CENTRE
|
||||||
};
|
};
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
WHLP_PARA_SCROLL, WHLP_PARA_NONSCROLL
|
WHLP_PARA_SCROLL, WHLP_PARA_NONSCROLL
|
||||||
};
|
};
|
||||||
void whlp_para_attr(WHLP h, int attr_id, int attr_param);
|
void whlp_para_attr(WHLP h, int attr_id, int attr_param);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue