diff --git a/Docs/src/bin/halibut/bk_xhtml.c b/Docs/src/bin/halibut/bk_xhtml.c index de874fcb..6f71f5a5 100644 --- a/Docs/src/bin/halibut/bk_xhtml.c +++ b/Docs/src/bin/halibut/bk_xhtml.c @@ -864,6 +864,7 @@ xhtml_backend(paragraph * sourceform, keywordlist * in_keywords, sfree(conf.fsect[i].number_suffix); sfree(conf.fsect); } + free_ustr_slist(conf.meta_append); } static int xhtml_para_level(paragraph * p) diff --git a/Docs/src/bin/halibut/halibut.h b/Docs/src/bin/halibut/halibut.h index a0ab4c33..07abf19c 100644 --- a/Docs/src/bin/halibut/halibut.h +++ b/Docs/src/bin/halibut/halibut.h @@ -1,6 +1,10 @@ #ifndef HALIBUT_HALIBUT_H #define HALIBUT_HALIBUT_H +#ifdef _WIN32 +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + #include #include #include @@ -92,6 +96,7 @@ struct paragraph_Tag { void *private_data; /* for temp use in backends */ }; +#define initpara(p) ( (p).type = para_NotParaType, (p).keyword = NULL, (p).words = NULL ) enum { para_IM, /* index merge */ para_BR, /* bibliography rewrite */ @@ -232,6 +237,7 @@ void *smalloc(int size); void *srealloc(void *p, int size); void sfree(void *p); #endif +void free_list(void*p); void free_word_list(word * w); void free_para_list(paragraph * p); word *dup_word_list(word * w); @@ -256,11 +262,13 @@ wchar_t *ustrcpy(wchar_t * dest, const wchar_t * source); wchar_t utolower(wchar_t); int ustrcmp(const wchar_t * lhs, const wchar_t * rhs); int ustricmp(const wchar_t * lhs, const wchar_t * rhs); +void ultou(unsigned long v, wchar_t *o); int utoi(const wchar_t *); int utob(const wchar_t *); int uisdigit(wchar_t); wchar_t *ustrlow(wchar_t * s); wchar_t *ustrftime(wchar_t * fmt, struct tm *timespec); +#define free_ustr_slist free_list ustr_slist* ustr_slist_append(ustr_slist**headaddr, const wchar_t*str); /* @@ -321,6 +329,7 @@ struct tagWrappedLine { }; wrappedline *wrap_para(word *, int, int, int (*)(word *)); void wrap_free(wrappedline *); +unsigned long getutcunixtime(); /* * input.c diff --git a/Docs/src/bin/halibut/input.c b/Docs/src/bin/halibut/input.c index cca822e6..a4d1a149 100644 --- a/Docs/src/bin/halibut/input.c +++ b/Docs/src/bin/halibut/input.c @@ -175,12 +175,16 @@ enum { tok_rbrace /* } */ }; +#define tokiscmd(t,c) ( (t).type == tok_cmd && (t).cmd == (c) ) + /* Halibut command keywords. */ enum { c__invalid, /* invalid command */ c__comment, /* comment command (\#) */ c__escaped, /* escaped character */ + c__nop, /* no-op */ c__nbsp, /* nonbreaking space */ + c__midparacmd_unixnow, c_A, /* appendix heading */ c_B, /* bibliography entry */ c_BR, /* bibliography rewrite */ @@ -215,6 +219,13 @@ enum { c_versionid /* document RCS id */ }; +#define getcmdstyle(c) \ + (c) == c_c ? word_Code : \ + (c) == c_cw ? word_WeakCode : \ + (c) == c_e ? word_Emph : \ + word_Normal + + /* Perhaps whitespace should be defined in a more Unicode-friendly way? */ #define iswhite(c) ( (c)==32 || (c)==9 || (c)==13 || (c)==10 ) #define isnl(c) ( (c)==10 ) @@ -260,6 +271,7 @@ static void match_kw(token * tok) { "-", c__escaped} , /* nonbreaking hyphen */ + { ".", c__nop }, { "A", c_A} , /* appendix heading */ @@ -326,6 +338,7 @@ static void match_kw(token * tok) { "e", c_e} , /* emphasis */ + { "hackunixnow", c__midparacmd_unixnow }, { "i", c_i} , /* visible index mark */ @@ -474,7 +487,7 @@ token get_token(input * in) { /* tok_cmd */ c = get(in, &cpos); if (c == '-' || c == '\\' || c == '_' || - c == '#' || c == '{' || c == '}') + c == '#' || c == '{' || c == '}' || c == '.') { /* single-char command */ rdadd(&rs, (wchar_t)c); @@ -635,6 +648,36 @@ static paragraph *addpara(paragraph newpara, paragraph *** hptrptr) */ #define dtor(t) ( sfree(t.text) ) +static int is_special_midpara_cmd(token*t) +{ + return tokiscmd(*t, c__midparacmd_unixnow); +} + +static int handle_special_midpara_cmd(token*t, rdstring*rs, paragraph ***hptrptr) +{ + wchar_t wbuf[100]; + paragraph par; + + if (t->type != tok_cmd) return 0; + initpara(par); + par.fpos = t->pos; + switch(t->cmd) + { + case c__midparacmd_unixnow: + ultou(getutcunixtime(), wbuf); + rdadds(rs, wbuf); + return 1; + } + return 0; +} + +#define stack_item_push(stck__, sitype__) do { \ + struct stack_item *si__ = mknew(struct stack_item); \ + si__->type = sitype__; \ + stk_push((stck__), si__); \ + } while(!__LINE__) + + /* * Reads a single file (ie until get() returns EOF) */ @@ -644,7 +687,7 @@ static void read_file(paragraph *** ret, input * in, indexdata * idx, tree234 *m paragraph par; word wd, **whptr, **idximplicit; wchar_t utext[2], *wdtext; - int style, spcstyle; + int style, spcstyle, tmpstyle; int already; int iswhite, seenwhite; int type; @@ -883,12 +926,14 @@ static void read_file(paragraph *** ret, input * in, indexdata * idx, tree234 *m t.type == tok_word || t.type == tok_white || (t.type == tok_cmd && t.cmd == c__nbsp) || - (t.type == tok_cmd && t.cmd == c__escaped)) + (t.type == tok_cmd && t.cmd == c__escaped) || + /* TODO: Merge from upstream?: (t.type == tok_cmd && t.cmd == c_u) || */ + is_special_midpara_cmd(&t)) { if (t.type == tok_white || (t.type == tok_cmd && t.cmd == c__nbsp)) rdadd(&rs, ' '); - else + else if (!handle_special_midpara_cmd(&t, &rs, ret)) rdadds(&rs, t.text); } if (t.type != tok_rbrace) @@ -994,6 +1039,10 @@ static void read_file(paragraph *** ret, input * in, indexdata * idx, tree234 *m break; } + if (t.type == tok_cmd && t.cmd == c__nop) { + dtor(t), t = get_token(in); + continue; /* do nothing! */ + } if (t.type == tok_cmd && t.cmd == c__escaped) { t.type = tok_word; /* nice and simple */ @@ -1283,15 +1332,13 @@ static void read_file(paragraph *** ret, input * in, indexdata * idx, tree234 *m */ sitem = mknew(struct stack_item); sitem->type = stack_hyper; - if (t.type == tok_cmd && - (t.cmd == c_e || t.cmd == c_c || t.cmd == c_cw)) + if (t.type == tok_cmd && (tmpstyle = getcmdstyle(t.cmd))) { if (style != word_Normal) error(err_nestedstyles, &t.pos); else { - style = (t.cmd == c_c ? word_Code : - t.cmd == c_cw ? word_WeakCode : word_Emph); + style = tmpstyle; spcstyle = tospacestyle(style); sitem->type |= stack_style; } @@ -1326,8 +1373,7 @@ static void read_file(paragraph *** ret, input * in, indexdata * idx, tree234 *m error(err_explbr, &t.pos); } else { - style = (type == c_c ? word_Code : - type == c_cw ? word_WeakCode : word_Emph); + style = getcmdstyle(type); spcstyle = tospacestyle(style); sitem = mknew(struct stack_item); sitem->type = stack_style; @@ -1354,15 +1400,13 @@ static void read_file(paragraph *** ret, input * in, indexdata * idx, tree234 *m * Special cases: \i\c, \i\e, \i\cw */ wd.fpos = t.pos; - if (t.type == tok_cmd && - (t.cmd == c_e || t.cmd == c_c || t.cmd == c_cw)) + if (t.type == tok_cmd && (tmpstyle = getcmdstyle(t.cmd))) { if (style != word_Normal) error(err_nestedstyles, &t.pos); else { - style = (t.cmd == c_c ? word_Code : - t.cmd == c_cw ? word_WeakCode : word_Emph); + style = tmpstyle; spcstyle = tospacestyle(style); sitem->type |= stack_style; } diff --git a/Docs/src/bin/halibut/main.c b/Docs/src/bin/halibut/main.c index 2b413d9e..a80c0417 100644 --- a/Docs/src/bin/halibut/main.c +++ b/Docs/src/bin/halibut/main.c @@ -20,6 +20,9 @@ int main(int argc, char **argv) int errs; int reportcols; int debug; +#ifdef C_ASSERT + { C_ASSERT(!word_Normal); /* For getcmdstyle */ } +#endif initversionstring(); diff --git a/Docs/src/bin/halibut/malloc.c b/Docs/src/bin/halibut/malloc.c index 24cb6765..90ee658d 100644 --- a/Docs/src/bin/halibut/malloc.c +++ b/Docs/src/bin/halibut/malloc.c @@ -129,6 +129,20 @@ word *dup_word_list(word * w) return head; } +/* + * Free a generic linked list + */ +void free_list(void*p) +{ + void *s = p, *n; + for (; p; p = n) + { + n = *(void**) p; /* Assmumes next pointer is the first member! */ + if (n == s) n = NULL; /* Around the ring? */ + sfree(p); + } +} + /* * Free a linked list of words */ diff --git a/Docs/src/bin/halibut/misc.c b/Docs/src/bin/halibut/misc.c index 5fad528d..83d4ba78 100644 --- a/Docs/src/bin/halibut/misc.c +++ b/Docs/src/bin/halibut/misc.c @@ -2,6 +2,7 @@ * misc.c: miscellaneous useful items */ #include +#include #include "halibut.h" struct stackTag { @@ -355,3 +356,21 @@ void wrap_free(wrappedline * w) w = t; } } + +unsigned long getutcunixtime() +{ +#ifndef _WIN32 + struct timespec ts; + ts.tv_sec = 0; + /* gettimeofday()? */ +#if (_XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 199309L) + if (0 == clock_gettime(CLOCK_REALTIME, &ts)) + return ts.tv_sec; +#endif +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L + if (timespec_get(&ts, TIME_UTC)) /* implementation defined epoch :( */ + return ts.tv_sec; +#endif +#endif /*~ _WIN32 */ + return (unsigned long) time(NULL); +} diff --git a/Docs/src/bin/halibut/ustring.c b/Docs/src/bin/halibut/ustring.c index b4e0a050..63c68dbd 100644 --- a/Docs/src/bin/halibut/ustring.c +++ b/Docs/src/bin/halibut/ustring.c @@ -2,9 +2,17 @@ * ustring.c: Unicode string routines */ +#include "halibut.h" #include #include -#include "halibut.h" +#include + +static void asciitou(wchar_t *dest, const char *src) +{ + for (;;) + if (!(*dest++ = *src++)) + break; +} wchar_t *ustrdup(const wchar_t * s) { @@ -119,6 +127,13 @@ wchar_t *ustrlow(wchar_t * s) return s; } +void ultou(unsigned long v, wchar_t *o) +{ + char buf[42]; + sprintf(buf, "%lu", v); + asciitou(o, buf); +} + int utoi(const wchar_t *s) { int sign = +1; diff --git a/Docs/src/config_web.but b/Docs/src/config_web.but index c9d7555f..bed94434 100644 --- a/Docs/src/config_web.but +++ b/Docs/src/config_web.but @@ -11,6 +11,6 @@ \cfg{xhtml-contents-depth-0}{3} -\cfg{xhtml-head-end}{} +\cfg{xhtml-head-end}{} \cfg{xhtml-body-end}{SourceForge Logo} diff --git a/Docs/unreleased.png b/Docs/unreleased.png index f3d4a719..3e61a975 100644 Binary files a/Docs/unreleased.png and b/Docs/unreleased.png differ