petidomo/librfc822/address.y

195 lines
5.7 KiB
Plaintext
Raw Normal View History

2000-12-16 12:38:21 +00:00
/*
2010-02-24 16:01:14 +00:00
* Copyright (c) 1995-2010 Peter Simons <simons@cryp.to>
* Copyright (c) 2000-2001 Cable & Wireless GmbH
* Copyright (c) 1999-2000 CyberSolutions GmbH
*
* This program 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 3 of the License, or (at your option) any later
* version.
*
* This program 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.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
2000-12-16 12:38:21 +00:00
%{
/* Definitions we need in the parser. */
2000-12-16 13:23:51 +00:00
#define YYSTYPE char *
#include <string.h>
2000-12-16 12:38:21 +00:00
#include <errno.h>
#ifdef DEBUG_DMALLOC
# include <dmalloc.h>
#endif
#include "../libmpools/mpools.h"
#define yytext rfc822_text
#define yylex rfc822_lex
2000-12-16 12:38:21 +00:00
/* 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;
2000-12-16 12:38:21 +00:00
/* 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 *)$$;
}
2000-12-16 12:38:21 +00:00
;
sourceroutings: /* empty */ { $$ = (YYSTYPE) NULL; }
| at domain colon sourceroutings {
str_join($$,$1,$2); str_join($$,$$,$3);
str_join($$,$$,$4);
}
2005-10-06 09:16:24 +00:00
;
2000-12-16 12:38:21 +00:00
local: atom { $$ = $1; }
| atom local { str_join($$,$1,$2); }
| dot { $$ = $1; }
| dot local { str_join($$,$1,$2); }
2000-12-16 12:38:21 +00:00
;
domain: atom { $$ = $1; }
| atom dot domain { str_join($$,$2,$3); str_join($$,$1,$$); }
2000-12-16 12:38:21 +00:00
;
atom: TOK_ATOM { str_dup($$,yytext); };
dot: '.' { $$ = (YYSTYPE) "."; };
at: '@' { $$ = (YYSTYPE) "@"; };
colon: ':' { $$ = (YYSTYPE) ":"; };
2000-12-16 12:38:21 +00:00
%%
/***** 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"