yodl-3.06.00/AUTHORS.txt0000644000175000017500000000143312573350734013513 0ustar frankfrank AUTHORS - who did what on Yodl? This file lists authors of Yodl, in alphabetical order. o Frank Brokken , Original and current (2004- ) author. o Kees de Bruin , Html- and various other fixes. o Jan Nieuwenhuizen , http://www.xs4all.nl/~jantien/ Main author and maintainer. o Karel Kubat , http://www.icce.rug.nl/karel/karel.html Original author and brainfather. Likes to receive postcards: Karel Kubat Rietveldlaan 37 9731 MJ Groningen The Netherlands o Jeffrey B. Reed , Windows-nt, StepMake fixes. o Paulo da Silva Little contribu- tion for internationalization. yodl-3.06.00/CHANGES0000644000175000017500000005053712573350734012631 0ustar frankfrank**** 2.00 Yodl version 2.00 is the result of a complete rebuild. It differs from the previous (1.31) version in the following aspects: - Added the following new commands: ADDTOSYMBOL - adds text to a symbol's value DEFINESYMBOLVALUE - defines a symbol and its initial value DELETECOUNTER - opposite from NEWCOUNTER: removes an existing IFBUILTIN - checks whether the argument is a builtin macro IFCOUNTER - checks whether the argument is a defined counter IFEQUAL - checks whether two numerical values are equal IFGREATER - checks whether the first numerical value exceeds the second numerical value IFMACRO - checks whether the argument is a defined macro IFSMALLER - checks whether the first numerical value is smaller than the second numerical value IFSYMBOL - checks whether the argument is a defined symbol PATHINCLUDELIT - includes literaly a file found in the XXincludepath path POPCOUNTER - pops a previously pushed countervalue POPMACRO - pops a previously pushed macrodefinition POPSYMBOL - pops a previously pushed symbolvalue PUSHCOUNTER - pushes the current value of a counter, initilaizes the active counter to 0 PUSHCOUNTERVALUE - pushes the current value of a counter, initilaizes the active counter to any value PUSHMACRO - pushes the current definition of a macro, activates a local redefinition PUSHSYMBOL - pushes the current value of a symbol, initializing the active value to an empty string. SETSYMBOL - assigns a new value to a symbol SYMBOLVALUE - returns the value of a symbol as text. - The following commands are now obsolete: ENDDEF - DECWSLEVEL should be used INCLUDELIT - NOEXPANDINCLUDE should be used STARTDEF - INCWSLEVEL should be used NEWCOUNTER - DEFINECOUNTER should be used UNDEFINEMACRO - DELETEMACRO should be used WRITEOUT - FPUTS should be used - Several macros are now deprecated. Alternatives are suggested in the `man yodlmacros' manpage. A (possibly non-exhaustive) list of deprecated macros is: enddit() endeit() endit() endmenu() endtable() enumerate(list) itemize(list) menu(list) mit() node(previous)(this)(next)(up) startcenter() startdit() starteit() startit() startmenu() starttable(nColumns)(LaTexAllignment) - XXincludePath - Symbol installed by Yodl itself, but modifiable by the user: It holds the value of the current :-separated list of directories that are visited (sequentially) by the INCLUDEFILE command. XXincludePath may contain $HOME, which will be replaced by the user's home directory if the `home' or `HOME' environment variable is defined. It may also contain $STD_INCLUDE, which will be replaced by the compilation defined standard include path. The standard includepath may be overruled by either (in that order) the command line switch -I or the YODL_INCLUDE_PATH environment variable. By default, the current directory is added to the standard include path. When -I or YODL_INCLUDE_PATH is used, the current directory must be mentioned explicitly. The individual directories need not be terminated by a /-character. In the distributed .deb archive, the standard directory is defined as /usr/share/yodl (prefixed by the current working directory). - Initial blank lines in the generated document are suppressed by default. - Command line argument -D also allows the assignment of an initial value to a symbol - Command line argument -P is now -p, the previously defined -p argument is now -n (--max-nested-files), defining the maximum number of nested files yodl will process. - Command line argument -r (--max-replacements) defines the maximum number of macro and/or subst replacements accepted between consecutive characters read from file(s). - All assignents to counters (SETCOUNTER, ADDTOCOUNTER, etc.) not only accept numerical arguments, but also counter names. - Rewrote several awkwardly coded macros, using the new SYMBOL and COUNTER facilities - Added experimental, very limited, xml support to help me generating xml for the horrible `webplatform' of the university of Groningen. But at least Yodl now offers xml support as well. - Changed Yodl's name expansion. From `Yet Oneother Document Language' to: Your Own Document Language That's MUCH better, isn't it? - Upgraded most of the documentation accordingly - Separated yodl-macro files for the various formats. While this might not strictly be necessary, I feel this is better than using big fat generic macro definition files which are bloated with `whenhtml(), whentxt()' macros. I introduced a generic frame, mentioning the macros that must at least be defined by the individual formats. - Internally, the software was VASTLY reorganized. I feel that a lot of C-code doesn't benefit from approaches that have become quite natural for C++ programmers. I had the choice to either rewrite Yodl to a C++ program or to reprogram Yodl in the line of C++, but still using C. I opted for the latter. So, now the src/lib section contains `object-like' function families, like `countermap_...()' handling all counte-related operations, `textvector_...()', handling all text-vector like operations, and other. Other functions reveived minor modifications. E.g., xrealloc() now requires you to specify both the number of elements and the size of the elements. By doing so, it is sheer impossible to overlook the fact that you have to specify the size of the elements, thus preventing the allocation of chars when, e.g., ints are required. - An old inconvenience was removed: line number counting is now using natural numbers, starting at 1, rather than line indices, starting at 0. - All over the place my old email address is still mentioned. Discard it, and as of now, use: "Frank B. Brokken" - The post processing is now performed by the program `yodlpost'. This program again used Design Patterns originally developed for object oriented contexts, resulting in an program that is easy to maintain. modify and expand. - The basic conversion formats now supported are html, latex, man, and text. Xml support is experimental, other formats are no longer supported, mainly because my personal unfamiliarity with the format (texinfo), or because the format appears to be somewhat obsolete (sgml). - Added a Yodl document type `letter', indended to be used with the `brief.cls' LaTeX documentclass - Yodl 2.00 converts documents much faster than earlier versions. ******** 1.31.18 - bf: texinfo: use @ref iso @xref - texinfo: bind() - bf: info - texinfo: table() row() cell() - sm: 81 - bf: internal html links (AARGH) * disabled checking for libgen's weird type of basename () * don't use libgen's broken basename () - 2texinfo: url-> uref iso url - New macros for internationalization added (Paulo da Silva) - html table with new characters (Paulo da Silva) ******** 1.31.17 - 2man: verb*() fixed - 2texinfo fixes: @top, Toplevel, \input texinfo - 2tely: mudela() -> @mudela - 2texinfo: nicer handling of wierd nodenames ... NOT: see comment in yodl2texinfo-post.py: urg ******** 1.31.16 - bf: warning/sgml Forgot to send these patches as well (albert chin) - IRIX has snprintf and vsnprintf but you never check for these functions in configure. You redefine them in src/lib/libc-extensions.c - Need to include if linking with -lgen ******* 1.31.15 - embarrassing bug + ugly fix: macros > 8kB - sm79: aix empty sed script fix ******** 1.31.14 - yodl2ms*: no adjustment (thanks: *W Nienhuys) ******** 1.31.13 - sm77 - bf's: yodl2texinfo-post.py - bf: .spec file: include yodl2texinfo-post - IRIX: check for basename in libgen - man/man7 fix ********* 1.31.12 - sm 74 - removed C++ comments 1.31.11 - hsearch turned off - included hsearch glibc sources: manually install libhsearch, for easy profiling - debian fixes (Anthony Fok) - sm 71 - max size of hashtables set in config.hh.in - bf: yodl2msps etc, use groff (or ditroff) iso troff - bf: only include libintl if HAVE_GETTEXT - smarter builtin lookup - use hash table: speed drops by factor 2 :-( - bf: strup call to basename (thanks, Nick Glencross) 1.31.10 - bf: yodl2texinfo: (no) missing xrefs - bf: mudela mode ********* 1.31.9 - moved ftp site: ftp://ftp.lilypond.org/pub/yodl - fixed ms/man table support, see: yodl2msless Documentation/test/table.yo | striproff - bf: ms/man output: use tbl preprocessor - stepmake 67, check for tbl, gmake - bf: latex email, url - bf: yodl2msps.sh ********* 1.31.8 - stepmake 63 - slashed o/O: \/o \/O (Stephan Petersen) - debian fixes by Anthony - bf: installscript comments in scripts - bf: use tmac.s iso tmac.gs (GNU s): troff -ms - bf: scripts: replaced ${word%%pattern} with sed script urg, urg: all these flavours of /bin/sh et al. ********* 1.31.7 - remove ugly empty lines, with uniq... - installable stepmake pl57..59 - fixed first time build again for msless - (re)added manpage yodlmacros.7 - bf's: macrodoc - bf's: shared doc sections - latex char translations (thanks, Adrian) 1.31.6.hwn1 - don't append \\NoLilyFooter to lilypond output (?) 1.31.6.hwn1 - don't put configure stuff in doco ********* 1.31.6 - urg: texinfo only: manpage, macrolist commented-out - bf: yodl2texinfo `\\` - sm 52, fixing striproff install 1.31.5.hwn1 - bf: spec 1.31.5.jbr1 - aclocal.m4,stepmake/aclocal.m4: allow developer to select which python - stepmake/bin/release.py: call package-diff.py with the same executable as release.py ********** 1.31.5 - latex: don't use math version of '*' - drop \tt front from special latex chars - process bin dir later - bf: bin/exe links - latex:code revisited (ta, adrian) 1.31.4.jbr1 - scripts/yodl2manless: slipped a \ - src/yodl/grampipethrough.c: ... the anticipation is killing Jan ;) - Fixed initilization error in NT hack. ********** 1.31.4 - don't make texinfo by default - latex code(%{) fix reverted (duh) - website fixes - gif -> png - website - embedded mudela 1.31.3.jbr1 - bin/GNUmakefile: added (DOTEXE) and - rejected: fix relative path to ../src/out ********* 1.31.3 - bf's: yodl2texinfo-post - fixed latex code(%{) (thanks Adrian) - new macro: setlatexverbchar() - sm 49 - macro doc fixes - renamed output-commands to format-macros - striproff for roff'd txt formatting (yodl2msless x | striproff) - junked bash stuff from scripts/* - 2less fixes - (experimental...) pipethrough really pipes, thanks JBR - took debian/control,copyright changes to *.in source files 1.31.2.jbr2 -src/yodl/message.c: va_end is doesn't do much on alot of platforms, but it is proper. -src/yodl/grampipethrough.c: Major NT hack. The popen on NT seems to be leaking process slots. With this patch I can at least build lilypond tutorial. -src/scripts/yodl2whatever: pass -v as switch to yodl to enable debugging 1.31.2.af1 - debian fixes 1.31.2.jbr1 - src/yodl/grampipethrough.c: A popen _must_ be closed with a pclose _not_ a fclose. Pipes were never getting closed on Windows NT cygnus. 1.31.2.jcn1 - sm 47 - texinfo fix *********** 1.31.2 - texinfo doc - stepmake 46 - disabled all xrefs in texinfo (makeinfo doesn't forgive human mistakes) 1.31.jcn1 - all texinfo doco - bf' texinfo: tt(), subsubsubsect(), quotation() - texinfo helper macros: nodename, nodetext, nodeprefix - yodl2texinfo-post.py - junked old scripts - < hacking at yodl2texinfo > - stepmake 44 (bedankt, lieverd) 1.31.1.jbr1 - aclocal.m4,stepmake/aclocal.m4,stepmake/stepmake/Variables.make: Install command scheme that supports UNIX, UNIX cross-compile and Windows-NT ********* 1.31.1 - BASH -> SHELL - declare realloc/malloc/free after make-3.75 1.31.0.hwn1 - stepmake .41 1.31.0 - Major release - rpm, zip doco list fixes 1.30.18 - bf: mudela use book-init iso init (HWN) - digicash.com -> cs.uu - website fixes - revised ANNOUNCE, AUTHORS.yo ********* 1.30.17 - bf: OUTDIR - top of web, - fixes: mudela fine counter 1.30.16 - bf's: fine counter - checking mudela diff ******** 1.30.15 - bf's website - added hw's yodl page - janneke@gnu.org - mudela: reset fine counter - (step)make fixes - shared-mudela: irix echo fix - latex bf's: ~ \ < > (HWN) ********* 1.30.14 - handier versioning: major release will be 1.31.0 - ANNOUNCE draft - \Tex \LaTeX fixes (HW+JC) - latex: file() fix (HWN) - verbosity switch for yodl2whatever (HWN) - ps-to-gifs fix (HWN) - bf: bash-2.x empty info install - (step)make fixes - html PARAGRAPH: changed "


