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/specs/parse_y.y | 297 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 doc/specs/parse_y.y (limited to 'doc/specs/parse_y.y') 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