/********************************************************** Small lexical analyser for inout. Also contains some bounds checking code. **********************************************************/ #include "qrt.h" extern int linenumber; char *malloc(); # ifdef AMIGA float atof(); # endif /********************************************************** Transforms all white spaces to blanks **********************************************************/ char towhite(c) char c; { if (c=='\n') linenumber++; if ((c=='\n') || (c=='=') || (c==',') || (c==';')) return(' '); return(c); } /********************************************************** Removes blank space before next token **********************************************************/ rmspace() { char c; while (((c=towhite(fgetc(stdin)))==' ') && !feof(stdin)); ungetc(c,stdin); } /********************************************************** Comment Killer - Added 16 Jun 88 to handle nested comments **********************************************************/ Comment_Killer() { char c; c='\0'; while (c != '}' && !feof(stdin)) { c = towhite(fgetc(stdin)); if (c == '{') Comment_Killer(); } } /********************************************************** Get next token from stdin **********************************************************/ GetToken(s) /* get a token from stdio */ char s[]; { /* */ char c; int x; x=0; s[0]=c='\0'; /* char count */ rmspace(); while (!feof(stdin) && x<(SLEN-1)) { s[x++]=c=toupper(towhite(fgetc(stdin))); if (c==' ') { s[--x]='\0'; break; } if (c=='(' || c==')') { if (x==1) { s[x]='\0'; break; } else { ungetc(c,stdin); s[--x]='\0'; break; } } if (c=='{') { x--; Comment_Killer(); rmspace(); } } } /********************************************************** Return value if color is in range 0<=cnum<=CNUM otherwise call error routine. **********************************************************/ float InRange(cnum) float cnum; { if (cnum>=0 && cnum<=1.00) return(cnum); Error(COLOR_VALUE_ERR,1501); } /********************************************************** Return value if value is >=0. otherwise call error routine. **********************************************************/ float IsPos(val) float val; { if (val >= 0) return(val); Error(LESS_THAN_ZERO,1502); } /********************************************************** Reads next number and converts to float from string **********************************************************/ float Get_Next_Num() { char str[SLEN]; float val; GetToken(str); val=atof(str); # ifdef IODEBUG printf("GETNEXTNUM: token=%s, val=%f\n",str,val); # endif return(val); } /********************************************************** Reads a name from input, and allocates some space for it. Returns a pointer to space. **********************************************************/ char *Get_Next_Name() { char str[SLEN], *s; GetToken(str); if ((s=malloc(strlen(str)))==NULL) Error(MALLOC_FAILURE,1503); strcpy(s,str); # ifdef IODEBUG printf("GETNEXTNAME: token=%s\n",str); # endif return(s); } /********************************************************** Reads a number 0..1 and returns a color value 0..CNUM; **********************************************************/ short Get_Color_Val() { return((short)(InRange(Get_Next_Num())*(float)CNUM)); } /********************************************************** Returns true if the next token is a left paren **********************************************************/ GetLeftParen() { char str[SLEN]; GetToken(str); if (strcmp(str,"(")!=0) Error(LPAREN_EXPECTED,1504); return; } /********************************************************** Returns true if the next token is a left paren **********************************************************/ int GetRightParen() { char str[SLEN]; GetToken(str); if (strcmp(str,")")!=0) return(FALSE); return(TRUE); } /********************************************************** Gets a VECTOR structure of the form (num1, num2, num3) **********************************************************/ GetVector(vector) VECT_PTR vector; { GetLeftParen(); vector->x = Get_Next_Num(); vector->y = Get_Next_Num(); vector->z = Get_Next_Num(); if(!GetRightParen()) Error(ILLEGAL_VECTOR,1505); } /********************************************************** Gets a SVECTOR structure of the form (num1, num2, num3) **********************************************************/ GetSVector(svector) SVECT_PTR svector; { GetLeftParen(); svector->r = Get_Color_Val(); svector->g = Get_Color_Val(); svector->b = Get_Color_Val(); if(!GetRightParen()) Error(ILLEGAL_SVECTOR,1506); }