From 65b0aeaecd75e081993c48db2837958073185165 Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Mon, 24 Jul 2006 15:47:40 +0000 Subject: Relevant BUGIDs: Purpose of commit: bugfixes Commit summary: --------------- 2006-07-24 Thorsten Kukuk * doc/adg/Makefile.am: Add uninstall and distclean rules. * doc/mwg/Makefile.am: Likewise. * doc/sag/Makefile.am: Likewise. 2006-07-08 Daniel Richard G. * conf/pam_conv1/Makefile.am: Fix rules for lex and yacc files. * conf/pam_conv1/pam_conv.lex: Rename to ... * conf/pam_conv1/pam_conv_l.l: ... this. * conf/pam_conv1/pam_conv.y: Rename to ... * conf/pam_conv1/pam_conv_y.y: ... this. * configure.in: Add AC_HELP_STRING()s to various AC_ARG_ENABLE() calls. * doc/Makefile.am: Fix rule to install index.html. * doc/adg/Makefile.am: Fix test usage. * doc/mwg/Makefile.am: Likewise. * doc/sag/Makefile.am: Likewise. * doc/specs/Makefile.am: Fix rules for lex and yacc files. * specs/parse.lex: Rename to ... * doc/specs/parse_l.l: ... this. * doc/specs/parse.y: Rename to ... * doc/specs/parse_y.y: ... this. * libpam/pam_account.c: Fix #if vs. #ifdef. * libpam/pam_audit.c: Likewise. * libpam/pam_auth.c: Likewise. * libpam/pam_password.c: Likewise. * libpam/pam_private.h: Likewise. * libpam/pam_session.c: Likewise. * libpam/pam_start.c: Likewise. * libpam/pam_static.c: Fix "empty sourcefile" warning. * modules/pam_limits/pam_limits.c: Check for __linux, too. * modules/pam_userdb/Makefile.am: Don't run test if no libdb available. * tests/tst-dlopen.c: Include config.h. --- doc/Makefile.am | 8 +- doc/adg/Makefile.am | 22 +++- doc/mwg/Makefile.am | 28 +++-- doc/sag/Makefile.am | 21 +++- doc/specs/Makefile.am | 19 ++-- doc/specs/parse.lex | 11 -- doc/specs/parse.y | 294 ------------------------------------------------- doc/specs/parse_l.l | 21 ++++ doc/specs/parse_y.y | 297 ++++++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 378 insertions(+), 343 deletions(-) delete mode 100644 doc/specs/parse.lex delete mode 100644 doc/specs/parse.y create mode 100644 doc/specs/parse_l.l create mode 100644 doc/specs/parse_y.y (limited to 'doc') diff --git a/doc/Makefile.am b/doc/Makefile.am index 31085a5c..a1155184 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -6,13 +6,11 @@ SUBDIRS = man specs sag adg mwg CLEANFILES = *~ -EXTRA_DIST = index.html +htmldir = $(DOCDIR)/html -####################################################### +dist_html_DATA = index.html -install-data-local: - $(mkinstalldirs) $(DESTDIR)$(DOCDIR)/html - install -m 644 $(srcdir)/index.html $(DESTDIR)$(DOCDIR)/html/ +####################################################### releasedocs: all $(mkinstalldirs) $(top_builddir)/Linux-PAM-$(VERSION)/doc/specs diff --git a/doc/adg/Makefile.am b/doc/adg/Makefile.am index 7ba2ab0d..d2531db2 100644 --- a/doc/adg/Makefile.am +++ b/doc/adg/Makefile.am @@ -45,6 +45,10 @@ html/Linux-PAM_ADG.html: $(XMLS) --stringparam section.label.includes.component.label 1 \ --stringparam toc.max.depth 3 --xinclude --nonet \ http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl $< + +distclean-local: + -rm -rf html Linux-PAM_ADG.txt Linux-PAM_ADG.pdf + endif install-data-local: @@ -52,35 +56,41 @@ install-data-local: $(mkinstalldirs) $(DESTDIR)$(DOCDIR)/txt $(mkinstalldirs) $(DESTDIR)$(DOCDIR)/pdf $(mkinstalldirs) $(DESTDIR)$(DOCDIR)/html - test -f html/Linux-PAM_ADG.html && \ + test -f html/Linux-PAM_ADG.html || exit 0; \ $(install_sh_DATA) html/Linux-PAM_ADG.html html/adg-*.html \ $(DESTDIR)$(DOCDIR)/html/ || \ $(install_sh_DATA) $(srcdir)/html/Linux-PAM_ADG.html \ $(srcdir)/html/sag-*.html \ $(DESTDIR)$(DOCDIR)/html/ - test -f Linux-PAM_ADG.txt && \ + test -f Linux-PAM_ADG.txt || exit 0; \ $(install_sh_DATA) Linux-PAM_ADG.txt $(DESTDIR)$(DOCDIR)/txt/ || \ $(install_sh_DATA) $(srcdir)/Linux-PAM_ADG.txt \ $(DESTDIR)$(DOCDIR)/txt/ - test -f Linux-PAM_ADG.pdf && \ + test -f Linux-PAM_ADG.pdf || exit 0; \ $(install_sh_DATA) Linux-PAM_ADG.pdf $(DESTDIR)$(DOCDIR)/pdf/ || \ $(install_sh_DATA) $(srcdir)/Linux-PAM_ADG.pdf \ $(DESTDIR)$(DOCDIR)/pdf/ +uninstall-local: + -rm $(DESTDIR)$(DOCDIR)/html/Linux-PAM_ADG.html + -rm $(DESTDIR)$(DOCDIR)/html/adg-*.html + -rm $(DESTDIR)$(DOCDIR)/txt/Linux-PAM_ADG.txt + -rm $(DESTDIR)$(DOCDIR)/pdf/Linux-PAM_ADG.pdf + releasedocs: all $(mkinstalldirs) $(top_builddir)/Linux-PAM-$(VERSION)/doc/adg/html - test -f html/Linux-PAM_ADG.html && \ + test -f html/Linux-PAM_ADG.html || exit 0; \ cp -ap html/Linux-PAM_ADG.html html/adg-*.html \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/adg/html/ || \ cp -ap $(srcdir)/html/Linux-PAM_ADG.html \ $(srcdir)/html/adg-*.html \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/adg/html/ - test -f Linux-PAM_ADG.txt && \ + test -f Linux-PAM_ADG.txt || exit 0; \ cp -p Linux-PAM_ADG.txt \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/adg/ || \ cp -p $(srcdir)/Linux-PAM_ADG.txt \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/adg/ - test -f Linux-PAM_ADG.pdf && \ + test -f Linux-PAM_ADG.pdf || exit 0; \ cp -p Linux-PAM_ADG.pdf \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/adg/ || \ cp -p $(srcdir)/Linux-PAM_ADG.pdf \ diff --git a/doc/mwg/Makefile.am b/doc/mwg/Makefile.am index f1b452f1..dbda086f 100644 --- a/doc/mwg/Makefile.am +++ b/doc/mwg/Makefile.am @@ -21,7 +21,7 @@ if ENABLE_GENERATE_PDF --stringparam section.label.includes.component.label 1 \ --stringparam toc.max.depth 3 --xinclude --nonet \ http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl $< > Linux-PAM_MWG.fo - $(FO2PDF) Linux-PAM_MWG.fo $(srcdir)/$@ + $(FO2PDF) Linux-PAM_MWG.fo $@ else echo "No fo2pdf processor installed, skip PDF generation" endif @@ -32,10 +32,10 @@ Linux-PAM_MWG.txt: $(XMLS) --stringparam section.autolabel 1 \ --stringparam section.label.includes.component.label 1 \ --stringparam toc.max.depth 3 --xinclude --nonet \ - http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< | $(BROWSER) > $(srcdir)/$@ + http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< | $(BROWSER) > $@ html/Linux-PAM_MWG.html: $(XMLS) - @test -d $(srcdir)/html || mkdir -p $(srcdir)/html + @test -d html || mkdir -p html $(XMLLINT) --nonet --xinclude --postvalid --noent --noout $< $(XSLTPROC) --stringparam base.dir html/ \ --stringparam root.filename Linux-PAM_MWG \ @@ -45,6 +45,10 @@ html/Linux-PAM_MWG.html: $(XMLS) --stringparam section.label.includes.component.label 1 \ --stringparam toc.max.depth 3 --xinclude --nonet \ http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl $< + +distclean-local: + -rm -rf html Linux-PAM_MWG.txt Linux-PAM_MWG.pdf + endif install-data-local: @@ -52,35 +56,41 @@ install-data-local: $(mkinstalldirs) $(DESTDIR)$(DOCDIR)/txt $(mkinstalldirs) $(DESTDIR)$(DOCDIR)/pdf $(mkinstalldirs) $(DESTDIR)$(DOCDIR)/html - test -f html/Linux-PAM_MWG.html && \ + test -f html/Linux-PAM_MWG.html || exit 0; \ $(install_sh_DATA) html/Linux-PAM_MWG.html html/mwg-*.html \ $(DESTDIR)$(DOCDIR)/html/ || \ $(install_sh_DATA) $(srcdir)/html/Linux-PAM_MWG.html \ $(srcdir)/html/sag-*.html \ $(DESTDIR)$(DOCDIR)/html/ - test -f Linux-PAM_MWG.txt && \ + test -f Linux-PAM_MWG.txt || exit 0; \ $(install_sh_DATA) Linux-PAM_MWG.txt $(DESTDIR)$(DOCDIR)/txt/ || \ $(install_sh_DATA) $(srcdir)/Linux-PAM_MWG.txt \ $(DESTDIR)$(DOCDIR)/txt/ - test -f Linux-PAM_MWG.pdf && \ + test -f Linux-PAM_MWG.pdf || exit 0; \ $(install_sh_DATA) Linux-PAM_MWG.pdf $(DESTDIR)$(DOCDIR)/pdf/ || \ $(install_sh_DATA) $(srcdir)/Linux-PAM_MWG.pdf \ $(DESTDIR)$(DOCDIR)/pdf/ +uninstall-local: + -rm $(DESTDIR)$(DOCDIR)/html/Linux-PAM_MWG.html + -rm $(DESTDIR)$(DOCDIR)/html/mwg-*.html + -rm $(DESTDIR)$(DOCDIR)/txt/Linux-PAM_MWG.txt + -rm $(DESTDIR)$(DOCDIR)/pdf/Linux-PAM_MWG.pdf + releasedocs: all $(mkinstalldirs) $(top_builddir)/Linux-PAM-$(VERSION)/doc/mwg/html - test -f html/Linux-PAM_MWG.html && \ + test -f html/Linux-PAM_MWG.html || exit 0; \ cp -ap html/Linux-PAM_MWG.html html/mwg-*.html \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/mwg/html/ || \ cp -ap $(srcdir)/html/Linux-PAM_MWG.html \ $(srcdir)/html/mwg-*.html \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/mwg/html/ - test -f Linux-PAM_MWG.txt && \ + test -f Linux-PAM_MWG.txt || exit 0; \ cp -p Linux-PAM_MWG.txt \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/mwg/ || \ cp -p $(srcdir)/Linux-PAM_MWG.txt \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/mwg/ - test -f Linux-PAM_MWG.pdf && \ + test -f Linux-PAM_MWG.pdf || exit 0; \ cp -p Linux-PAM_MWG.pdf \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/mwg/ || \ cp -p $(srcdir)/Linux-PAM_MWG.pdf \ diff --git a/doc/sag/Makefile.am b/doc/sag/Makefile.am index 1efc6d4e..fe1e7835 100644 --- a/doc/sag/Makefile.am +++ b/doc/sag/Makefile.am @@ -45,6 +45,9 @@ html/Linux-PAM_SAG.html: $(XMLS) --stringparam section.label.includes.component.label 1 \ --stringparam toc.max.depth 2 --xinclude --nonet \ http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl $< + +distclean-local: + -rm -rf html Linux-PAM_SAG.txt Linux-PAM_SAG.pdf endif install-data-local: @@ -52,35 +55,41 @@ install-data-local: $(mkinstalldirs) $(DESTDIR)$(DOCDIR)/txt $(mkinstalldirs) $(DESTDIR)$(DOCDIR)/pdf $(mkinstalldirs) $(DESTDIR)$(DOCDIR)/html - test -f html/Linux-PAM_SAG.html && \ + test -f html/Linux-PAM_SAG.html || exit 0; \ $(install_sh_DATA) html/Linux-PAM_SAG.html html/sag-*.html \ $(DESTDIR)$(DOCDIR)/html/ || \ $(install_sh_DATA) $(srcdir)/html/Linux-PAM_SAG.html \ $(srcdir)/html/sag-*.html \ $(DESTDIR)$(DOCDIR)/html/ - test -f Linux-PAM_SAG.txt && \ + test -f Linux-PAM_SAG.txt || exit 0; \ $(install_sh_DATA) Linux-PAM_SAG.txt $(DESTDIR)$(DOCDIR)/txt/ || \ $(install_sh_DATA) $(srcdir)/Linux-PAM_SAG.txt \ $(DESTDIR)$(DOCDIR)/txt/ - test -f Linux-PAM_SAG.pdf && \ + test -f Linux-PAM_SAG.pdf || exit 0; \ $(install_sh_DATA) Linux-PAM_SAG.pdf $(DESTDIR)$(DOCDIR)/pdf/ || \ $(install_sh_DATA) $(srcdir)/Linux-PAM_SAG.pdf \ $(DESTDIR)$(DOCDIR)/pdf/ +uninstall-local: + -rm $(DESTDIR)$(DOCDIR)/html/Linux-PAM_SAG.html + -rm $(DESTDIR)$(DOCDIR)/html/sag-*.html + -rm $(DESTDIR)$(DOCDIR)/txt/Linux-PAM_SAG.txt + -rm $(DESTDIR)$(DOCDIR)/pdf/Linux-PAM_SAG.pdf + releasedocs: all $(mkinstalldirs) $(top_builddir)/Linux-PAM-$(VERSION)/doc/sag/html - test -f html/Linux-PAM_SAG.html && \ + test -f html/Linux-PAM_SAG.html || exit 0; \ cp -ap html/Linux-PAM_SAG.html html/sag-*.html \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/sag/html/ || \ cp -ap $(srcdir)/html/Linux-PAM_SAG.html \ $(srcdir)/html/sag-*.html \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/sag/html/ - test -f Linux-PAM_SAG.txt && \ + test -f Linux-PAM_SAG.txt || exit 0; \ cp -p Linux-PAM_SAG.txt \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/sag/ || \ cp -p $(srcdir)/Linux-PAM_SAG.txt \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/sag/ - test -f Linux-PAM_SAG.pdf && \ + test -f Linux-PAM_SAG.pdf || exit 0; \ cp -p Linux-PAM_SAG.pdf \ $(top_builddir)/Linux-PAM-$(VERSION)/doc/sag/ || \ cp -p $(srcdir)/Linux-PAM_SAG.pdf \ diff --git a/doc/specs/Makefile.am b/doc/specs/Makefile.am index 53641678..440e0076 100644 --- a/doc/specs/Makefile.am +++ b/doc/specs/Makefile.am @@ -6,24 +6,19 @@ CLEANFILES = draft-morgan-pam-current.txt *~ EXTRA_DIST = draft-morgan-pam.raw std-agent-id.raw rfc86.0.txt -all: draft-morgan-pam-current.txt - test -f rfc86.0.txt || cp -p $(srcdir)/rfc86.0.txt . - draft-morgan-pam-current.txt: padout draft-morgan-pam.raw ./padout < $(srcdir)/draft-morgan-pam.raw > draft-morgan-pam-current.txt +AM_YFLAGS = -d + +BUILT_SOURCES = parse_y.h + noinst_PROGRAMS = padout -padout_SOURCES = parse.y parse.lex +padout_SOURCES = parse_l.l parse_y.y padout_LDADD = @LEXLIB@ -parse.c: lex.yy.c - -lex.yy.c: $(srcdir)/parse.lex - $(LEX) $(srcdir)/parse.lex +specdir = $(DOCDIR)/spec -install-data-local: - $(mkinstalldirs) $(DESTDIR)$(DOCDIR)/spec - $(INSTALL_DATA) draft-morgan-pam-current.txt $(DESTDIR)$(DOCDIR)/spec/ - $(INSTALL_DATA) rfc86.0.txt $(DESTDIR)$(DOCDIR)/spec/ +spec_DATA = draft-morgan-pam-current.txt rfc86.0.txt diff --git a/doc/specs/parse.lex b/doc/specs/parse.lex deleted file mode 100644 index 1d5c898e..00000000 --- a/doc/specs/parse.lex +++ /dev/null @@ -1,11 +0,0 @@ -%% - -\#[\$]+[a-zA-Z]*(\=[0-9]+)? return NEW_COUNTER; -\#\{[a-zA-Z][a-zA-Z0-9\_]*\} return LABEL; -\# return NO_INDENT; -\#\# return RIGHT; -\\\# return HASH; -[^\n] return CHAR; -[\n] return NEWLINE; - -%% diff --git a/doc/specs/parse.y b/doc/specs/parse.y deleted file mode 100644 index 9d0e2534..00000000 --- a/doc/specs/parse.y +++ /dev/null @@ -1,294 +0,0 @@ - -%{ -#include -#include -#include - -#define MAXLINE 1000 -#define INDENT_STRING " " -#define PAPER_WIDTH 74 - - int indent=0; - int line=1; - char *last_label=NULL; - - extern void yyerror(const char *x); - extern char *get_label(const char *label); - extern void set_label(const char *label, const char *target); - char *new_counter(const char *key); - -#include "lex.yy.c" - -%} - -%union { - int def; - char *string; -} - -%token NEW_COUNTER LABEL HASH CHAR NEWLINE NO_INDENT RIGHT -%type stuff text - -%start doc - -%% - -doc: -| doc NEWLINE { - printf("\n"); - ++line; -} -| doc stuff NEWLINE { - if (strlen($2) > (PAPER_WIDTH-(indent ? strlen(INDENT_STRING):0))) { - yyerror("line too long"); - } - printf("%s%s\n", indent ? INDENT_STRING:"", $2); - free($2); - indent = 1; - ++line; -} -| doc stuff RIGHT stuff NEWLINE { - char fixed[PAPER_WIDTH+1]; - int len; - - len = PAPER_WIDTH-(strlen($2)+strlen($4)); - - if (len >= 0) { - memset(fixed, ' ', len); - fixed[len] = '\0'; - } else { - yyerror("line too wide"); - fixed[0] = '\0'; - } - printf("%s%s%s\n", $2, fixed, $4); - free($2); - free($4); - indent = 1; - ++line; -} -| doc stuff RIGHT stuff RIGHT stuff NEWLINE { - char fixed[PAPER_WIDTH+1]; - int len, l; - - len = PAPER_WIDTH-(strlen($2)+strlen($4)); - - if (len < 0) { - len = 0; - yyerror("line too wide"); - } - - l = len/2; - memset(fixed, ' ', l); - fixed[l] = '\0'; - printf("%s%s%s", $2, fixed, $4); - free($2); - free($4); - - l = (len+1)/2; - memset(fixed, ' ', l); - fixed[l] = '\0'; - printf("%s%s\n", fixed, $6); - free($6); - - indent = 1; - ++line; -} -| doc stuff RIGHT stuff RIGHT stuff NEWLINE { - char fixed[PAPER_WIDTH+1]; - int len, l; - - len = PAPER_WIDTH-(strlen($2)+strlen($4)); - - if (len < 0) { - len = 0; - yyerror("line too wide"); - } - - l = len/2; - memset(fixed, ' ', l); - fixed[l] = '\0'; - printf("%s%s%s", $2, fixed, $4); - free($2); - free($4); - - l = (len+1)/2; - memset(fixed, ' ', l); - fixed[l] = '\0'; - printf("%s%s\n", fixed, $6); - free($6); - - indent = 1; - ++line; -} -; - -stuff: { - $$ = strdup(""); -} -| stuff text { - $$ = malloc(strlen($1)+strlen($2)+1); - sprintf($$,"%s%s", $1, $2); - free($1); - free($2); -} -; - -text: CHAR { - $$ = strdup(yytext); -} -| text CHAR { - $$ = malloc(strlen($1)+2); - sprintf($$,"%s%s", $1, yytext); - free($1); -} -| NO_INDENT { - $$ = strdup(""); - indent = 0; -} -| HASH { - $$ = strdup("#"); -} -| LABEL { - if (($$ = get_label(yytext)) == NULL) { - set_label(yytext, last_label); - $$ = strdup(""); - } -} -| NEW_COUNTER { - $$ = new_counter(yytext); -} -; - -%% - -typedef struct node_s { - struct node_s *left, *right; - const char *key; - char *value; -} *node_t; - -node_t label_root = NULL; -node_t counter_root = NULL; - -static const char *find_key(node_t root, const char *key) -{ - while (root) { - int cmp = strcmp(key, root->key); - - if (cmp > 0) { - root = root->right; - } else if (cmp) { - root = root->left; - } else { - return root->value; - } - } - return NULL; -} - -static node_t set_key(node_t root, const char *key, const char *value) -{ - if (root) { - int cmp = strcmp(key, root->key); - if (cmp > 0) { - root->right = set_key(root->right, key, value); - } else if (cmp) { - root->left = set_key(root->left, key, value); - } else { - free(root->value); - root->value = strdup(value); - } - } else { - root = malloc(sizeof(struct node_s)); - root->right = root->left = NULL; - root->key = strdup(key); - root->value = strdup(value); - } - return root; -} - -void yyerror(const char *x) -{ - fprintf(stderr, "line %d: %s\n", line, x); -} - -char *get_label(const char *label) -{ - const char *found = find_key(label_root, label); - - if (found) { - return strdup(found); - } - return NULL; -} - -void set_label(const char *label, const char *target) -{ - if (target == NULL) { - yyerror("no hanging value for label"); - target = ""; - } - label_root = set_key(label_root, label, target); -} - -char *new_counter(const char *key) -{ - int i=0, j, ndollars = 0; - const char *old; - char *new; - - if (key[i++] != '#') { - yyerror("bad index"); - return strdup(""); - } - - while (key[i] == '$') { - ++ndollars; - ++i; - } - - key += i; - old = find_key(counter_root, key); - new = malloc(20*ndollars); - - if (old) { - for (j=0; ndollars > 1 && old[j]; ) { - if (old[j++] == '.' && --ndollars <= 0) { - break; - } - } - if (j) { - strncpy(new, old, j); - } - if (old[j]) { - i = atoi(old+j); - } else { - new[j++] = '.'; - i = 0; - } - } else { - j=0; - while (--ndollars > 0) { - new[j++] = '0'; - new[j++] = '.'; - } - i = 0; - } - new[j] = '\0'; - sprintf(new+j, "%d", ++i); - - counter_root = set_key(counter_root, key, new); - - if (last_label) { - free(last_label); - } - last_label = strdup(new); - - return new; -} - -int -main(void) -{ - return yyparse(); -} diff --git a/doc/specs/parse_l.l b/doc/specs/parse_l.l new file mode 100644 index 00000000..7cab424c --- /dev/null +++ b/doc/specs/parse_l.l @@ -0,0 +1,21 @@ +%{ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "parse_y.h" +%} + +%% + +\#[\$]+[a-zA-Z]*(\=[0-9]+)? return NEW_COUNTER; +\#\{[a-zA-Z][a-zA-Z0-9\_]*\} return LABEL; +\# return NO_INDENT; +\#\# return RIGHT; +\\\# return HASH; +[^\n] return CHAR; +[\n] return NEWLINE; + +%% diff --git a/doc/specs/parse_y.y b/doc/specs/parse_y.y new file mode 100644 index 00000000..9ea51654 --- /dev/null +++ b/doc/specs/parse_y.y @@ -0,0 +1,297 @@ + +%{ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#define MAXLINE 1000 +#define INDENT_STRING " " +#define PAPER_WIDTH 74 + + int indent=0; + int line=1; + char *last_label=NULL; + + extern int yylex(void); + extern char *yytext; + extern void yyerror(const char *x); + extern char *get_label(const char *label); + extern void set_label(const char *label, const char *target); + char *new_counter(const char *key); +%} + +%union { + int def; + char *string; +} + +%token NEW_COUNTER LABEL HASH CHAR NEWLINE NO_INDENT RIGHT +%type stuff text + +%start doc + +%% + +doc: +| doc NEWLINE { + printf("\n"); + ++line; +} +| doc stuff NEWLINE { + if (strlen($2) > (PAPER_WIDTH-(indent ? strlen(INDENT_STRING):0))) { + yyerror("line too long"); + } + printf("%s%s\n", indent ? INDENT_STRING:"", $2); + free($2); + indent = 1; + ++line; +} +| doc stuff RIGHT stuff NEWLINE { + char fixed[PAPER_WIDTH+1]; + int len; + + len = PAPER_WIDTH-(strlen($2)+strlen($4)); + + if (len >= 0) { + memset(fixed, ' ', len); + fixed[len] = '\0'; + } else { + yyerror("line too wide"); + fixed[0] = '\0'; + } + printf("%s%s%s\n", $2, fixed, $4); + free($2); + free($4); + indent = 1; + ++line; +} +| doc stuff RIGHT stuff RIGHT stuff NEWLINE { + char fixed[PAPER_WIDTH+1]; + int len, l; + + len = PAPER_WIDTH-(strlen($2)+strlen($4)); + + if (len < 0) { + len = 0; + yyerror("line too wide"); + } + + l = len/2; + memset(fixed, ' ', l); + fixed[l] = '\0'; + printf("%s%s%s", $2, fixed, $4); + free($2); + free($4); + + l = (len+1)/2; + memset(fixed, ' ', l); + fixed[l] = '\0'; + printf("%s%s\n", fixed, $6); + free($6); + + indent = 1; + ++line; +} +| doc stuff RIGHT stuff RIGHT stuff NEWLINE { + char fixed[PAPER_WIDTH+1]; + int len, l; + + len = PAPER_WIDTH-(strlen($2)+strlen($4)); + + if (len < 0) { + len = 0; + yyerror("line too wide"); + } + + l = len/2; + memset(fixed, ' ', l); + fixed[l] = '\0'; + printf("%s%s%s", $2, fixed, $4); + free($2); + free($4); + + l = (len+1)/2; + memset(fixed, ' ', l); + fixed[l] = '\0'; + printf("%s%s\n", fixed, $6); + free($6); + + indent = 1; + ++line; +} +; + +stuff: { + $$ = strdup(""); +} +| stuff text { + $$ = malloc(strlen($1)+strlen($2)+1); + sprintf($$,"%s%s", $1, $2); + free($1); + free($2); +} +; + +text: CHAR { + $$ = strdup(yytext); +} +| text CHAR { + $$ = malloc(strlen($1)+2); + sprintf($$,"%s%s", $1, yytext); + free($1); +} +| NO_INDENT { + $$ = strdup(""); + indent = 0; +} +| HASH { + $$ = strdup("#"); +} +| LABEL { + if (($$ = get_label(yytext)) == NULL) { + set_label(yytext, last_label); + $$ = strdup(""); + } +} +| NEW_COUNTER { + $$ = new_counter(yytext); +} +; + +%% + +typedef struct node_s { + struct node_s *left, *right; + const char *key; + char *value; +} *node_t; + +node_t label_root = NULL; +node_t counter_root = NULL; + +static const char *find_key(node_t root, const char *key) +{ + while (root) { + int cmp = strcmp(key, root->key); + + if (cmp > 0) { + root = root->right; + } else if (cmp) { + root = root->left; + } else { + return root->value; + } + } + return NULL; +} + +static node_t set_key(node_t root, const char *key, const char *value) +{ + if (root) { + int cmp = strcmp(key, root->key); + if (cmp > 0) { + root->right = set_key(root->right, key, value); + } else if (cmp) { + root->left = set_key(root->left, key, value); + } else { + free(root->value); + root->value = strdup(value); + } + } else { + root = malloc(sizeof(struct node_s)); + root->right = root->left = NULL; + root->key = strdup(key); + root->value = strdup(value); + } + return root; +} + +void yyerror(const char *x) +{ + fprintf(stderr, "line %d: %s\n", line, x); +} + +char *get_label(const char *label) +{ + const char *found = find_key(label_root, label); + + if (found) { + return strdup(found); + } + return NULL; +} + +void set_label(const char *label, const char *target) +{ + if (target == NULL) { + yyerror("no hanging value for label"); + target = ""; + } + label_root = set_key(label_root, label, target); +} + +char *new_counter(const char *key) +{ + int i=0, j, ndollars = 0; + const char *old; + char *new; + + if (key[i++] != '#') { + yyerror("bad index"); + return strdup(""); + } + + while (key[i] == '$') { + ++ndollars; + ++i; + } + + key += i; + old = find_key(counter_root, key); + new = malloc(20*ndollars); + + if (old) { + for (j=0; ndollars > 1 && old[j]; ) { + if (old[j++] == '.' && --ndollars <= 0) { + break; + } + } + if (j) { + strncpy(new, old, j); + } + if (old[j]) { + i = atoi(old+j); + } else { + new[j++] = '.'; + i = 0; + } + } else { + j=0; + while (--ndollars > 0) { + new[j++] = '0'; + new[j++] = '.'; + } + i = 0; + } + new[j] = '\0'; + sprintf(new+j, "%d", ++i); + + counter_root = set_key(counter_root, key, new); + + if (last_label) { + free(last_label); + } + last_label = strdup(new); + + return new; +} + +int +main(void) +{ + return yyparse(); +} -- cgit v1.2.3