/* lex.l								   */
/* Copyright (C) 1989, 1991, Craig E. Kolb				   */
/* All rights reserved.							   */
/*									   */
/* This software may be freely copied, modified, and redistributed,	   */
/* provided that this copyright notice is preserved on all copies.	   */
/*									   */
/* You may not distribute this software, in whole or in part, as part of   */
/* any commercial product without the express consent of the authors.	   */
/* 									   */
/* There is no warranty or other guarantee of fitness of this software	   */
/* for any purpose.  It is provided solely "as is".			   */
/* $Id$ */
%{
#include <stdio.h>
#ifdef SYSV
#include <string.h>
#else
#include <strings.h>
#endif
#include <stdlib.h>
#include "libcommon/common.h"
#include "y.tab.h"

%}
alpha	[a-zA-Z]
special	[\.\_-]
digit	[0-9]
exp	[Ee][-+]?{digit}+
string	({alpha}|"/")({alpha}|{digit}|{special}|"/")*
%p 3000
%%
[\t\n]			{WriteVerbatim(yytext);};
" "			{};
^#			{handlehash();}
"/*"			{skipcomments();}
adaptive		{return(tADAPTIVE);}
aperture		{return(tAPERTURE);}
background		{return(tBACKGROUND);}
blotch			{return(tBLOTCH);}
box			{return(tBOX);}
bump			{return(tBUMP);}
checker			{return(tCHECKER);}
cone			{return(tCONE);}
contrast		{return(tCONTRAST);}
cutoff			{return(tCUTOFF);}
cylinder		{return(tCYL);}
defend			{return(tENDDEF);}
define			{return(tSTARTDEF);}
directional		{return(tDIRECTIONAL);}
endfile			{return(tENDFILE);}
extended		{return(tEXTENDED);}
eyep			{return(tEYEP);}
fbm			{return(tFBM);}
fbmbump			{return(tFBMBUMP);}
focaldist		{return(tFOCALDIST);}
fog			{return(tFOG);}
fov			{return(tFOV);}
gloss			{return(tGLOSS);}
grid			{return(tGRID);}
heightfield		{return(tHEIGHTFIELD);}
jittered		{return(tJITTERED);}
light			{return(tLIGHT);}
list			{return(tLIST);}
lookp			{return(tLOOKP);}
marble			{return(tMARBLE);}
maxdepth		{return(tMAXDEPTH);}
mist			{return(tMIST);}
object			{return(tOBJECT);}
outfile			{return(tOUTFILE);}
plane			{return(tPLANE);}
point			{return(tPOINT);}
poly			{return(tPOLY);}
resolution		{return(tRESOLUTION);}
rotate			{return(tROTATE);}
samples			{return(tSAMPLES);}
scale			{return(tSCALE);}
screen			{return(tSCREEN);}
sphere			{return(tSPHERE);}
superq			{return(tSUPERQ);}
surface			{return(tSURFACE);}
texture			{return(tTEXTURE);}
transform		{return(tTRANSFORM);}
translate		{return(tTRANSLATE);}
triangle		{return(tTRIANGLE);}
up			{return(tUP);}
wood			{return(tWOOD);}
{string}		{yylval.c = strsave(yytext);
				return(tSTRING);}
[+-]?{digit}+		{yylval.i = atoi(yytext);
				return(tINT);}

[+-]?{digit}+"."{digit}*({exp})? |
[+-]?{digit}*"."{digit}+({exp})? |
[+-]?{digit}+{exp}		{yylval.d = atof(yytext); return(tFLOAT);}

.			{return yytext[0];}

%%
yywrap() {return(1);}
/*
 * Skip over comments.
 */
skipcomments()
{
	char c;

	WriteVerbatim("/*");
	while (1) {
		while ((c = input()) != '*')
			WriteChar(c);
		WriteChar(c);
		if ((c = input()) == '/') {
			WriteChar(c);
			return;
		}
		unput(c);
	}
}
/*
 * Deal with ccp-produced lines of the form:
 * # n "filename"
 * and
 * # n
 * Where filename is the name of the file being processed, and n is
 * the current line number in that file.
 */
handlehash()
{
	char buf[BUFSIZ];
	int i;
	extern int yylineno;
	extern char yyfilename[];

	/*
	 * Read the entire line into buf.
	 */
	for (i = 0; (buf[i] = input()) != '\n'; i++)
			;
	unput(buf[i]);		/* To make sure consecutive # lines work. */
	buf[i] = (char)NULL;	/* Replace newline with NULL. */

	/*
	 * Check to see if it's #include or
	 * #define.
	 * If so just spit out the line.
	 */
	if (strncmp("include", buf, 7) == 0 || strncmp("define", buf, 6) == 0) {
		WriteVerbatim("#");
		WriteVerbatim(buf);
		return;
	}
	/*
	 * Complain if the line was not of the form #n "filename"
	 */
	if ((i = sscanf(buf, "%d \"%[^\"]s\"", &yylineno, yyfilename)) == 0) {
		yyerror("Unknown '#' control.");
		exit(1);
	}
	if (i == 1) {
#ifdef SYSV
		if (strchr(buf, '"') != (char *)0) {
#else
		if (index(buf, '"') != (char *)0) {
#endif
			/*
			 * Filename was "", which means stdin.
			 */
			strcpy(yyfilename, "stdin");
		}
	}
}
