%option noyywrap
%{
/* lexical analyser for gplink
Copyright (C) 2001, 2002, 2003, 2004, 2005
Craig Franklin
This file is part of gputils.
gputils 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.
gputils 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 gputils; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "stdhdr.h"
#include "libgputils.h"
#include "gplink.h"
#include "parse.h"
#include "scan.h"
#include "script.h"
/* YY_UNPUT not used, suppress the warning */
#define YY_NO_UNPUT
static void bad_char(char *character);
%}
SYM [a-z0-9_./\\:]*
%%
<<EOF>> {
if (close_file())
return LEXEOF;
}
libpath {
return LIBPATH;
}
lkrpath {
return LKRPATH;
}
[0-9]+ {
char *endptr;
yylval.i = strtol(yytext, &endptr, 10);
if ((endptr == NULL) || (*endptr != '\0')) {
bad_char(endptr);
}
return NUMBER;
}
0x[0-9a-f]+ {
char *endptr;
yylval.i = strtol(yytext + 2, &endptr, 16);
if ((endptr == NULL) || (*endptr != '\0')) {
bad_char(endptr);
}
return NUMBER;
}
{SYM} {
yylval.s = strdup(yytext);
return SYMBOL;
}
[ \t\r]*
[\n] {
return yytext[0];
}
\/\/.* { }
. {
yylval.i = yytext[0];
return yytext[0];
}
%%
static void bad_char(char *character)
{
char complaint[80];
snprintf(complaint, sizeof(complaint),
isprint(*character) ?
"Illegal character '%c' in numeric constant" :
"Illegal character %#x in numeric constant",
*character);
script_error(&complaint[0], NULL);
return;
}
void open_src(char *name, int isinclude)
{
extern FILE *yyin;
struct source_context *new = malloc(sizeof(*new));
if (state.src)
state.src->yybuf = YY_CURRENT_BUFFER;
new->f = fopen(name, "rt");
if(new->f)
new->name = strdup(name);
else if(isinclude && (strchr(name, PATH_CHAR) == 0)) {
/* If include file and no "/" in name, try searching include path */
char tryname[BUFSIZ];
int i;
for(i = 0; i < state.numpaths; i++) {
strncpy(tryname, state.paths[i], sizeof(tryname));
strncat(tryname, COPY_CHAR, sizeof(tryname));
strncat(tryname, name, sizeof(tryname));
new->f = fopen(tryname, "rt");
if(new->f) {
new->name = strdup(tryname);
break;
}
}
}
yyin = new->f;
if (new->f == NULL) {
if (state.src) {
gp_error("Unable to open file \"%s\" - %s",
name,
strerror(errno));
} else {
perror(name);
}
exit(1);
}
if (state.src) {
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
}
new->line_number = 1;
new->prev = state.src;
state.src = new;
}
int close_file()
{
struct source_context *old;
int terminate = 0;
old = state.src;
state.src = state.src->prev;
if (old->f != NULL) {
fclose(old->f);
free(old->name);
}
free(old);
if (state.src) {
/* Just an include file */
yy_delete_buffer(YY_CURRENT_BUFFER);
yy_switch_to_buffer(state.src->yybuf);
} else {
terminate = 1;
}
return terminate;
}
syntax highlighted by Code2HTML, v. 0.9.1