" to "

": a single "

" should be the right thing to appear in such cases, as "


" adds too much vertical whitespace to a text (SP) - bf: toc html ********* 1.30.pre13 - bf: real simple and obvious silly enumcounter fix - bf's: website - lily's Documentation layout - bf: spec - stepmake uses just-built yodl too 1.30.0.pre12 - doco fixes - currbase alloc (JBR) 1.30.0.pre11 - -d, --definemacro=NAME=EXPANSION\n" (HWN) ********* 1.30.0.pre10 - bf: yodl2dvi (KDB) - world.xpm - bf: yodl.yo.in: latexpackage()() - bf: yodl2xless - bf: latex2.yo.in -> latex2.yodoc.in ********* 1.30.0.pre9 - bf: spec assumes cwd in PATH (KDB) - latex2e support: * \xx to \textxx{ }; \em to \emph{ } * yodl2latex converts to latex2e * yodl2tex and latex2 depreciated - dpkg-shlibdeps: warning: unknown output from ldd on `debian/tmp/usr/bin/yodlfixlabels': ` libc.so.6 => /lib/libc.so.6 (0x40005000)' - binary releases: * make deb * dpkg 1.4.0.23.2 * debhelper 0.96 * /usr/bin/db_*: remove -p from install options (urg) * make rpm * make zip - try at debian package: /bin/bash: dh_testdir: command not found - bf: html: Previous/Next chapter links - bf: label() - {c,f,v,k,p,t}index(), makeindex() macros - configure/make ********* 1.30.0.pre8 - BASH is not required for yodl scripts - bf: absolute include path (KDB) - lots of (step)make fixes ********* 1.30.0.pre7 - bf: garbled error messages - doco fixes - YODL -> Yodl - various stepmake updates - run yodl from sourcetree - check for TROFF - changed ld order to support gettext with ecgs compiler (JBR) - stepmake fixes ******** 1.30.0.pre6 - doco additions and fixes - libc-extensions - check for dirname/basename - make website - Documentation fixes: * yodl.yo -> yodl.yo.in fixed silly install-excerpt hack * replaced legalese.yo with copying.yo - dropped old scripts - bf: don't check for c++ - dropped obsolete submissions - do put nchapters in html toc - more latex-mimic macros: * appendix() After issuing 'appendix()', 'chapter(foo) chapter(bar)' looks like: Appendix A: foo Appendix B: bar * cite() * sc() - don't catch failure signals: rather dump core - allow CHAR(a+b) (e.g.: CHAR(65+foo_counter) ******** 1.30.0.pre5 - bf: xpm typos - included pl 1.23, where relevant: [OLD] * Minor code changes. Yodl now also compiles under cygwin32 (a mini-Unix under Windows 95, yech). [OLD] * The define TMPDIR didn't get passed down from the top level Makefile into the source tree. Fixed. * Several warnings in the C compilation fixed. * Nesting imlemented in enumerate() lists up to 3 levels deep. * the umlaut fix - added some macros: * ellipsis() * TeX() LaTeX() * rangle(), langle(), * sups(1), subs(1) * bind(1): bind(figure)ref(fig:one) -> figure~\ref{fig:one} * nop(1): nop(bla)footnote(foo) * includeverbatim(file): real verbatim include 1.30.0.pre4 - bf: yodl2html-post: don't prefix links with dirname - bf: tag htmlnewfile - added (OUT)FILENAME builtins ... - sanified some warning/error messages - bf: included getop1.c - mudela.yodoc.in: handle mudela in 2tex and 2html - added DOEXPAND as builtin macro (urg) - htmlnewfile fixes (KDB) - added verbpipe(2) - bf: silly str_short in pipethrough ? - bf's: doc typos - small macro fixes - fix: aux-macros: .TAGSTART. .TAGEND. in html (XXinternallabel) ?... - added [n]paragraph(1) - atvariables - bf: scripts: make uninstall 1.30.0.pre3 - doos-dist fixes - doos compile fixes - Documentation/AUTHORS.yo - distribute Documentation/man/out/* - yodl: --version - yodl: warranty message - yodl: long options - yodl: automated list of builtin macros - fixed config.h dependency 1.30.0.pre2 - bf's: macros + @@ substs 1.30.0.pre1 - NEWS - mudela(2) (Temporarily, will be gone in next pl) - StepMakification - yodl2texinfo: don't use (rather new) @uref command 1.22.kdb1 - configurable TOC header - use

iso
entries, which includes the final */ static size_t s_lastLabelNr; HashItem *construct_tocentry(char const *key, char *rest) { size_t level; char *section = string_firstword(&rest); if (!section) { message_error("incomplete tocentry"); return 0; } string_strip(&rest); /* find the section's index */ level = lines_find(section, section_levels, sizeofSectionLevels); if (level == UFAILED) /* no section given is err. */ { message_error("unknown toc-section `%s'", section); free(section); return 0; } free(section); /* write
for deeper levels */ for (; level > global.d_toclevel; ++global.d_toclevel) lines_add(&global.d_toc, "
"); /* write
when returning to shallower levels */ for (; level < global.d_toclevel; --global.d_toclevel) lines_add(&global.d_toc, "
"); /* add a new entry */ lines_format(&global.d_toc, "
%s%s%s
", toc_section[global.d_doctype][level][0], string_str(&global.d_outName), (unsigned)++s_lastLabelNr, rest, toc_section[global.d_doctype][level][1]); return hashitem_construct(VOIDPTR, "", (void *)s_lastLabelNr, root_nop); } yodl-3.06.00/src/yodlpost/handlexmlsolvelink.c0000644000175000017500000000200612573350735020336 0ustar frankfrank#include "yodlpost.h" void handle_xml_solvelink(long offset, HashItem *item) { LabelInfo *lp; char const *label = hashitem_key(item); register char *xml_label; /* look up the label */ HashItem *info = hashmap_find(&symtab, label, ANY); file_copy2offset(global.d_out, postqueue_istream(), offset); if (info == PFAILED) { message_show(MSG_WARNING); message("Unresolved label: %s", label); fputs("??", global.d_out); return; } lp = (LabelInfo *)hashitem_value(info); xml_label = xml_label_name(label); if (lp->d_filenr) { fprintf(global.d_out, "%s%02u.%s#%s", global.d_noext, (unsigned)lp->d_filenr, global.d_ext, xml_label); } else { fprintf(global.d_out, "%s.%s#%s", global.d_noext, global.d_ext, xml_label); } free(xml_label); } yodl-3.06.00/src/yodlpost/constructxmltocentry.c0000644000175000017500000000413012573350735020770 0ustar frankfrank#include "yodlpost.h" /* toc entries are of the form: tocentry sectionname sectionnumber entrytext e.g., 24121 tocentry ssect 2.3.2: Compiling a C program by a C++ compiler First the section is determined. It's an error if omitted. The toc is built as a description list. Each level is a nested table When entering a sublevel, as many s are opened to reach the appropriate level. When leaving a sublevel, as many
s are written to leave the current level. When staying inside a level, no or
is written. Example tocentry: 21862 tocentry ssect 2.3.1: History of the C++ Annotations The toc entry is appended to the toc-lines, the handler received offset and internal label number. */ static size_t s_lastLabelNr; HashItem *construct_xml_tocentry(char const *key, char *rest) { size_t level; char *section = string_firstword(&rest); if (!section) { message_error("incomplete tocentry"); return 0; } /* find the section's index */ level = lines_find(section, section_levels, sizeofSectionLevels); free(section); if (level == UFAILED) /* no section given is err. */ { message_error("unknown toc-section `%s'", section); return 0; } /* add a new entry */ if (global.d_filecount) lines_format(&global.d_toc, "%d %s%02u %u %s", global.d_toclevel - level, global.d_noext, (unsigned)global.d_filecount, (unsigned)++s_lastLabelNr, rest); else lines_format(&global.d_toc, "%d %s %u %s", global.d_toclevel - level, global.d_noext, (unsigned)++s_lastLabelNr, rest); global.d_toclevel = level; return hashitem_construct(VOIDPTR, "", (void *)s_lastLabelNr, root_nop); } yodl-3.06.00/src/yodlpost/constructtoc.c0000644000175000017500000000115012573350735017164 0ustar frankfrank#include "yodlpost.h" HashItem *construct_toc(char const *key, char *rest) { char *newheader = new_str(rest); register HashItem *item = hashmap_find(&global.d_symbol, "tocheader", ANY); if (item != PFAILED) hashitem_set(item, newheader, free); /* reassign existing value */ else /* of insert new element */ hashmap_insert(&global.d_symbol, hashitem_construct(VOIDPTR, "tocheader", newheader, free)); return hashitem_construct(VOIDPTR, rest, 0, root_nop); } yodl-3.06.00/src/yodlpost/handlexmlref.c0000644000175000017500000000227012573350735017107 0ustar frankfrank#include "yodlpost.h" void handle_xml_ref(long offset, HashItem *item) { LabelInfo *lp; char const *documentbase; char const *label = hashitem_key(item); register char *xml_label; /* look up the label */ HashItem *info = hashmap_find(&symtab, label, ANY); file_copy2offset(global.d_out, postqueue_istream(), offset); if (info == PFAILED) { warning("Unresolved label: %s", label); fputs("??", global.d_out); return; } lp = (LabelInfo *)hashitem_value(info); documentbase = hashmap_textOf(&global.d_symbol, "XXdocumentbase"); xml_label = xml_label_name(label); if (lp->d_filenr) { fprintf(global.d_out, "%s", documentbase, global.d_noext, (unsigned)lp->d_filenr, xml_label, lines_at(&global.d_section, lp->d_section)); } else { fprintf(global.d_out, "%s", documentbase, global.d_noext, xml_label, lines_at(&global.d_section, lp->d_section)); } free(xml_label); } yodl-3.06.00/src/yodlpost/usage.c0000644000175000017500000000204612573350735015543 0ustar frankfrank #include "../config.h" #include "yodlpost.h" void usage() { char const *program = args_programName(); fprintf(stderr, "%s%s%s%s%s%s%s", "\n" "Your Own Document Language: ", program, " " VERSION "\n" "Usage: ", program, " [options] index yodlout [out]\n" "Where:\n" " [options] options. Select from\n" " -l linesize: maximum length of lines in the index file " "(default: 1000)\n" " -x ext: extension of the out-files if different from the extension\n" " of `out' itself. If omitted, and `out' has no extension,\n" " ypp (Yodl Post Processor) is used.\n" " index: the name of the index file generated by Yodl\n" " yodlout: the name of the output file generated by Yodl\n" " [out]: optional name of the file generated by ", program, ",\n" " stdout if omitted.\n" "\n" "The special tags in the index file are processed.\n" "Normally, this program is run from a yodl2xxx script\n" "\n" ); exit(1); } yodl-3.06.00/src/yodlpost/data.c0000644000175000017500000001154512573350735015354 0ustar frankfrank#include "yodlpost.h" Global global; HashMap symtab; /* The maximum linelength that can be used in index values is 500. Beyond that, the line is truncated and subsequent lines may be ill-formed due to the truncation. construct: key: store key and rest in the returned HashItem. The key + rest is not used during the stack construction, but contains info which results in code/copy actions when the item is processed later on It receives the key and the stripped rest of the line (following the key). the line may be modified by the construct-functions, but is not owned by them. So, when the contents are to be kept, copies must be created locally by the construct-functions. handle: key: redefine key's value in d_symbol lastnumber: assign the current lastnumber to d_section lastnumber is (and remains) stored in the Queue, and is therefore stored only once. */ Task task[] = { // label constructor function handling function // ---------------------------------------------------------- {"copy", construct_nop, handle_copy}, {"bodytagopt", construct_deprecated, handle_set}, {"documenttype", construct_deprecated, handle_set}, {"drainws", construct_nop, handle_drain_ws}, {"htmldone", construct_nop, handle_html_done}, {"htmllabel", construct_label, handle_html_label}, {"htmlnewfile", construct_newfile, handle_html_newfile}, {"htmltoc", construct_toc, handle_toc}, {"htmltocentry", construct_tocentry, handle_html_tocentry}, {"ignorews", construct_nop, handle_ignore_ws}, {"lastnumber", construct_lastnumber, handle_copy}, {"labvalue", construct_labvalue, handle_labvalue}, {"mandone", construct_nop, handle_copy}, {"preset", construct_preset, handle_nop}, {"ref", construct_ref, handle_ref}, {"set", construct_set, handle_set}, {"solvelink", construct_ref, handle_solvelink}, {"title", construct_deprecated, handle_set}, {"txtlabel", construct_label, handle_nop}, {"txtref", construct_ref, handle_txt_ref}, {"txttoc", construct_toc, handle_txt_toc}, {"txttocentry", construct_txt_tocentry, handle_nop}, {"verb", construct_verb, handle_verb}, {"xmldone", construct_xml_done, handle_xml_done}, {"xmllabel", construct_label, handle_xml_label}, {"xmlnewfile", construct_newfile, handle_xml_newfile}, {"xmlref", construct_ref, handle_xml_ref}, {"xmlsolvelink", construct_ref, handle_xml_solvelink}, {"xmltoc", construct_toc, handle_xml_toc}, {"xmltocentry", construct_xml_tocentry, handle_xml_tocentry}, {0, 0, 0}, }; /* The default names may be altered using the INTERNALINDEX(set ...) command. E.g., INTERNALINDEX(set previous Vorig Hoofdstuk) The bodytagopt, documenttype and title values may be set this way too, but here the direct INTERNALINDEX commands may also still be used. However, they are deprecated, and a corresponding message is issued when they are encountered. */ char const *default_symbols[][2] = { {"previous", "Previous Chapter"}, {"next", "Next Chapter"}, {0, 0}, }; char const *section_levels[] = { "", /* UNDETERMINED_SECTION */ "chap", "sect", "ssect", "sssect", 0, }; /* Dimensions: (no)article, SectionLevel, open/close */ static char const *s_empty[2] = {"", ""}; static char const *s_h2[] = {"

", "

"}; static char const *s_h3[] = {"

", "

"}; char const **toc_section[][sizeofSectionLevels] = { { /* DocType: no article */ 0, s_h2, /* chapter */ s_h3, /* section */ s_empty, /* ssect */ s_empty, /* sssect */ }, { /* DocType: article */ 0, s_empty, /* chapter */ s_h2, /* section */ s_h3, /* ssect */ s_empty, /* sssect */ } }; char const *doctypes[] = /* Modify this when DocType in yodlpost.h is */ { /* altered */ "book", "report", "article", "manpage", "letter", 0 }; yodl-3.06.00/src/yodlpost/handledrainws.c0000644000175000017500000000063512573350735017264 0ustar frankfrank#include "yodlpost.h" void handle_drain_ws(long offset, HashItem *item) { FILE *src = postqueue_istream(); FILE *dest = global.d_out; while (ftell(src) < offset) { register int ch; switch (ch = fgetc(src)) { case EOF: return; case ' ': case '\t': continue; } fputc(ch, dest); } } yodl-3.06.00/src/yodlpost/constructtxttocentry.c0000644000175000017500000000071112573350735021010 0ustar frankfrank#include "yodlpost.h" /* toc entries are of the form: tocentry sectionnumber entrytext e.g., 24121 tocentry 2.3.2: Compiling a C program by a C++ compiler This toc entry is eventually simply written to the output file. */ HashItem *construct_txt_tocentry(char const *key, char *rest) { lines_add(&global.d_toc, rest); /* add a new entry */ return hashitem_construct(VOIDPTR, "", 0, root_nop); } yodl-3.06.00/src/yodlpost/yodlpost.c0000644000175000017500000000361412573350735016316 0ustar frankfrank#include "yodlpost.h" extern int args_data; extern int postqueue_data; extern int message_data; int main (int argc, char **argv) { char const *doctype; char const **ptr; args_data = postqueue_data = message_data; message_construct(argv[0]); args_construct(argc, argv, "?x:l:", 0); hashmap_construct(&symtab); global.d_toclevel = 1; /* prevent extra
level for the 1st level of the table of contents */ global.d_html5 = true; lines_construct(&global.d_toc); lines_construct(&global.d_section); lines_construct(&global.d_styleopt); lines_add(&global.d_section, ""); hashmap_constructText(&global.d_symbol, default_symbols); if (!args_ok() || args_nArgs() < 2) /* check arguments */ usage(); if (args_nArgs() == 2) /* file name specified */ { global.d_out = stdout; global.d_noext = 0; } else { global.d_noext = file_rmExtension(args_arg(2)); global.d_ext = file_extension(args_arg(2)); if (!global.d_ext) { global.d_ext = new_str(args_optarg('x')); if (!global.d_ext) global.d_ext = "ypp"; /* Yodl Post Processor */ } } string_construct(&global.d_outName, 0); postqueue_construct(task); if (global.d_noext) { string_format(&global.d_outName, "%s.%s", global.d_noext, global.d_ext); global.d_out = file_open(string_str(&global.d_outName), "w"); } doctypes[sizeofDocType - 1] = doctype = hashmap_textOf(&global.d_symbol, "documenttype"); for ( ptr = doctypes, global.d_doctype = 1; strcmp(doctype, *ptr); ptr++, global.d_doctype <<= 1 ) ; postqueue_process(); fclose(global.d_out); return 0; } yodl-3.06.00/src/yodlpost/handlecopy.c0000644000175000017500000000021212573350735016556 0ustar frankfrank#include "yodlpost.h" void handle_copy(long offset, HashItem *item) { file_copy2offset(global.d_out, postqueue_istream(), offset); } yodl-3.06.00/src/yodlpost/handlehtmldone.c0000644000175000017500000000041312573350735017421 0ustar frankfrank#include "yodlpost.h" void handle_html_done(long offset, HashItem *item) { file_copy2offset(global.d_out, postqueue_istream(), offset); html_chapterlinks((int)global.d_fileNr++); fprintf(global.d_out, "\n" "\n"); } yodl-3.06.00/src/yodlpost/handletxtref.c0000644000175000017500000000115412573350735017126 0ustar frankfrank#include "yodlpost.h" void handle_txt_ref(long offset, HashItem *item) { LabelInfo *lp; char const *label = hashitem_key(item); /* look up the label */ HashItem *info = hashmap_find(&symtab, label, ANY); file_copy2offset(global.d_out, postqueue_istream(), offset); if (info == PFAILED) { warning("Unresolved label: %s", label); fputs("??", global.d_out); return; } lp = (LabelInfo *)hashitem_value(info); fprintf(global.d_out, "%s", lines_at(&global.d_section, lp->d_section)); } yodl-3.06.00/src/yodlpost/constructset.c0000644000175000017500000000137512573350735017203 0ustar frankfrank#include "yodlpost.h" /* An example of the `set' index item is: 1234 set title This is the title of the document title is stored as key, and what's beyond is stored as the value in the returned HashItem structure. The handler may store these values in a storage. The value is NOT freed after handling. */ HashItem *construct_set(char const *setkey, char *rest) { char *key; HashItem *ret; if (!(key = string_firstword(&rest))) /* get the key */ { message_error("`set ...: missing key"); return 0; } if (!*string_strip(&rest)) warning("Empty value of symbol `%s'", key); ret = hashitem_construct(VOIDPTR, key, new_str(rest), root_nop); free(key); return ret; } yodl-3.06.00/src/yodlpost/htmlchapterlinks.c0000644000175000017500000000277112573350735020020 0ustar frankfrank#include "yodlpost.h" void html_chapterlinks(int current) /* set links to next/prev chap */ { /* and table of contents */ if ( !(global.d_doctype & (BOOK | REPORT)) || !current ) return; /* links only in books, reports, */ /* and outside of toc itself */ fputs ( "
\n" /* borders the contents */ "
    \n", global.d_out ); fprintf ( global.d_out, "
  • %s\n", global.d_noext, global.d_ext, hashmap_textOf(&global.d_symbol, "tocheader") ); if (current > 1) { fprintf ( global.d_out, "
  • %s\n", global.d_noext, current - 1, global.d_ext, hashmap_textOf(&global.d_symbol, "previous") ); } if ((size_t)current < global.d_filecount) { fprintf ( global.d_out, "
  • %s\n", global.d_noext, current + 1, global.d_ext, hashmap_textOf(&global.d_symbol, "next") ); } fputs ( "
\n" "
\n", /* borders the contents */ global.d_out ); } yodl-3.06.00/src/yodlpost/handlehtmllabel.c0000644000175000017500000000032712573350735017557 0ustar frankfrank#include "yodlpost.h" void handle_html_label(long offset, HashItem *item) { file_copy2offset(global.d_out, postqueue_istream(), offset); fprintf(global.d_out, "", hashitem_key(item)); } yodl-3.06.00/src/yodlpost/handleset.c0000644000175000017500000000230312573350735016402 0ustar frankfrank#include "yodlpost.h" /* The key's value is inserted into the &global.d_symbol hashmap. If the indicated value already exists, it is reassigned. The hashitem's value is swallowed by the hashmap. */ void handle_set(long offset, HashItem *item) { register HashItem *mapItem; register char const *key = hashitem_key(item); char *value; file_copy2offset(global.d_out, postqueue_istream(), offset); /* grab the item's value */ /* since the construct_set */ /* doesn't free the value */ /* it can be used here */ /* without copying */ value = (char *)hashitem_value(item); mapItem = hashmap_find(&global.d_symbol, key, ANY); if (mapItem != PFAILED) hashitem_set(mapItem, value, free); /* reassign existing value */ else /* of insert new element */ hashmap_insert(&global.d_symbol, hashitem_construct(VOIDPTR, key, value, free)); } yodl-3.06.00/src/yodlpost/handlexmlnewfile.c0000644000175000017500000000234712573350735017771 0ustar frankfrank#include "yodlpost.h" void handle_xml_newfile(long offset, HashItem *item) { handle_xml_done(offset, item); if (global.d_noext) { fclose(global.d_out); /* construct the new output */ /* file name */ string_format(&global.d_outName, "%s%02u.%s", global.d_noext, (unsigned)global.d_fileNr, global.d_ext); /* and open it */ global.d_out = file_open(string_str(&global.d_outName), "w"); } file_append(global.d_out, hashmap_textOf(&global.d_symbol, "XXarticleBegin")); fputs(hashmap_textOf(&global.d_symbol, "title"), global.d_out); file_append(global.d_out, hashmap_textOf(&global.d_symbol, "XXarticleEndTitle")); file_append(global.d_out, hashmap_textOf(&global.d_symbol, "XXxhtmlBegin")); xml_chapterlinks((int)global.d_fileNr); /* and the chapterlinks */ } yodl-3.06.00/src/yodlpost/handleref.c0000644000175000017500000000175412573350735016374 0ustar frankfrank#include "yodlpost.h" void handle_ref(long offset, HashItem *item) { LabelInfo *lp; char const *label = hashitem_key(item); /* look up the label */ HashItem *info = hashmap_find(&symtab, label, ANY); file_copy2offset(global.d_out, postqueue_istream(), offset); if (info == PFAILED) { warning("Unresolved label: %s", label); fputs("??", global.d_out); return; } lp = (LabelInfo *)hashitem_value(info); if (lp->d_filenr) { fprintf(global.d_out, "%s", global.d_noext, (unsigned)lp->d_filenr, global.d_ext, label, lines_at(&global.d_section, lp->d_section)); } else { fprintf(global.d_out, "%s", global.d_noext, global.d_ext, label, lines_at(&global.d_section, lp->d_section)); } } yodl-3.06.00/src/yodlpost/handletoc.c0000644000175000017500000000133412573350735016377 0ustar frankfrank#include "yodlpost.h" void handle_toc(long offset, HashItem *item) { register size_t idx; register size_t n; file_copy2offset(global.d_out, postqueue_istream(), offset); fprintf(global.d_out, "

%s

\n" "
", hashitem_key(item)); for (idx = 0, n = lines_size(&global.d_toc); idx != n; ++idx) { fputs(lines_at(&global.d_toc, idx), global.d_out); fputc('\n', global.d_out); } for (; --global.d_toclevel; ) /* stop at 1, which matches the */ fputs("
", global.d_out); /* initial value 1, set in */ /* yodlpost.c */ fputs("\n", global.d_out); } yodl-3.06.00/src/yodlpost/yodlpost.h0000644000175000017500000002262512573350735016326 0ustar frankfrank#ifndef INCLUDED_YODLPOST_H_ #define INCLUDED_YODLPOST_H_ #include #include #include #include "../postqueue/postqueue.h" #include "../lines/lines.h" typedef enum { UNDETERMINED_SECTION = 0, CHAPTER, SECTION, SUBSECTION, SUBSUBSECTION, _SectionLevels_searchfield, sizeofSectionLevels } SectionLevels; typedef enum { BOOK = (1 << 0), REPORT = (1 << 1), ARTICLE = (1 << 2), MANPAGE = (1 << 3), LETTER = (1 << 4), OTHER_DOCTYPE = (1 << 5), sizeofDocType = 6 } DocType; /* Modify data.c:doctypes[] when this emum is altered */ /* args_arg(2) has the name of Yodl's output file. d_noext is set to file_rmExtension(args_arg(2)) d_outname is set the full filename of the current output file. */ typedef struct { bool d_keep_ws; /* true if series of ws should */ /* be KEPT by ignore_ws */ /* initially false */ bool d_html5; /* true (by default) if html5 */ /* must be specified in the hdr */ size_t d_fileNr; /* currently written file */ size_t d_filecount; /* counts filenumbers */ Lines d_section; /* stores section names */ DocType d_doctype; char *d_noext; /* output file without ext. */ char *d_ext; /* extension for the output */ String d_outName; /* name of current output file */ FILE *d_out; /* currently written file */ Lines d_toc; /* stores table of contents */ size_t d_toclevel; /* level of current toc entries */ /* (chapter, section, etc.) */ HashMap d_symbol; /* configurable symbols */ /* (title, bodytagopt, etc. */ Lines d_styleopt; /* styleopts from preset */ } Global; typedef struct { size_t d_filenr; size_t d_section; /* points to tos(d_section) */ } LabelInfo; extern char const *default_symbols[][2]; /* initializes d_symbol */ extern Global global; extern char const *section_levels[]; extern HashMap symtab; extern Task task[]; extern char const **toc_section[][sizeofSectionLevels]; extern char const *doctypes[]; void html_chapterlinks(int current); /* set links to next/prev chap */ void xml_chapterlinks(int current); /* set links to next/prev chap */ char *xml_label_name(char const *lab); /* change all nonalnum chars to . */ HashItem *construct_deprecated(char const *key, char *rest); HashItem *construct_label(char const *key, char *rest); HashItem *construct_labvalue(char const *key, char *rest); HashItem *construct_lastnumber(char const *key, char *rest); HashItem *construct_newfile(char const *key, char *rest); HashItem *construct_nop(char const *key, char *rest); HashItem *construct_preset(char const *key, char *rest); HashItem *construct_ref(char const *key, char *rest); HashItem *construct_set(char const *key, char *rest); HashItem *construct_toc(char const *key, char *rest); HashItem *construct_tocentry(char const *key, char *rest); HashItem *construct_txt_tocentry(char const *key, char *rest); HashItem *construct_verb(char const *key, char *rest); HashItem *construct_xml_done(char const *key, char *rest); HashItem *construct_xml_tocentry(char const *key, char *rest); void handle_copy(long offset, HashItem *item); void handle_drain_ws(long offset, HashItem *item); void handle_html_done(long offset, HashItem *item); void handle_html_label(long offset, HashItem *item); void handle_html_tocentry(long offset, HashItem *item); void handle_html_newfile(long offset, HashItem *item); void handle_ignore_ws(long offset, HashItem *item); void handle_labvalue(long offset, HashItem *item); void handle_nop(long offset, HashItem *item); void handle_ref(long offset, HashItem *item); void handle_set(long offset, HashItem *item); void handle_solvelink(long offset, HashItem *item); void handle_txt_ref(long offset, HashItem *item); void handle_txt_toc(long offset, HashItem *item); void handle_txt_tocentry(long offset, HashItem *item); void handle_toc(long offset, HashItem *item); void handle_verb(long offset, HashItem *item); void handle_xml_done(long offset, HashItem *item); void handle_xml_label(long offset, HashItem *item); void handle_xml_newfile(long offset, HashItem *item); void handle_xml_solvelink(long offset, HashItem *item); void handle_xml_toc(long offset, HashItem *item); void handle_xml_tocentry(long offset, HashItem *item); void handle_xml_ref(long offset, HashItem *item); void usage(void); /* When reading the index file, its keys are looked up in the Task array. Each key's construct_ function is called, and the returned HashItem *, is then processed according to its value/organization: construct_...() functions return: 0: disregard due to, e.g., error HashItem *, processed depending on the existence of a value for d_handler in the corresponding task-struct. If non-zero: the queue processor handles the HashItem in sequence and calls its hashitem_destroy() function and destroys the HashItem itself afterwards. If zero: the hashitem is stored by its key in the symbol table. construct/handler function pairs used by yodlpost: ======================================================== construct_deprecated(): VALUE NOT FREED deprecated as the INTERNALINDEX(set key ...} should be used. returns HashItem(key, new_str(rest)) handle_set(): stores value at element key in d_symbols. free() not required. ------------------------------------------------------------------------ construct_label(): Stores the label in the symboltable: stores HashItem(labelname, new LabelInfo(sectionidx, filecount)) returns HashItem(labelname, offset); 0 is returned and an error is generated when no label is specified or if the label is doubly defined. handle_label(): cp2offset, then write the label anchor to the output file. ------------------------------------------------------------------------ construct_labvalue(): returns HashItem(labelname, new long(offset)); 0 is returned and an error is generated when no label is specified. handle_labvalue(): Writes the label's section after copying the input file to the indicated offset ------------------------------------------------------------------------ construct_lastnumber(): adds the section number to Lines d_section returns HashItem("", 0); handle_lastnumber(): No action required. ------------------------------------------------------------------------ construct_newfile(): Marks the location of then next file to be processed. The file number is incremented at each construct_newfile() call, which is then used as the filenumber of subsequent labels. Later, when the queue is processed, the filecount is reset to 0. As the newfile handlers also increment the filecount the numbers are synchronized, and need not be kept inside the HashItem's value. returns HashItem("", 0) handle_newfile(): cp2offset, closes the current file (and writes chapterlinks), opens the next file (and writes chapterlinks) ------------------------------------------------------------------------ construct_ref(): Marks the offset where the section of a label should be inserted. returns HashItem(labelname, new long(offset)); returns 0 if no label was specified. handle_ref(): cp2offset, looks up the label, writes section nr. handle_solvelink(): cp2offset, looks up the label, writes file#label ------------------------------------------------------------------------ construct_set(): VALUE NOT FREED Extracts key and value beyond `set', to be stored later in the d_symbols map. returns HashItem(key, string_strip(rest)) returns 0 if no key was specified. Empty `rest' is ok. handle_set(): stores value at element key in d_symbols. free() not required. ------------------------------------------------------------------------ construct_toc(): returns HashItem(tocheader 0) handle_toc(): writes a

tocheader

followed by all lines of the toc to the current output file. ------------------------------------------------------------------------ construct_tocentry(): Enters a description in the &global.d_toc returns HashItem(key, new TocInfo(offset, labelnr), which is converted into label l at `offset' by the queue processor. Error conditions are: missing or unknown section indicator. handle_tocentry(): cp2offset, prints to the output file. ------------------------------------------------------------------------ */ #endif yodl-3.06.00/src/yodlpost/handlexmltoc.c0000644000175000017500000000165012573350735017121 0ustar frankfrank#include "yodlpost.h" void handle_xml_toc(long offset, HashItem *item) { register size_t idx; register size_t n; int level; char *filename = new_memory(1, 250); char const *documentbase = hashmap_textOf(&global.d_symbol, "XXdocumentbase"); file_copy2offset(global.d_out, postqueue_istream(), offset); fprintf(global.d_out, "

%s

\n", hashitem_key(item)); for (idx = 0, n = lines_size(&global.d_toc); idx < n; idx++) { int nread; unsigned labelnr; char const *line = lines_at(&global.d_toc, idx); sscanf(line, "%d %100s %u %n", &level, filename, &labelnr, &nread); fprintf ( global.d_out, "%s" "
\n", documentbase, filename, labelnr, line + nread ); } free(filename); } yodl-3.06.00/src/yodlpost/constructnewfile.c0000644000175000017500000000206212573350735020033 0ustar frankfrank#include "yodlpost.h" /* Example of a newfile entry: 431 newfile Marks the location of then next file to be processed. The file number is incremented at each construct_newfile() call, which is then used as the filenumber of subsequent labels. Later, when the queue is processed, the filecount is reset to 0. As the newfile handlers also increment the filecount the numbers are synchronized, and need not be kept inside the HashItem's value. */ HashItem *construct_newfile(char const *key, char *rest) { global.d_filecount++; if (global.d_noext) { string_format(&global.d_outName, "%s%02u.%s", global.d_noext, (unsigned)global.d_filecount, global.d_ext); } /* arguments are for the handlers to process */ return *rest ? hashitem_construct(VOIDPTR, "", new_str(rest), free) : hashitem_construct(VOIDPTR, "", 0, root_nop); } yodl-3.06.00/src/yodlpost/handlexmldone.c0000644000175000017500000000106512573350735017261 0ustar frankfrank#include "yodlpost.h" void handle_xml_done(long offset, HashItem *item) { file_copy2offset(global.d_out, postqueue_istream(), offset); xml_chapterlinks((int)global.d_fileNr++); file_append(global.d_out, hashmap_textOf(&global.d_symbol, "XXxhtmlEnd")); fputs("\n", global.d_out); file_append(global.d_out, hashmap_textOf(&global.d_symbol, "XXarticleSummary")); fputs("\n", global.d_out); } yodl-3.06.00/src/yodlpost/handleverb.c0000644000175000017500000000037012573350735016547 0ustar frankfrank#include "yodlpost.h" /* d_keepws: at `verb on' it was set to 1 else 0. */ void handle_verb(long offset, HashItem *item) { file_copy2offset(global.d_out, postqueue_istream(), offset); global.d_keep_ws = (bool)hashitem_value(item); } yodl-3.06.00/src/yodlpost/constructpreset.c0000644000175000017500000000311012573350735017677 0ustar frankfrank#include "yodlpost.h" /* An example of the `preset' index item is: 1234 preset title This is the title of the document title is stored immediately. No action at `handle' */ HashItem *construct_preset(char const *setkey, char *rest) { char *key; HashItem *mapItem; if (!(key = string_firstword(&rest))) /* get the key */ { /* e.g., title */ message_error("`preset ...: missing key"); return 0; } if (strcmp(key, "nohtmlfive") == 0) global.d_html5 = 0; else { if (!*string_strip(&rest)) /* get the value */ warning("Empty value of symbol `%s'", key); /* e.g., This is... */ if (strcmp(key, "styleopt") == 0) /* store styleopts */ lines_add(&global.d_styleopt, rest); else { /* look up the key */ mapItem = hashmap_find(&global.d_symbol, key, ANY); if (mapItem != PFAILED) /* reassign */ hashitem_set(mapItem, rest, free); /* existing value */ else /* or insert new */ hashmap_insert(&global.d_symbol, /* element */ hashitem_construct(VOIDPTR, key, new_str(rest), free)); } } free(key); return hashitem_construct(VOIDPTR, "", 0, root_nop); } yodl-3.06.00/src/yodlpost/constructlastnumber.c0000644000175000017500000000123512573350735020557 0ustar frankfrank#include "yodlpost.h" /* A simple key required no special handling. Any information it contains is stored in a KeyInfo struct, containing the offset and the `rest' info. The stored info is then handled by specific handlers. The handler is responsible for freeing the information that is stored at the d_tail field. The KeyInfo itself is freed by the postprocessor. */ HashItem *construct_lastnumber(char const *key, char *rest) { if (!(*string_strip(&rest))) warning("No section specified at `lastnumber'"); lines_add(&global.d_section, rest); /* empty is no problem here */ return hashitem_construct(VOIDPTR, "", 0, root_nop); } yodl-3.06.00/src/yodlpost/handlexmllabel.c0000644000175000017500000000044412573350735017413 0ustar frankfrank#include "yodlpost.h" void handle_xml_label(long offset, HashItem *item) { register char *label; file_copy2offset(global.d_out, postqueue_istream(), offset); label = xml_label_name(hashitem_key(item)); fprintf(global.d_out, "", label); free (label); } yodl-3.06.00/src/yodlpost/constructref.c0000644000175000017500000000051112573350735017153 0ustar frankfrank#include "yodlpost.h" /* Example of a ref: 1234 ref LabelName The offset and the labelname are stored in the returned HashItem. */ HashItem *construct_ref(char const *key, char *rest) { rest = strtok(rest, " \t"); if (rest) return hashitem_construct(VOIDPTR, rest, 0, root_nop); return 0; } yodl-3.06.00/src/chartab/0000755000175000017500000000000012573350735014020 5ustar frankfrankyodl-3.06.00/src/chartab/chartabconstruct.c0000644000175000017500000000471012573350735017537 0ustar frankfrank#include "chartab.ih" /* The regular expression of chartab-elements consists of the following parts: "[[:space:]]*" - start with optional whitespace "'((\\\\)?.)'" - followed by one character between single quotes, optionally preceded by a backslash "[[:space:]]*" - followed by optional white space "=" - and an '=' sign "[[:space:]]*" - followed by optional white space "\"(((\\\\.)|[^\"])*)\"" - followed by any series of chars, each optionally preceded by a \, enclosed in double string quotes d_regex_oct is identical to d_regex, but has the character expression "'\\\\([0-7]{3})'" - three octal digits preceded by a \, surrounded by single quotes. Example: '\123' d_regex_hex is identical to d_regex, but has the character expression "'0x([0-9a-fA-F]{2})'" - 0x followed by 2 hex digits, surrounded by single quotes. Example: '0xab' */ void chartab_construct() { if ( regcomp ( &chartab.d_regex, "[[:space:]]*" "'((\\\\)?.)'" "[[:space:]]*" "=" "[[:space:]]*" "\"(((\\\\.)|[^\"])*)\"" , REG_EXTENDED | REG_NEWLINE ) || regcomp ( &chartab.d_regex_oct, "[[:space:]]*" "'\\\\([0-7]{3})'" "[[:space:]]*" "=" "[[:space:]]*" "\"(((\\\\.)|[^\"])*)\"" , REG_EXTENDED | REG_NEWLINE ) || regcomp ( &chartab.d_regex_hex, "[[:space:]]*" "'0x([0-9a-fA-F]{2})'" "[[:space:]]*" "=" "[[:space:]]*" "\"(((\\\\.)|[^\"])*)\"" , REG_EXTENDED | REG_NEWLINE ) ) if (message_show(MSG_EMERG)) message("Chartab_construct(): regcomp() failed"); stack_construct(&chartab.d_chartab_st, NULL); } yodl-3.06.00/src/chartab/chartab.h0000644000175000017500000000505012573350735015575 0ustar frankfrank#ifndef INCLUDED_CHARTAB_H_ #define INCLUDED_CHARTAB_H_ #include #include #include "../root/root.h" #include "../stack/stack.h" #include "../hashmap/hashmap.h" #include "../string/string.h" /* Character tables are defined as arrays of 256 char *s and stored by name in the symbol table. In d_chartab_st the addresses of the tables are stored, stackwise, while d_active is always set to the stack's top to speed up chartable access. There is no default character table. If the default is requested, NULL is pushed on the stack. */ typedef struct { Stack d_chartab_st; /* pointers to stacked character tables */ char **d_active; /* currently active character table NULL if */ /* the default (1:1) chartab is active */ regex_t d_regex; /* compiled regular expression */ regex_t d_regex_oct; /* compiled regular expression (octal char) */ regex_t d_regex_hex; /* compiled regular expression (hex char) */ } Chartab; extern int chartab_data; /* to ensure linkage via chartabconstruct.c */ String *chartab_apply(char const *txt); /* returns transformed text */ /* MUST have active chartab */ void chartab_construct(void); Result chartab_find(char const **chartab); Result chartab_insert(HashMap *symtab, char const *name, char *table); Result chartab_pop(void); /* pop the most recent chartab */ /* activate the previous one */ /* push and activate the named */ /* chartab, or no chartab for */ /* an empty string */ Result chartab_use(HashMap *symtab, char const *name, bool pushIsTrue); /* Internal Chartab use only. Not used outside of this directory functions, needed here to allow proper compilation of the static inline functions below */ extern Chartab chartab; /* there's only one chartab */ /* storage */ /* public interface continues from here */ static inline char const **chartab_active() /* returns active chartab or 0 */ { return (char const **)chartab.d_active; } static inline void chartab_destroy(void *chartable) {} static inline bool chartab_isActive() { return chartab.d_active != NULL; } #endif yodl-3.06.00/src/chartab/chartabinsert.c0000644000175000017500000000045512573350735017021 0ustar frankfrank#include "chartab.ih" Result chartab_insert(HashMap *symtab, char const *name, char *table) { return hashmap_insert ( symtab, hashitem_construct(CHARTABLE, name, ct_construct(table), ct_destroy) ); } yodl-3.06.00/src/chartab/chartabapply.c0000644000175000017500000000035212573350735016636 0ustar frankfrank#include "chartab.ih" String *chartab_apply(char const *txt) { register String *sp = string_new(0); while (*txt) string_addstr(sp, chartab.d_active[*(unsigned char const *)txt++]); return sp; } yodl-3.06.00/src/chartab/chartabfind.c0000644000175000017500000000032712573350735016433 0ustar frankfrank#include "chartab.ih" Result chartab_find(char const **ctab) { if (ctab == (char const **)chartab.d_active) return SUCCESS; return stack_contains(&chartab.d_chartab_st, ctab) ? SUCCESS : FAILED; } yodl-3.06.00/src/chartab/ctconstruct.c0000644000175000017500000000065012573350735016540 0ustar frankfrank#include "chartab.ih" static char std_char[2]; /* initially: 1 to 1 mapping of chars */ char **ct_construct(char *table) { char **chartable = new_memory(256, sizeof(char *)); size_t idx; for (idx = 0; idx < 256; idx++) /* set table to defaults */ { std_char[0] = idx; chartable[idx] = new_str(std_char); } ct_parse_table(chartable, table); return chartable; } yodl-3.06.00/src/chartab/ctascii.c0000644000175000017500000000202412573350735015601 0ustar frankfrank#include "chartab.ih" size_t ct_ascii(char const *ch, size_t *skip) { size_t ret; if (*ch != '\\') return (unsigned char)*ch; ++*skip; switch (ch[1]) { case 'a': return '\a'; case 'b': return '\b'; case 'f': return '\f'; case 'n': return '\n'; case 'r': return '\r'; case 't': return '\t'; case 'v': return '\v'; case 'x': case 'X': if (isdigit(ch[3]) && isdigit(ch[4])) { sscanf(ch + 2, "%2x", &ret); *skip = 4; return ret; } return (unsigned char)ch[1]; case '0': case '1': if (strchr("01234567", ch[2]) && strchr("01234567", ch[3])) { sscanf(ch + 1, "%3o", &ret); *skip = 4; return ret; } //FALLING THROUGH default: return (unsigned char)ch[1]; } } yodl-3.06.00/src/chartab/ctstring.c0000644000175000017500000000056112573350735016023 0ustar frankfrank#include "chartab.ih" char *ct_string(char const *str) { String string; string_construct(&string, 0); while (*str) { size_t increment = 1; string_addchar ( &string, (*str == '\\') ? (int)ct_ascii(str, &increment) : *str ); str += increment; } return string_release(&string); } yodl-3.06.00/src/chartab/chartabuse.c0000644000175000017500000000123612573350735016307 0ustar frankfrank#include "chartab.ih" /* Method: push active (if requested), reset active Then at popping: reset active to tos() pop stack */ Result chartab_use(HashMap *symtab, char const *name, bool push) { register StackValue stValue; if (push) { stValue.u_charpp = chartab.d_active; stack_push(&chartab.d_chartab_st, stValue); } if (!*name) chartab.d_active = NULL; else { HashItem *item = hashmap_find(symtab, name, CHARTABLE); if (item == PFAILED) return FAILED; chartab.d_active = (char **)hashitem_value(item); } return SUCCESS; } yodl-3.06.00/src/chartab/chartabpop.c0000644000175000017500000000060612573350735016311 0ustar frankfrank#include "chartab.ih" /* Pushing method: push active reset active Then here, at popping: reset active to tos() pop stack */ Result chartab_pop() { if (!stack_size(&chartab.d_chartab_st)) return FAILED; chartab.d_active = stack_tos(&chartab.d_chartab_st)->u_charpp; stack_pop(&chartab.d_chartab_st); return SUCCESS; } yodl-3.06.00/src/chartab/ctdestroy.c0000644000175000017500000000046212573350735016206 0ustar frankfrank#include "chartab.ih" void ct_destroy(void *table) { register char **cpp = (char **)table; register size_t idx; for (idx = 0; idx < 256; idx++) /* free elements */ free(*cpp++); free(table); /* free the table itself */ } yodl-3.06.00/src/chartab/cdata.c0000644000175000017500000000025512573350735015242 0ustar frankfrank#include "chartab.ih" int chartab_data = 0; /* to ensure linkage via chartabconstruct.c */ Chartab chartab; /* Initialized to 0 by the compiler */ yodl-3.06.00/src/chartab/chartab.ih0000644000175000017500000000055412573350735015752 0ustar frankfrank#include "chartab.h" #include #include #include #include "../message/message.h" #include "../new/new.h" size_t ct_ascii(char const *ch, size_t *increment); char **ct_construct(char *table); void ct_destroy(void *); void ct_parse_table(char **chartab, char *table); char *ct_string(char const *str); yodl-3.06.00/src/chartab/ctparsetable.c0000644000175000017500000001006012573350735016632 0ustar frankfrank#include "chartab.ih" /* See also chatab_construct() for the description of d_regex_hex and d_regex_oct. character tables consist of lines, each line containing a 'x' = "redef" phrase. The problem here is, of course, that we MUST have the newlines. So, we MUST make sure that the WS level, not using -k, doesn't kill our newlines. This is realized by yodl/gramdefinechartable.c by calling parser_push_ws_level() and parser_pop_ws_level(). One match is described by: match: 1 23 (count match by parenthesis number) \s*'(\\?.)'\s*=\s*"(((\\.)|[^"])*)" 1111 22222 3333 55555555 4444444444444 \s: [[:space:]] 1: maybe backslash, then any char within stringquotes 2: backslash, then any char 3: no double quote 4: (2) or (3), as often as required The 'x' part may contain escape sequences: '(\.|)' or '\.' The "redef" part may contain escape sequences "([^"]|\.)*" */ typedef enum { REGEX_HEX, REGEX_PLAIN, REGEX_OCT } REGEX_TYPE; static regmatch_t pmatch[5]; void ct_parse_table(char **table, register char *arg) { int idx; size_t key = 0; /* to prevent `may be used initialized' warning */ /* produced by some compilers */ while (*arg) /* Process `arg' */ { REGEX_TYPE regex_type; unsigned uns_key; register char *chartext; /* Match the next element in `arg' */ /* 5: max 5 subexpressions, 0: no flags */ if (!regexec(&chartab.d_regex, arg, 5, pmatch, 0)) regex_type = REGEX_PLAIN; else if (!regexec(&chartab.d_regex_oct, arg, 5, pmatch, 0)) regex_type = REGEX_OCT; else if (!regexec(&chartab.d_regex_hex, arg, 5, pmatch, 0)) regex_type = REGEX_HEX; else { if (message_show(MSG_ERR)) message("DEFINECHARTABLE: Entry `%s' not recognized", string_short(arg)); if (!(arg = strchr(arg, '\n'))) /* find next definition */ return; arg++; /* skip \n */ continue; /* retry at the next one */ } /* Got a match. Terminate the matched elements */ arg[pmatch[1].rm_eo] = 0; /* terminate matched char */ arg[pmatch[3].rm_eo] = 0; /* terminate matched string */ chartext = arg + pmatch[1].rm_so; /* Convert the matched character text to a char (key) value */ switch (regex_type) { case REGEX_HEX: sscanf(chartext, "%x", &uns_key); key = uns_key; break; case REGEX_OCT: sscanf(chartext, "%o", &uns_key); key = uns_key; if (key > 0xff) { if (message_show(MSG_ERR)) message("DEFINECHARTABLE: Character value `\\%s' " "exceeds 0%o (255)", chartext, 255); arg += pmatch[0].rm_eo + 1; continue; /* retry at the next one */ } break; case REGEX_PLAIN: { size_t dummy = 0; /* not used by ct_ascii */ key = ct_ascii(chartext, &dummy); } break; } if (message_show(MSG_INFO)) message("chartab[%s] = `%s'", chartext, arg + pmatch[3].rm_so); free(table[key]); table[key] = ct_string(arg + pmatch[3].rm_so); arg += pmatch[0].rm_eo + 1; } idx = strspn(arg, " \t\n"); if (arg[idx]) if (message_show(MSG_ERR)) message("DEFINECHARTABLE: Illegal table contents `%s'", string_short(arg + idx)); } yodl-3.06.00/src/string/0000755000175000017500000000000012573350735013722 5ustar frankfrankyodl-3.06.00/src/string/stringnew.c0000644000175000017500000000024612573350735016110 0ustar frankfrank#include "string.ih" String *string_new(char const *str) { register String *sp = new_memory(1, sizeof(String)); string_construct(sp, str); return sp; } yodl-3.06.00/src/string/stringshort.c0000644000175000017500000000054312573350735016456 0ustar frankfrank#include "string.ih" static char s_buf[30]; char const *string_short(register char const *s) { register char *cp; if (!s || !*s) return (""); strncpy(s_buf, s, 28); s_buf[29] = '\0'; if (strlen(s_buf) > 25) strcpy(s_buf + 25, "..."); while ((cp = strchr(s_buf, '\n'))) *cp = ' '; return s_buf; } yodl-3.06.00/src/string/string.h0000644000175000017500000001022512573350735015401 0ustar frankfrank#ifndef INCLUDED_STRING_H_ #define INCLUDED_STRING_H_ /* String stores ascii-Z strings. Char * args may be NULL. string_format() assumes C99 is active (see the snprintf() manpage) */ #include "../root/root.h" #include #include typedef struct { size_t d_size; /* buffer size of d_str */ size_t d_length; /* length not counting ascii-Z */ char *d_str; } String; void string_add(String *dest, String *src); void string_addchar(String *sp, int c); /* actually: c is a char */ void string_addcharOnce(String *sp, int c); /* not if already there */ void string_additerators(String *string, char const *begin, char const *end); void string_addstr(String *sp, char const *str); void string_assign(String *sp, char const *str); void string_copy(String *dest, String *src); size_t string_count(String *sp, char needle); void string_destructor(void *sp); /* frees sp + contents */ void string_fill(String *s, size_t length, int fill); /* FAILED if no such character */ size_t string_find_first_of(String *sp, char const *accept); size_t string_find_first_not_of(String *sp, int (*fun)(int)); char *string_firstword(char **str); /* returns new string */ /* or NULL if none */ /* *str points beyond */ /* assigns new contents */ void string_format(String *sp, char const *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(2, 3); String *string_new(char const *initext); char string_popfront(String *sp); char *string_release(String *sp); /* returns interal str */ /* don't use sp anymore. */ /* destroy/uctor isn't required */ /* (but can still be used) */ void string_replace(String *sp, char const *srch, char const *replace); /* allocates and formats */ /* returned string. size (incl. */ /* ascii-Z) in n */ char *string_str_replace(char const *cp, char const *srch, char const *replace); /* allocates and formats */ /* returned string. size (incl. */ /* ascii-Z) in n */ char *string_vformat(size_t *n, char const *fmt, va_list list) ATTRIBUTE_FORMAT_PRINTF(2, 0); void string_swallow(String *dest, String *src); /* dest eats src */ /* following string_swallow */ /* src is invalid */ char const *string_short (char const *s); char *string_strip(char **str); /* returns *str as stripped str */ /* Internal String use only. Not used outside of this directory, needed here to allow proper compilation of the static inline functions below */ #include extern char const s_stringEmpty[]; void s_init(String *sp, char const *txt); /* disregards sp's contents */ /* public interface continues from here */ static inline char const *string_str(register String const *sp) { return sp->d_str; } static inline size_t string_length(register String const *sp) { return sp->d_length; } static inline void string_erase(String *sp) /* resets to "" */ { string_assign(sp, 0); } static inline void string_destroy(register String *sp) { free(sp->d_str); } static inline void string_construct(String *s, char const *str) { s_init(s, str ? str : s_stringEmpty); } static inline int string_last(String const *sp) { return sp->d_length == 0 ? 0 : sp->d_str[sp->d_length - 1]; } #endif yodl-3.06.00/src/string/stringfirstword.c0000644000175000017500000000121312573350735017335 0ustar frankfrank#include "string.ih" char *string_firstword(char **str) { String ret; size_t begin = strspn(*str, " \t"); /* length of initial blanks */ size_t end = /* length of non blanks beyond */ strcspn(*str + begin, " \t"); if (!end) /* no first word */ return 0; string_construct(&ret, 0); *str += begin; /* skip blanks */ string_additerators(&ret, *str, *str + end); *str += end; /* skip beyond first word */ return string_release(&ret); } yodl-3.06.00/src/string/stringadditerators.c0000644000175000017500000000075712573350735020013 0ustar frankfrank#include "string.ih" void string_additerators(register String *string, char const *begin, char const *end) { size_t oldLength; size_t newLength; int addLength = end - begin; if (addLength <= 0) return; oldLength = string->d_length; newLength = oldLength + addLength; s_size(string, newLength); memcpy(string->d_str + oldLength, begin, (size_t)addLength); string->d_str[newLength] = 0; string->d_length = newLength; } yodl-3.06.00/src/string/stringswallow.c0000644000175000017500000000030212573350735017000 0ustar frankfrank#include "string.ih" void string_swallow(String *dest, String *src) { free(dest->d_str); dest->d_str = src->d_str; dest->d_length = src->d_length; dest->d_size = src->d_size; } yodl-3.06.00/src/string/stringassign.c0000644000175000017500000000023512573350735016601 0ustar frankfrank#include "string.ih" void string_assign(register String *sp, register char const *txt) { free(sp->d_str); s_init(sp, txt ? txt : s_stringEmpty); } yodl-3.06.00/src/string/string.ih0000644000175000017500000000047312573350735015556 0ustar frankfrank#include "string.h" #include #include #include #include #include #define STRING_BLOCK 80 #include "../root/root.h" #include "../new/new.h" #include "../message/message.h" void s_size(String *sp, size_t newsize); /* adds 1 for the ascii-z */ yodl-3.06.00/src/string/stringcopy.c0000644000175000017500000000020412573350735016263 0ustar frankfrank#include "string.ih" void string_copy(register String *dest, String *src) { free(dest->d_str); s_init(dest, src->d_str); } yodl-3.06.00/src/string/sinit.c0000644000175000017500000000053512573350735015217 0ustar frankfrank#include "string.ih" void s_init(register String *str, register char const *txt) { size_t newlength; if (*txt) newlength = strlen(txt); else { newlength = 0; txt = ""; } str->d_size = 0; str->d_str = 0; s_size(str, newlength); strcpy(str->d_str, txt); str->d_length = newlength; } yodl-3.06.00/src/string/stringstrreplace.c0000644000175000017500000000127712573350735017470 0ustar frankfrank#include "string.ih" char *string_str_replace(char const *left, char const *search, char const *replace) { size_t searchlen = search ? strlen(search) : 0; register char const *right; String out; if (!searchlen) /* search should have some length */ return new_str(left); { string_construct(&out, 0); while ((right = strstr(left, search))) { string_additerators(&out, left, right); string_addstr(&out, replace); left = right + searchlen; } string_addstr(&out, left); /* append the final tail */ return string_release(&out); } } yodl-3.06.00/src/string/stringfill.c0000644000175000017500000000031012573350735016235 0ustar frankfrank#include "string.ih" void string_fill(register String *s, size_t length, int fill) { s_size(s, length); memset(s->d_str, fill, length); s->d_str[length] = 0; s->d_length = length; } yodl-3.06.00/src/string/stringstrip.c0000644000175000017500000000161312573350735016457 0ustar frankfrank#include "string.ih" static bool s_initialized; static regex_t s_strip; static regmatch_t pmatch[2]; char *string_strip(char **str) { if (!s_initialized) { s_initialized = true; if ( regcomp ( &s_strip, "^[[:space:]]*" "(" "([^[:space:]].*[^[:space:]])" "|" "[^[:space:]]*" ")" "[[:space:]]*$" , REG_EXTENDED | REG_NEWLINE ) ) { message_show(MSG_EMERG); message("string_strip() regcomp() failed"); } } if (regexec(&s_strip, *str, 2, pmatch, 0)) /* no match */ **str = 0; else { (*str)[pmatch[1].rm_eo] = 0; *str += pmatch[1].rm_so; } return *str; } yodl-3.06.00/src/string/stringdestructor.c0000644000175000017500000000016412573350735017514 0ustar frankfrank#include "string.ih" void string_destructor(register void *sp) { string_destroy((String *)sp); free(sp); } yodl-3.06.00/src/string/stringfindfirstnotof.c0000644000175000017500000000047012573350735020354 0ustar frankfrank#include "string.ih" size_t string_find_first_not_of(register String *sp, register int (*fun)(int)) { size_t idx; for (idx = 0; idx < sp->d_length; idx++) { if (!(*fun)(sp->d_str[idx])) return idx; } return UFAILED; } yodl-3.06.00/src/string/stringrelease.c0000644000175000017500000000037412573350735016741 0ustar frankfrank#include "string.ih" /* returns d_str. Afther this the string is invalid, but destroy() can be used (as can destructor() */ char *string_release(register String *sp) { register char *ret = sp->d_str; sp->d_str = 0; return ret; } yodl-3.06.00/src/string/data.c0000644000175000017500000000006712573350735015002 0ustar frankfrank#include "string.ih" char const s_stringEmpty[] = ""; yodl-3.06.00/src/string/stringadd.c0000644000175000017500000000043712573350735016051 0ustar frankfrank#include "string.ih" void string_add(register String *dest, register String *src) { size_t newlength = dest->d_length + src->d_length; s_size(dest, newlength); strcpy ( dest->d_str + dest->d_length, src->d_str ); dest->d_length = newlength; } yodl-3.06.00/src/string/ssize.c0000644000175000017500000000057412573350735015231 0ustar frankfrank#include "string.ih" void s_size(register String *dest, register size_t newsize) { if (++newsize > dest->d_size) /* ++ to acount for ascii-Z */ { newsize += STRING_BLOCK; new_size ( &dest->d_str, newsize, dest->d_size, sizeof(char) ); dest->d_size = newsize; } } yodl-3.06.00/src/string/stringaddchar.c0000644000175000017500000000024412573350735016703 0ustar frankfrank#include "string.ih" static char s_buf[2]; void string_addchar(register String *sp, int c) { s_buf[0] = c; s_buf[1] = 0; string_addstr(sp, s_buf); } yodl-3.06.00/src/string/stringcount.c0000644000175000017500000000035512573350735016450 0ustar frankfrank#include "string.ih" size_t string_count(String *sp, char needle) { register size_t count = 0; register char *cp = sp->d_str; while ((cp = strchr(cp, needle))) { count++; cp++; } return count; } yodl-3.06.00/src/string/stringformat.c0000644000175000017500000000050612573350735016606 0ustar frankfrank#include "string.ih" /* string_format() assumes C99 is active (see the snprintf() manpage) */ void string_format(String *s, char const *fmt, ...) { va_list list; va_start(list, fmt); free(s->d_str); s->d_str = string_vformat(&s->d_size, fmt, list); s->d_length = s->d_size - 1; va_end(list); } yodl-3.06.00/src/string/stringaddstr.c0000644000175000017500000000046412573350735016602 0ustar frankfrank#include "string.ih" void string_addstr(register String *str, register char const *add) { size_t newlength; if (!add || !*add) return; newlength = str->d_length + strlen(add); s_size(str, newlength); strcpy(str->d_str + str->d_length, add); str->d_length = newlength; } yodl-3.06.00/src/string/stringfindfirstof.c0000644000175000017500000000030012573350735017623 0ustar frankfrank#include "string.ih" size_t string_find_first_of(register String *sp, char const *accept) { register char *cp = strpbrk(sp->d_str, accept); return !cp ? FAILED : (cp - sp->d_str); } yodl-3.06.00/src/string/stringreplace.c0000644000175000017500000000125412573350735016732 0ustar frankfrank#include "string.ih" void string_replace(String *str, char const *search, char const *replace) { size_t searchlen = search ? strlen(search) : 0; register char *left = str->d_str; register char *right; String out; if (!searchlen) /* search should have some length */ return; string_construct(&out, 0); while ((right = strstr(left, search))) { string_additerators(&out, left, right); string_addstr(&out, replace); left = right + searchlen; } string_addstr(&out, left); /* append the final tail */ string_copy(str, &out); string_destroy(&out); } yodl-3.06.00/src/string/stringpopfront.c0000644000175000017500000000030612573350735017163 0ustar frankfrank#include "string.ih" char string_popfront(register String *sp) { char front = *sp->d_str; if (sp->d_length) memmove(sp->d_str, sp->d_str + 1, sp->d_length--); return front; } yodl-3.06.00/src/string/stringaddcharonce.c0000644000175000017500000000021312573350735017544 0ustar frankfrank#include "string.ih" void string_addcharOnce(register String *sp, int c) { if (string_last(sp) != c) string_addchar(sp, c); } yodl-3.06.00/src/string/stringvformat.c0000644000175000017500000000062412573350735016775 0ustar frankfrank#include "string.ih" /* string_vformat() assumes C99 is active (see the snprintf() manpage) */ char *string_vformat(size_t *nret, char const *fmt, va_list list) { size_t n; register char *cp; va_list copy; va_copy(copy, list); n = 1 + vsnprintf(0, 0, fmt, list); vsnprintf(cp = new_memory(n, sizeof(char)), n, fmt, copy); va_end(copy); *nret = n; return cp; } yodl-3.06.00/src/builtin/0000755000175000017500000000000012573350735014062 5ustar frankfrankyodl-3.06.00/src/builtin/builtinsetaction.c0000644000175000017500000000031412573350735017604 0ustar frankfrank#include "builtin.ih" void (*builtin_setAction(Builtin *builtin, void (*action)(void)))(void) { void (*old_action)(void) = builtin->d_action; builtin->d_action = action; return old_action; } yodl-3.06.00/src/builtin/builtin.h0000644000175000017500000000076212573350735015706 0ustar frankfrank#ifndef INCLUDED_BUILTIN_H_ #define INCLUDED_BUILTIN_H_ #include "../hashmap/hashmap.h" typedef struct { char const *d_name; void (*d_action)(void); } Builtin; Builtin *builtin_copy(Builtin const *builtin); void builtin_insert(HashMap *symtab, Builtin *builtin); char const *builtin_name(Builtin const *builtin); void (*builtin_setAction(Builtin *builtin, void (*)(void)))(void); static inline void builtin_call(Builtin *builtin) { (*builtin->d_action)(); } #endif yodl-3.06.00/src/builtin/builtincopy.c0000644000175000017500000000033312573350735016566 0ustar frankfrank#include "builtin.ih" Builtin *builtin_copy(Builtin const *builtin) { Builtin *copy = new_memory(1, sizeof(Builtin)); copy->d_name = builtin->d_name; copy->d_action = builtin->d_action; return copy; } yodl-3.06.00/src/builtin/builtininsert.c0000644000175000017500000000043112573350735017117 0ustar frankfrank#include "builtin.ih" void builtin_insert(HashMap *symtab, Builtin *builtin) { while (builtin->d_name) { hashmap_insert ( symtab, hashitem_construct(BUILTIN, builtin->d_name, builtin, root_nop) ); builtin++; } } yodl-3.06.00/src/builtin/builtin.ih0000644000175000017500000000011412573350735016046 0ustar frankfrank#include "builtin.h" #include "../string/string.h" #include "../new/new.h" yodl-3.06.00/src/stack/0000755000175000017500000000000012573350735013521 5ustar frankfrankyodl-3.06.00/src/stack/demo/0000755000175000017500000000000012573350735014445 5ustar frankfrankyodl-3.06.00/src/stack/demo/demo.c0000644000175000017500000000455012573350735015541 0ustar frankfrank/* Compile using gcc demo.c ../out/library.a \ ../../string/out/library.a \ ../../new/out/library.a \ ../../message/out/library.a \ ../../root/out/library.a */ #include #include #include #include "../../root/root.h" #include "../../message/message.h" #include "../stack.h" int main(int argc, char **argv) { Stack intStack; /* stack of ints */ Stack txtStack; /* stack of char *'s */ int idx; stack_construct(&intStack, NULL); /* no destructor */ stack_construct(&txtStack, free); /* free() is destructor */ stack_destroy(&txtStack); /* destroy an empty stack */ stack_construct(&txtStack, free); /* reconstruct it */ for (idx = 0; idx < 20; idx++) /* Push 10 values on inttack */ { stack_push(&intStack, (void *)(2 * idx)); printf("Intstack %d contains %d\n", idx, stack_tos(&intStack)); } stack_assign(&intStack, (void *)100); /* reassing topmost element */ printf("intstack has %u elements\n", stack_size(&intStack)); for (idx = 0; idx < 5; idx++) /* Pop 5 values from inttack */ { printf("After popping %d elements, top contains %d\n", idx, stack_tos(&intStack)); stack_pop(&intStack); } stack_destroy(&intStack); /* destroy the rest */ for (idx = 0; idx < argc; idx++) /* Push argv's on txtstack */ { stack_push(&txtStack, new_str(argv[idx])); printf("Txtstack %d contains %s\n", idx, stack_tos(&txtStack)); } /* reassing topmost element */ stack_assign(&txtStack, new_str("Hello world")); printf("txtstack has %u elements\n", stack_size(&txtStack)); for (idx = 0; idx < argc - 1; idx++) /* Pop all elements but one */ { printf("After popping %d elements, top contains %s\n", idx, stack_tos(&txtStack)); stack_pop(&txtStack); } printf("txtstack has %u elements\n", stack_size(&txtStack)); stack_destroy(&txtStack); /* destroy the stack */ } yodl-3.06.00/src/stack/stackdestroy.c0000644000175000017500000000041412573350735016403 0ustar frankfrank#include "stack.ih" void stack_destroy(void *sp) { size_t idx = ((Stack *)sp)->d_n; register StackValue *stack = ((Stack *)sp)->d_value; for ( ; idx--; stack++) (*((Stack *)sp)->d_destructor)(stack->u_voidp); free(((Stack *)sp)->d_value); } yodl-3.06.00/src/stack/stnop.c0000644000175000017500000000007012573350735015025 0ustar frankfrank#include "stack.ih" void st_nop(register void *nop) {} yodl-3.06.00/src/stack/data.c0000644000175000017500000000006612573350735014600 0ustar frankfrank#include "stack.ih" StackValue stFailed = {PFAILED}; yodl-3.06.00/src/stack/stack.ih0000644000175000017500000000036712573350735015156 0ustar frankfrank#include "stack.h" #include #include "../new/new.h" #include "../message/message.h" #define STACK_BLOCK 10 void st_nop(void *); /* does nothing */ Result st_push(register Stack *sp, register StackValue element); yodl-3.06.00/src/stack/stackcontains.c0000644000175000017500000000042012573350735016525 0ustar frankfrank#include "stack.ih" bool stack_contains(Stack *sp, char const **ctab) { register StackValue *vp = sp->d_value; register size_t idx; for (idx = sp->d_n; idx--; vp++) { if (ctab == vp->u_charCpp) return true; } return false; } yodl-3.06.00/src/stack/stackassign.c0000644000175000017500000000065112573350735016201 0ustar frankfrank#include "stack.ih" /* stack will own `value': its destructor will eventually be called by the stack. stack_assign will push value on the stack if it's still empty. */ void stack_assign(register Stack *sp, register StackValue value) { size_t n = sp->d_n; if (!n) stack_push(sp, value); else { (*sp->d_destructor)(sp->d_value[n - 1].u_voidp); sp->d_value[n - 1] = value; } } yodl-3.06.00/src/stack/stackpop.c0000644000175000017500000000034512573350735015513 0ustar frankfrank#include "stack.ih" void stack_pop(register Stack *sp) { if (!sp->d_n) if (message_show(MSG_EMERG)) message("Stack underflow of stack %p", sp); (*sp->d_destructor)(sp->d_value[--sp->d_n].u_voidp); } yodl-3.06.00/src/stack/stack.h0000644000175000017500000000652412573350735015006 0ustar frankfrank#ifndef INCLUDED_STACK_H_ #define INCLUDED_STACK_H_ #include "../root/root.h" #include "../string/string.h" #include "../media/media.h" /* The stack's destructor destroys the contents of the elements of the stack. So, at destruction time d_destructor(d_value[idx]) is called. The stack_constructor's argument may be NULL, in which case no destruction takes place. If the element itself is a pointer to a plainly allocated block of memory, then free()'s address may be specified to free the element. If the element itself is a dynamically allocated struct, itself containing allocated memory, then the destructor should: 1. free the memory allocated by the struct 2. free the struct itself. Use the following convention: X_destroy(X *xp) destroys any memory allocated by the X struct, X_destructor(X *xp) calls X_destroy(xp), and then free(xp). Elements the size of a pointer can be stored safely in the stack, when NULL is specified as the destructor (e.g., ints). However, in that case stack_tos()'s return value PFAILED cannot be discerned from the value FAILED, which may be at the stacktop. However, if stack_size() returns a value != 0, stack_tos()'s return value is always ok. */ struct Parser; /* required for the StackValue union definition */ typedef union /* Note: all fields start with u_, which doesn't mean */ { /* `unsigned' */ char *u_charp; char const *u_charCp; char **u_charpp; char const **u_charCpp; int u_int; size_t u_size_t; void *u_voidp; void const *u_voidCp; Media *u_Media; String *u_Stringp; /* Parser function pointers */ bool (**u_Pfun1p)(struct Parser *); void (*u_Pfun2p)(struct Parser *, char const *); } StackValue; typedef struct { size_t d_size; size_t d_n; StackValue *d_value; void (*d_destructor)(void *); } Stack; void stack_assign(Stack *sp, StackValue value); /* if empty, value is pushed */ /* if used, topmost is destroyed */ /* and `value' is stored instead */ void stack_construct(Stack *sp, void (*destructor)(void *)); /* only used by chartab_find() */ bool stack_contains(Stack *sp, char const **ctab); /* true: yes */ void stack_destroy(void *sp); void stack_pop(Stack *sp); /* removes top elemenet from stack */ /* always SUCCESS, but sp must be */ /* a valid pointer */ Result stack_push(Stack *sp, StackValue value); /* Internal Stack use only. Not used outside of this directory, needed here to allow proper compilation of the static inline functions below */ extern StackValue stFailed; /* public interface continues from here */ /* topmost element or {PFAILED} */ static inline StackValue *stack_tos(Stack const *sp) { return sp->d_n ? sp->d_value + sp->d_n - 1 : &stFailed; } static inline size_t stack_size(Stack const *sp) { return sp->d_n; } #endif yodl-3.06.00/src/stack/stackconstruct.c0000644000175000017500000000042712573350735016742 0ustar frankfrank#include "stack.ih" void stack_construct(register Stack *sp, void (*destructor)(void *)) { memset(sp, 0, sizeof(Stack)); sp->d_size = STACK_BLOCK; sp->d_value = new_memory(STACK_BLOCK, sizeof(void *)); sp->d_destructor = destructor != 0 ? destructor : st_nop; } yodl-3.06.00/src/stack/stackpush.c0000644000175000017500000000051212573350735015670 0ustar frankfrank#include "stack.ih" Result stack_push(register Stack *sp, register StackValue element) { register size_t last = sp->d_n++; if (last == sp->d_size) new_size(&sp->d_value, sp->d_size += STACK_BLOCK, last, sizeof(StackValue)); sp->d_value[last] = element; return SUCCESS; } yodl-3.06.00/src/subst/0000755000175000017500000000000012573350735013554 5ustar frankfrankyodl-3.06.00/src/subst/demo/0000755000175000017500000000000012573350735014500 5ustar frankfrankyodl-3.06.00/src/subst/demo/demo.c0000644000175000017500000000253512573350735015575 0ustar frankfrank/* Compile using gcc demo.c ../out/library.a \ ../../string/out/library.a \ ../../new/out/library.a \ ../../message/out/library.a \ ../../root/out/library.a */ #include #include #include #include "../../root/root.h" #include "../../message/message.h" #include "../subst.h" char buffer[80]; int main(int argc, char **argv) { Subst subst; message_setseverity(MSG_NOTICE | MSG_ERR); subst_construct(&subst); /* construct the Subst object */ subst_insert(&subst, "DEMO", "one", "ONE SUBST"); subst_insert(&subst, "DEMO", "one", "TWO SUBST"); subst_insert(&subst, "DEMO", "\\'e", "é"); while (true) { char *cp; puts("Enter text: "); if (!fgets(buffer, 80, stdin) || buffer[0] == '\n') break; for (cp = buffer; *cp && *cp != '\n'; cp++) { printf("Inspecting char `%c': ", *cp); if (subst_find(&subst, *cp)) printf("found. Swallowed by subst\n"); else { char *txt = new_str(subst_text(&subst)); printf("Not found. Next returned: `%c(`%s')\n", subst_get(&subst), txt ? txt : ""); free(txt); } } } } yodl-3.06.00/src/subst/sstatetransition.c0000644000175000017500000000127312573350735017341 0ustar frankfrank#include "subst.ih" bool s_state_transition(State **state_pp, int ch) { register char const *cp; register State *sp = *state_pp; /* sp: current state */ if ((cp = strchr(sp->d_str, ch)) == 0) /* ch not in this state */ return false; *state_pp = sp->d_next[cp - sp->d_str]; /* change to state */ /* corresponding to the */ /* matched character */ (*state_pp)->d_parent = sp; /* set the parent state */ /* in the next state */ return true; } yodl-3.06.00/src/subst/substconstruct.c0000644000175000017500000000025712573350735017031 0ustar frankfrank#include "subst.ih" void subst_construct(register Subst *sp) { string_construct(&sp->d_buffer, 0); sp->d_start_state_ptr = sp->d_current_state_ptr = s_state_new(); } yodl-3.06.00/src/subst/subst.h0000644000175000017500000000117412573350735015070 0ustar frankfrank#ifndef INCLUDED_SUBST_H_ #define INCLUDED_SUBST_H_ #include #include "../root/root.h" #include "../message/message.h" #include "../string/string.h" typedef enum { SUBST_CONTINUE, SUBST_GETCHAR, SUBST_SUBSTITUTION } SubstAction; typedef struct { String d_buffer; void *d_start_state_ptr; void *d_current_state_ptr; } Subst; SubstAction subst_action(Subst *sp, int ch); void subst_construct(Subst *sp); char *subst_get(Subst *sp); void subst_insert(Subst *sp, char const *fname, char const *key, char const *value); #endif yodl-3.06.00/src/subst/substaction.c0000644000175000017500000000315612573350735016263 0ustar frankfrank#include "subst.ih" /* if ch is not EOF and found in the current state transition, then add it to the buffer holding the matched characters (so far). If there isn't a match, but if there is a replacement, then put the replacement into the buffer. If there isn't a match, but there was a match earlier, then put the earlier replacement and all later characters into the buffer, and indicate a substitution as well */ SubstAction subst_action(register Subst *sp, int ch) { size_t n_keep; register char const *text; /* char found in the current */ if /* state ? */ ( ch != EOF /* if not an EOF char */ && /* and if state transition */ s_state_transition((State **)(void *)&sp->d_current_state_ptr, ch) ) { /* add char to `matched so far' */ string_addchar(&sp->d_buffer, ch); return SUBST_CONTINUE; } n_keep = 0; /* replacement seen ? */ if ((text = s_state_replacement(sp->d_current_state_ptr, &n_keep))) { size_t length = string_length(&sp->d_buffer); char *buffer = string_release(&sp->d_buffer); string_assign(&sp->d_buffer, text); string_addstr(&sp->d_buffer, buffer + length - n_keep); free(buffer); } if (ch != EOF) string_addchar(&sp->d_buffer, ch); return text == 0 ? SUBST_GETCHAR : SUBST_SUBSTITUTION; } yodl-3.06.00/src/subst/sstateinsert.c0000644000175000017500000000267512573350735016462 0ustar frankfrank#include "subst.ih" char const *s_state_insert(register State *sp, char const *key, char const *subst) { while (*key) { register char const *cp; /* if key is in the set, switch to */ if ((cp = strchr(sp->d_str, *key)) != 0) /* that state */ sp = sp->d_next[cp - sp->d_str]; else { /* if not, add a new state to the */ size_t last = string_length(&sp->d_set); /* set */ string_addchar(&sp->d_set, (char)*key); /* add key's 1st char */ sp->d_str = string_str(&sp->d_set); /* and set the state's ptr */ /* add a new state */ new_size(&sp->d_next, last + 1, last, sizeof(State *)); sp = sp->d_next[last] = s_state_new(); } key++; /* inspect the next key char */ } /* all key chars exhausted: insert */ /* replacement text */ if (sp->d_replacement) /* oops, it's already there */ return sp->d_replacement; /* return the one found */ sp->d_replacement = new_str(subst); return 0; /* here 0 indicates SUCCESS */ } yodl-3.06.00/src/subst/sstatereplacement.c0000644000175000017500000000053712573350735017450 0ustar frankfrank#include "subst.ih" char const *s_state_replacement(register State const *sp, register size_t *n_back) { register char const *text; while (true) { if ((text = sp->d_replacement)) return text; if (!(sp = sp->d_parent)) return 0; ++*n_back; } } yodl-3.06.00/src/subst/subst.ih0000644000175000017500000000122112573350735015232 0ustar frankfrank#include "subst.h" #include "../new/new.h" typedef struct State { String d_set; char const *d_str; struct State **d_next; struct State *d_parent; /* where do we come from */ char *d_replacement; } State; /* NULL if subst(itution) inserted */ /* otherwise: already def'd subst. */ char const *s_state_insert(State *sp, char const *key, char const *subst); State *s_state_new(void); char const *s_state_replacement(State const *sp, size_t *n_keep); bool s_state_transition(State **sp, int ch); yodl-3.06.00/src/subst/substget.c0000644000175000017500000000035012573350735015556 0ustar frankfrank#include "subst.ih" char *subst_get(register Subst *sp) { register char *cp; sp->d_current_state_ptr = sp->d_start_state_ptr; cp = string_release(&sp->d_buffer); string_construct(&sp->d_buffer, 0); return cp; } yodl-3.06.00/src/subst/substinsert.c0000644000175000017500000000110612573350735016303 0ustar frankfrank#include "subst.ih" void subst_insert(register Subst *sp, char const *fname, char const *key, char const *value) { char const *text; char *short_value = new_str(string_short(value)); if ((text = s_state_insert(sp->d_start_state_ptr, key, value)) == 0) { if (message_show(MSG_NOTICE)) message("%s(%s)(%s)", fname, key, short_value); } else if (message_show(MSG_ERR)) message("%s(%s)(%s): Keeping existing definition `%s'", fname, key, short_value, string_short(text)); free(short_value); } yodl-3.06.00/src/subst/sstatenew.c0000644000175000017500000000035212573350735015735 0ustar frankfrank#include "subst.ih" State *s_state_new() { register State *sp = new_calloc(1, sizeof(State)); string_construct(&sp->d_set, 0); sp->d_str = string_str(&sp->d_set); /* locally avail. searchstring */ return sp; } yodl-3.06.00/src/counter/0000755000175000017500000000000012573350735014073 5ustar frankfrankyodl-3.06.00/src/counter/countervalue.c0000644000175000017500000000022612573350735016753 0ustar frankfrank#include "counter.ih" int counter_value(HashItem *item) { Stack *sp = co_sp(item, true); return sp == PFAILED ? 0 : stack_tos(sp)->u_int; } yodl-3.06.00/src/counter/cosp.c0000644000175000017500000000076412573350735015212 0ustar frankfrank#include "counter.ih" Stack *co_sp(HashItem *item, bool errOnFailure) { Stack *sp; if (item == PFAILED) { if (errOnFailure) if (message_show(MSG_ERR)) message("Missing counter stack"); return PFAILED; } if (stack_size(sp = (Stack *)hashitem_value(item))) return sp; if (errOnFailure) if (message_show(MSG_ERR)) message("No stacked value for counter `%s'", hashitem_key(item)); return PFAILED; } yodl-3.06.00/src/counter/counterinsert.c0000644000175000017500000000044712573350735017150 0ustar frankfrank#include "counter.ih" Result counter_insert(HashMap *symtab, char const *key, int value) { return hashmap_insert ( symtab, hashitem_construct(COUNTER, key, co_construct(value), stack_destroy) ); } yodl-3.06.00/src/counter/coconstruct.c0000644000175000017500000000047112573350735016607 0ustar frankfrank#include "counter.ih" Stack *co_construct(int value) { Stack *counter = (Stack *)new_memory(1, sizeof(Stack)); register StackValue stValue; stack_construct(counter, 0); /* just values, nothing allocated */ stValue.u_int = value; stack_push(counter, stValue); return counter; } yodl-3.06.00/src/counter/counter.ih0000644000175000017500000000032212573350735016071 0ustar frankfrank#include "counter.h" #include #include "../stack/stack.h" #include "../message/message.h" #include "../new/new.h" Stack *co_construct(int value); Stack *co_sp(HashItem *item, bool errOnFailure); yodl-3.06.00/src/counter/counterset.c0000644000175000017500000000036512573350735016436 0ustar frankfrank#include "counter.ih" void counter_set(HashItem *item, int value) { Stack *sp = co_sp(item, true); if (sp != PFAILED) { register StackValue stValue; stValue.u_int = value; stack_assign(sp, stValue); } } yodl-3.06.00/src/counter/counteradd.c0000644000175000017500000000041012573350735016362 0ustar frankfrank#include "counter.ih" void counter_add(HashItem *item, int value) { Stack *sp = co_sp(item, true); if (sp != PFAILED) { register StackValue stValue = *stack_tos(sp); stValue.u_int += value; stack_assign(sp, stValue); } } yodl-3.06.00/src/counter/counterhasvalue.c0000644000175000017500000000037212573350735017451 0ustar frankfrank#include "counter.ih" bool counter_has_value(int *valuePtr, HashItem *item) { Stack *sp = (Stack *)hashitem_value(item); if (sp == PFAILED || !stack_size(sp)) return false; *valuePtr = stack_tos(sp)->u_int; return true; } yodl-3.06.00/src/counter/counter.h0000644000175000017500000000107712573350735015730 0ustar frankfrank#ifndef INCLUDED_COUNTER_H_ #define INCLUDED_COUNTER_H_ #include "../root/root.h" #include "../hashmap/hashmap.h" void counter_add(HashItem *item, int add); /* err if no counter */ bool counter_has_value(int *valuePtr, HashItem *item); Result counter_insert(HashMap *symtab, char const *key, int value); void counter_set(HashItem *item, int value); /* err if no counter */ char const *counter_text(HashItem *item); /* returns static buffer */ int counter_value(HashItem *item); /* err if no stack/item */ #endif yodl-3.06.00/src/counter/countertext.c0000644000175000017500000000025612573350735016626 0ustar frankfrank#include "counter.ih" static char valueText[40]; char const *counter_text(HashItem *item) { snprintf(valueText, 40, "%d", counter_value(item)); return valueText; }