/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
/*
* University Copyright- Copyright (c) 1982, 1986, 1988
* The Regents of the University of California
* All Rights Reserved
*
* University Acknowledgment- Portions of this document are derived from
* software developed by the University of California, Berkeley, and its
* contributors.
*/
/*
* COPYRIGHT NOTICE
*
* This software is copyright(C) 1982 by Pavel Curtis
*
* Permission is granted to reproduce and distribute
* this file by any means so long as no fee is charged
* above a nominal handling fee and so long as this
* notice is always included in the copies.
*
* Other rights are reserved except as explicitly granted
* by written permission of the author.
* Pavel Curtis
* Computer Science Dept.
* 405 Upson Hall
* Cornell University
* Ithaca, NY 14853
*
* Ph- (607) 256-4934
*
* Pavel.Cornell@Udel-Relay(ARPAnet)
* decvax!cornell!pavel(UUCPnet)
*/
/*
* comp_scan.c --- Lexical scanner for terminfo compiler.
*
* $Log: RCS/comp_scan.v $
* Revision 2.1 82/10/25 14:45:55 pavel
* Added Copyright Notice
*
* Revision 2.0 82/10/24 15:17:12 pavel
* Beta-one Test Release
*
* Revision 1.3 82/08/23 22:30:03 pavel
* The REAL Alpha-one Release Version
*
* Revision 1.2 82/08/19 19:10:06 pavel
* Alpha Test Release One
*
* Revision 1.1 82/08/12 18:37:46 pavel
* Initial revision
*
*
*/
#include <stdio.h>
#include <ctype.h>
#include "compiler.h"
static void backspace(void);
void reset_input(void);
void panic_mode(int);
/*
* int
* get_token()
*
* Scans the input for the next token, storing the specifics in the
* global structure 'curr_token' and returning one of the following:
*
* NAMES A line beginning in column 1. 'name'
* will be set to point to everything up to
* but not including the first comma on the line.
* BOOLEAN An entry consisting of a name followed by
* a comma. 'name' will be set to point to the
* name of the capability.
* NUMBER An entry of the form
* name#digits,
* 'name' will be set to point to the capability
* name and 'valnumber' to the number given.
* STRING An entry of the form
* name=characters,
* 'name' is set to the capability name and
* 'valstring' to the string of characters, with
* input translations done.
* CANCEL An entry of the form
* name@,
* 'name' is set to the capability name and
* 'valnumber' to -1.
* EOF The end of the file has been reached.
*
*/
int
{
long number;
register int ch;
register char *ptr;
else {
if (ch == '.') {
}
panic_mode(',');
}
if (first_column) {
err_abort("Premature EOF");
else if (ch == '\n') {
warning("Newline in middle of terminal name");
panic_mode(',');
}
*ptr = '\0';
} else {
}
*ptr++ = '\0';
switch (ch) {
case ',':
break;
case '@':
if (next_char() != ',')
warning("Missing comma");
break;
case '#':
number = 0;
warning("Missing numeric value");
backspace();
number *= 16;
else
}
} else {
backspace();
ch <= '7')
}
} else {
backspace();
}
if (ch != ',')
warning("Missing comma");
break;
case '=':
warning("Missing comma");
warning("NULL string value");
break;
default:
}
} /* end else (first_column == FALSE) */
} /* end else (ch != EOF) */
if (debug_level >= 8) {
switch (type) {
case BOOLEAN:
break;
case NUMBER:
break;
case STRING:
break;
case CANCEL:
break;
case NAMES:
break;
case EOF:
break;
default:
warning("Bad token type");
}
}
return (type);
}
/*
* int
* next_char()
*
* Returns the next character in the input stream. Comments and leading
* white space are stripped. The global state variable 'firstcolumn' is
* set TRUE if the character returned is from the first column of the
* inputline. The global variable curr_line is incremented for each new.
* line. The global variable curr_file_pos is set to the file offset
* of the beginning of each line.
*
*/
int
{
char *rtn_value;
long ftell();
char *p;
do {
return (EOF);
curr_line++;
p = &line[0];
while (*p && iswhite(*p)) {
p++;
}
} while (*p == '#');
curr_column = 0;
curr_column++;
}
first_column = TRUE;
else
return (line[curr_column++]);
}
static void
backspace(void)
{
curr_column--;
if (curr_column < 0)
syserr_abort("Backspaced off beginning of line");
}
/*
* reset_input()
*
* Resets the input-reading routines. Used after a seek has been done.
*
*/
void
reset_input(void)
{
curr_column = -1;
}
/*
* int
* trans_string(ptr)
*
* Reads characters using next_char() until encountering a comma, a new
* entry, or end-of-file. The returned value is the character which
* caused reading to stop. The following translations are done on the
* input:
*
* ^X goes to ctrl-X (i.e. X & 037)
* {\E,\n,\r,\b,\t,\f} go to
* {ESCAPE,newline,carriage-return,backspace,tab,formfeed}
* {\^,\\} go to {carat,backslash}
* \ddd (for ddd = up to three octal digits) goes to
* the character ddd
*
* \e == \E
* \0 == \200
*
*/
int
{
register int count = 0;
int number;
register int i;
register int ch;
if (ch == '^') {
err_abort("Premature EOF");
}
if (ch == '@')
*(ptr++) = 0200;
else
} else if (ch == '\\') {
err_abort("Premature EOF");
for (i = 0; i < 2; i++) {
err_abort("Premature EOF");
backspace();
break;
}
}
if (number == 0)
number = 0200;
} else {
switch (ch) {
case 'E':
case 'l':
default:
warning("Illegal character in \\ sequence - '%c'",
ch);
} /* endswitch (ch) */
} /* endelse (ch < '0' || ch > '7') */
} /* end else if (ch == '\\') */
else {
}
count ++;
if (count > 1000)
warning("Very long string found. Missing comma?");
} /* end while */
warning("Premature EOF - missing comma?");
/* start of new description */
else if (first_column) {
backspace();
warning("Missing comma?");
/* pretend we did get a comma */
ch = ',';
}
*ptr = '\0';
if (count == 0)
return (NULL);
return (ch);
}
/*
* Panic mode error recovery - skip everything until a "ch" is found.
*/
void
{
int c;
for (;;) {
c = next_char();
if (c == ch)
return;
if (c == EOF)
return;
}
}