/* $Source: /v/ossp/cvs/ossp-pkg/petidomo/librfc822/address.y,v $ $Revision: 1.5 $ Copyright (C) 2000 by CyberSolutions GmbH, Germany. This file is part of OpenPetidomo. OpenPetidomo is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. OpenPetidomo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ %{ /* Definitions we need in the parser. */ #define YYSTYPE char * #include #include #ifdef DEBUG_DMALLOC # include #endif #include "../libmpools/mpools.h" #define yytext rfc822_text #define yyley rfc822_lex /* Variables in our lexer. */ extern char * rfc822_address_buffer; extern int rfc822_address_buffer_pos; extern char * yytext; /* Our static/global variables. */ static int no_memory_flag; static char * poolname, * result_hostpart, * result_localpart, * result_address; /* Prototypes for internal functions. */ static int yyparse(void); static int yyerror(char *); static char * pool_strdup(char *); static char * pool_strjoin(char *, char *); int yylex(void); /* These macros call the routines we define later in a fail safe way. */ #define str_dup(target,a) { \ target = (YYSTYPE) pool_strdup((char *) a); \ if (target == NULL) { \ no_memory_flag++; \ YYABORT; \ } \ } #define str_join(target,a,b) { \ target = (YYSTYPE) pool_strjoin((char *) a, (char *) b); \ if (target == NULL) { \ no_memory_flag++; \ YYABORT; \ } \ } %} %token TOK_ATOM TOK_ILLEGAL %left ':' %left '@' %% address: local { result_localpart = (char *)$1; str_dup($$,$1); result_address = (char *)$$; } | local at domain { result_localpart = (char *)$1; result_hostpart = (char *)$3; str_join($$,$1,$2); str_join($$,$$,$3); result_address = (char *)$$; } | at domain colon sourceroutings local { result_hostpart = (char *)$2; str_join($$,$4,$5); result_localpart = (char *)$$; str_join($$,$3,$$); str_join($$,$2,$$); str_join($$,$1,$$); result_address = (char *)$$; } | at domain colon sourceroutings local at domain { result_hostpart = (char *)$2; str_join($$,$4,$5); str_join($$,$$,$6); str_join($$,$$,$7); result_localpart = (char *)$$; str_join($$,$3,$$); str_join($$,$2,$$); str_join($$,$1,$$); result_address = (char *)$$; } ; sourceroutings: /* empty */ { $$ = (YYSTYPE) NULL; } | at domain colon sourceroutings { str_join($$,$1,$2); str_join($$,$$,$3); str_join($$,$$,$4); } ; local: atom { $$ = $1; } | atom local { str_join($$,$1,$2); } | dot { $$ = $1; } | dot local { str_join($$,$1,$2); } ; domain: atom { $$ = $1; } | atom dot domain { str_join($$,$2,$3); str_join($$,$1,$$); } ; atom: TOK_ATOM { str_dup($$,yytext); }; dot: '.' { $$ = (YYSTYPE) "."; }; at: '@' { $$ = (YYSTYPE) "@"; }; colon: ':' { $$ = (YYSTYPE) ":"; }; %% /***** internal routines *****/ static int yyerror(char * string) { return 0; } /* Do the same as strdup(3) but use the memory pool to allocate the memory, so that we don't lose memory. */ static char * pool_strdup(char * string) { char * p; if (string == NULL) return NULL; p = mp_malloc(poolname, strlen(string) + 1); if (p == NULL) return NULL; strcpy(p, string); return p; } /* Allocate a new buffer (using the memory pool) and join the strings 'a' and 'b' into it. */ static char * pool_strjoin(char * a, char * b) { char * p; int length = 0; if (a != NULL) length += strlen(a); if (b != NULL) length += strlen(b); if (length == 0) return NULL; p = mp_malloc(poolname, length + 2); if (p == NULL) return NULL; else *p = '\0'; if (a) strcpy(p, a); if (b) strcpy(&(p[strlen(p)]), b); return p; } /****** public routines ******/ #include "parse_address.c"