diff options
Diffstat (limited to 'usr/src/cmd/tic')
| -rw-r--r-- | usr/src/cmd/tic/Makefile | 67 | ||||
| -rw-r--r-- | usr/src/cmd/tic/req.flg | 33 | ||||
| -rw-r--r-- | usr/src/cmd/tic/tic_captab.c | 57 | ||||
| -rw-r--r-- | usr/src/cmd/tic/tic_error.c | 191 | ||||
| -rw-r--r-- | usr/src/cmd/tic/tic_hash.c | 215 | ||||
| -rw-r--r-- | usr/src/cmd/tic/tic_main.c | 276 | ||||
| -rw-r--r-- | usr/src/cmd/tic/tic_parse.c | 904 | ||||
| -rw-r--r-- | usr/src/cmd/tic/tic_read.c | 296 | ||||
| -rw-r--r-- | usr/src/cmd/tic/tic_scan.c | 510 |
9 files changed, 2549 insertions, 0 deletions
diff --git a/usr/src/cmd/tic/Makefile b/usr/src/cmd/tic/Makefile new file mode 100644 index 0000000000..0bc08a394f --- /dev/null +++ b/usr/src/cmd/tic/Makefile @@ -0,0 +1,67 @@ +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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 +# +# +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright (c) 1989,1996 by Sun Microsystems, Inc. +# All rights reserved. +# + +PROG= tic + +OBJS= \ + tic_captab.o \ + tic_error.o \ + tic_hash.o \ + tic_main.o \ + tic_parse.o \ + tic_read.o \ + tic_scan.o + +SRCS= $(OBJS:%.o=%.c) + +include ../Makefile.cmd + +LDLIBS += -lcurses +CPPFLAGS += -I../../lib/libcurses/screen + +.KEEP_STATE: + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) $(OBJS) -o $@ $(LDLIBS) + $(POST_PROCESS) + +$(POFILE): $(POFILES) + $(RM) $@ + cat $(POFILES) > $@ + + +install: all $(ROOTPROG) + +clean: + $(RM) $(OBJS) + +lint: lint_SRCS + +include ../Makefile.targ diff --git a/usr/src/cmd/tic/req.flg b/usr/src/cmd/tic/req.flg new file mode 100644 index 0000000000..0912843156 --- /dev/null +++ b/usr/src/cmd/tic/req.flg @@ -0,0 +1,33 @@ +#!/bin/sh +# +# 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 +# or http://www.opensolaris.org/os/licensing. +# 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 (c) 1999 by Sun Microsystems, Inc. +# All rights reserved. +# +#pragma ident "%Z%%M% %I% %E% SMI" + +echo_file usr/src/lib/libcurses/screen/curses_inc.h +echo_file usr/src/lib/libcurses/screen/compiler.h +echo_file usr/src/lib/libcurses/screen/curshdr.h +echo_file usr/src/lib/libcurses/screen/curses_wchar.h +echo_file usr/src/lib/libcurses/screen/object.h diff --git a/usr/src/cmd/tic/tic_captab.c b/usr/src/cmd/tic/tic_captab.c new file mode 100644 index 0000000000..6ad8e0d547 --- /dev/null +++ b/usr/src/cmd/tic/tic_captab.c @@ -0,0 +1,57 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 (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. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * comp_captab.c -- The names of the capabilities in a form ready for + * the making of a hash table for the compiler. + * + */ + + +#include "curses_inc.h" +#include "compiler.h" + + +struct name_table_entry cap_table[512]; + +struct name_table_entry *cap_hash_table[360]; + +int Hashtabsize = 360; +int Captabsize = 0; +int BoolCount = 0; +int NumCount = 0; +int StrCount = 0; diff --git a/usr/src/cmd/tic/tic_error.c b/usr/src/cmd/tic/tic_error.c new file mode 100644 index 0000000000..13bf098848 --- /dev/null +++ b/usr/src/cmd/tic/tic_error.c @@ -0,0 +1,191 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 2004 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. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * 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) + */ + +/* + * tic_error.c -- Error message routines + * + * $Log: RCS/tic_error.v $ + * Revision 2.1 82/10/25 14:45:31 pavel + * Added Copyright Notice + * + * Revision 2.0 82/10/24 15:16:32 pavel + * Beta-one Test Release + * + * Revision 1.3 82/08/23 22:29:31 pavel + * The REAL Alpha-one Release Version + * + * Revision 1.2 82/08/19 19:09:44 pavel + * Alpha Test Release One + * + * Revision 1.1 82/08/12 18:36:02 pavel + * Initial revision + * + * + */ + +#include <unistd.h> + +#include "compiler.h" +#ifdef __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +extern char *string_table; +extern short term_names; +extern char *progname; + +/* VARARGS1 */ +#ifdef __STDC__ +void +warning(char *fmt, ...) +#else +warning(va_alist) +va_dcl +#endif +{ +#ifndef __STDC__ + register char *fmt; +#endif + va_list args; + +#ifdef __STDC__ + va_start(args, fmt); +#else + va_start(args); + fmt = va_arg(args, char *); +#endif + fprintf(stderr, "%s: Warning: near line %d: ", progname, curr_line); + if (string_table != NULL) { + fprintf(stderr, "terminal '%s', ", string_table+term_names); + } + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); +} + + +/* VARARGS1 */ +#ifdef __STDC__ +err_abort(char *fmt, ...) +#else +err_abort(va_alist) +va_dcl +#endif +{ +#ifndef __STDC__ + register char *fmt; +#endif + va_list args; + +#ifdef __STDC__ + va_start(args, fmt); +#else + va_start(args); + fmt = va_arg(args, char *); +#endif + fprintf(stderr, "%s: Line %d: ", progname, curr_line); + if (string_table != NULL) { + fprintf(stderr, "terminal '%s', ", string_table+term_names); + } + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); + exit(1); +} + + +/* VARARGS1 */ +#ifdef __STDC__ +void +syserr_abort(char *fmt, ...) +#else +syserr_abort(va_alist) +va_dcl +#endif +{ +#ifndef __STDC__ + register char *fmt; +#endif + va_list args; + +#ifdef __STDC__ + va_start(args, fmt); +#else + va_start(args); + fmt = va_arg(args, char *); +#endif + fprintf(stderr, "PROGRAM ERROR: Line %d: ", curr_line); + if (string_table != NULL) { + fprintf(stderr, "terminal '%s', ", string_table+term_names); + } + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + fprintf(stderr, "*** Possibly corrupted terminfo file ***\n"); + va_end(args); + exit(1); +} diff --git a/usr/src/cmd/tic/tic_hash.c b/usr/src/cmd/tic/tic_hash.c new file mode 100644 index 0000000000..093d2a036b --- /dev/null +++ b/usr/src/cmd/tic/tic_hash.c @@ -0,0 +1,215 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 (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. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* +************************************************************************* +* 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_hash.c --- Routines to deal with the hashtable of capability + * names. + * + * $Log: RCS/comp_hash.v $ + * Revision 2.1 82/10/25 14:45:34 pavel + * Added Copyright Notice + * + * Revision 2.0 82/10/24 15:16:34 pavel + * Beta-one Test Release + * + * Revision 1.3 82/08/23 22:29:33 pavel + * The REAL Alpha-one Release Version + * + * Revision 1.2 82/08/19 19:09:46 pavel + * Alpha Test Release One + * + * Revision 1.1 82/08/12 18:36:23 pavel + * Initial revision + * + * + */ + +#include "curses_inc.h" +#include "compiler.h" + + + +/* + * make_hash_table() + * + * Takes the entries in cap_table[] and hashes them into cap_hash_table[] + * by name. There are Captabsize entries in cap_table[] and Hashtabsize + * slots in cap_hash_table[]. + * + */ + +void +make_hash_table() +{ + int i; + int hashvalue; + int collisions = 0; + + make_nte(); + for (i = 0; i < Captabsize; i++) { + hashvalue = hash_function(cap_table[i].nte_name); + DEBUG(9, "%d\n", hashvalue); + + if (cap_hash_table[hashvalue] != (struct name_table_entry *) 0) + collisions++; + + cap_table[i].nte_link = cap_hash_table[hashvalue]; + cap_hash_table[hashvalue] = &cap_table[i]; + } + + DEBUG(3, "Hash table complete\n%d collisions ", collisions); + DEBUG(3, "out of %d entries\n", Captabsize); + return; +} + +/* + * Make the name_table_entry from the capnames.c set of tables. + */ +make_nte() +{ + register int i, n; + extern char *boolnames[], *numnames[], *strnames[]; + + n = 0; + + for (i = 0; boolnames[i]; i++) { + cap_table[n].nte_link = NULL; + cap_table[n].nte_name = boolnames[i]; + cap_table[n].nte_type = BOOLEAN; + cap_table[n].nte_index = i; + n++; + } + BoolCount = i; + + for (i = 0; numnames[i]; i++) { + cap_table[n].nte_link = NULL; + cap_table[n].nte_name = numnames[i]; + cap_table[n].nte_type = NUMBER; + cap_table[n].nte_index = i; + n++; + } + NumCount = i; + + for (i = 0; strnames[i]; i++) { + cap_table[n].nte_link = NULL; + cap_table[n].nte_name = strnames[i]; + cap_table[n].nte_type = STRING; + cap_table[n].nte_index = i; + n++; + } + StrCount = i; + + Captabsize = n; +} + + +/* + * int hash_function(string) + * + * Computes the hashing function on the given string. + * + * The current hash function is the sum of each consectutive pair + * of characters, taken as two-byte integers, mod Hashtabsize. + * + */ + +static +int +hash_function(char *string) +{ + long sum = 0; + + while (*string) { + sum += *string + (*(string + 1) << 8); + string++; + } + + return (sum % Hashtabsize); +} + + + +/* + * struct name_table_entry * + * find_entry(string) + * + * Finds the entry for the given string in the hash table if present. + * Returns a pointer to the entry in the table or 0 if not found. + * + */ + +struct name_table_entry * +find_entry(char *string) +{ + int hashvalue; + struct name_table_entry *ptr; + + hashvalue = hash_function(string); + + ptr = cap_hash_table[hashvalue]; + + while (ptr != (struct name_table_entry *) 0 && + strcmp(ptr->nte_name, string) != 0) + ptr = ptr->nte_link; + + return (ptr); +} diff --git a/usr/src/cmd/tic/tic_main.c b/usr/src/cmd/tic/tic_main.c new file mode 100644 index 0000000000..c5ddc9b6e7 --- /dev/null +++ b/usr/src/cmd/tic/tic_main.c @@ -0,0 +1,276 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 (c) 1996, by Sun Microsystems, Inc. + * All Rights reserved. + */ +/* 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. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* +************************************************************************* +* 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 Halli * +* Cornell Universityi * +* Ithaca, NY 14853 * +* * +* Ph- (607) 256-4934 * +* * +* Pavel.Cornell@Udel-Relay(ARPAnet) * +* decvax!cornell!pavel(UUCPnet) * +*********************************************************************** */ + +/* + * comp_main.c --- Main program for terminfo compiler + * + * $Log: RCS/comp_main.v $ + * Revision 2.1 82/10/25 14:45:37 pavel + * Added Copyright Notice + * + * Revision 2.0 82/10/24 15:16:37 pavel + * Beta-one Test Release + * + * Revision 1.3 82/08/23 22:29:36 pavel + * The REAL Alpha-one Release Version + * + * Revision 1.2 82/08/19 19:09:49 pavel + * Alpha Test Release One + * + * Revision 1.1 82/08/12 18:36:55 pavel + * Initial revision + * + * + */ + + +#define EXTERN /* EXTERN=extern in other .c files */ +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <unistd.h> +#include "compiler.h" + +char *source_file = "./terminfo.src"; +char *destination = SRCDIR; +char *usage_string = "[-v[n]] [-c] source-file\n"; +char check_only = 0; +char *progname; + +extern void make_hash_table(); /* should be in a header file :-( */ +extern void compile(); /* should be in a header file :-( */ +extern void syserr_abort(); /* should be in a header file :-( */ +static void init(); + +main(int argc, char *argv[]) +{ + int i; + int argflag = FALSE; + + debug_level = 0; + progname = argv[0]; + + umask(022); + + for (i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + switch (argv[i][1]) { + case 'c': + check_only = 1; + break; + + case 'v': + debug_level = argv[i][2] ? atoi(&argv[i][2]) : 1; + break; + + default: + fprintf(stderr, + "%s: Unknown option. Usage is:\n\t%s: %s\n", + argv[0], progname, usage_string); + exit(1); + } + } else if (argflag) { + fprintf(stderr, "%s: Too many file names. Usage is:\n\t%s\n", + argv[0], usage_string); + exit(1); + } else { + argflag = TRUE; + source_file = argv[i]; + } + } + + init(); + make_hash_table(); + compile(); + + exit(0); + + return(0); +} + +/* + * init() + * + * Miscellaneous initializations + * + * Open source file as standard input + * Change directory to working terminfo directory. + * + */ + +static void +init() +{ + char *env = getenv("TERMINFO"); + + start_time = time((time_t *) 0); + + curr_line = 0; + + if (freopen(source_file, "r", stdin) == NULL) { + fprintf(stderr, "%s: Can't open %s\n", progname, source_file); + exit(1); + } + + if (env && *env) + destination = env; + + if (check_only) { + DEBUG(1, "Would be working in %s\n", destination); + } else { + DEBUG(1, "Working in %s\n", destination); + } + + if (access(destination, 7) < 0) { + fprintf(stderr, "%s: %s nonexistent or permission denied\n", + progname, destination); + exit(1); + } + + if (chdir(destination) < 0) { + fprintf(stderr, "%s: %s is not a directory\n", + progname, destination); + exit(1); + } + +} + +/* + * + * check_dir(dirletter) + * + * Check for access rights to the destination directory. + * Create any directories which don't exist. + * + */ + +void +check_dir(char dirletter) +{ + struct stat64 statbuf; + static char dirnames[128]; + static char dir[2] = " "; + + if (dirnames[dirletter] == 0) { + dir[0] = dirletter; + if (stat64(dir, &statbuf) < 0) { + if (mkdir(dir, 0755) < 0) + syserr_abort("mkdir %s returned bad status", dir); + dirnames[dirletter] = 1; + } else if (access(dir, 7) < 0) { + fprintf(stderr, "%s: %s/%s: Permission denied\n", + progname, destination, dir); + perror(dir); + exit(1); + } else if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { + fprintf(stderr, "%s: %s/%s: Not a directory\n", + progname, destination, dir); + perror(dir); + exit(1); + } + } + return; +} + +#include <curses.h> +#if (defined(SYSV) || defined(USG)) && !defined(SIGPOLL) +/* + * mkdir(dirname, mode) + * + * forks and execs the mkdir program to create the given directory + * + */ + +mkdir(dirname, mode) +#ifdef __STDC__ +const +#endif +char *dirname; +int mode; +{ + int fork_rtn; + int status; + + fork_rtn = fork(); + + switch (fork_rtn) { + case 0: /* Child */ + (void) execl("/bin/mkdir", "mkdir", dirname, (char *)0); + _exit(1); + + case -1: /* Error */ + fprintf(stderr, "%s: SYSTEM ERROR!! Fork failed!!!\n", + progname); + exit(1); + + default: + (void) wait(&status); + if ((status != 0) || (chmod(dirname, mode) == -1)) + return (-1); + return (0); + } +} +#endif diff --git a/usr/src/cmd/tic/tic_parse.c b/usr/src/cmd/tic/tic_parse.c new file mode 100644 index 0000000000..ebbc88dd50 --- /dev/null +++ b/usr/src/cmd/tic/tic_parse.c @@ -0,0 +1,904 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 (c) 1996-1999 by Sun Microsystems, Inc. + * All rights reserved. + */ +/* 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. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * ******************************************************************* + * 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_parse.c -- The high-level (ha!) parts of the compiler, + * that is, the routines which drive the scanner, + * etc. + * + * $Log: RCS/comp_parse.v $ + * Revision 2.1 82/10/25 14:45:43 pavel + * Added Copyright Notice + * + * Revision 2.0 82/10/24 15:16:39 pavel + * Beta-one Test Release + * + * Revision 1.3 82/08/23 22:29:39 pavel + * The REAL Alpha-one Release Version + * + * Revision 1.2 82/08/19 19:09:53 pavel + * Alpha Test Release One + * + * Revision 1.1 82/08/12 18:37:12 pavel + * Initial revision + * + * + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> +#include "curses_inc.h" +#include "compiler.h" +#include "object.h" + +extern char check_only; +extern char *progname; + +char *string_table; +int next_free; /* next free character in string_table */ +unsigned int table_size = 0; /* current string_table size */ +short term_names; /* string table offset - current terminal */ +int part2 = 0; /* set to allow old compiled defns to be used */ +int complete = 0; /* 1 if entry done with no forward uses */ + +struct use_item { + long offset; + struct use_item *fptr, *bptr; +}; + +struct use_header { + struct use_item *head, *tail; +}; + +struct use_header use_list = {NULL, NULL}; +int use_count = 0; + +/* + * The use_list is a doubly-linked list with NULLs terminating the lists: + * + * use_item use_item use_item + * --------- --------- --------- + * | | | | | | offset + * |-------| |-------| |-------| + * | ----+-->| ----+-->| NULL | fptr + * |-------| |-------| |-------| + * | NULL |<--+---- |<--+---- | bptr + * --------- --------- --------- + * ^ ^ + * | ------------------ | + * | | | | | + * +--+---- | ----+---+ + * | | | + * ------------------ + * head tail + * use_list + * + */ + + +/* + * compile() + * + * Main loop of the compiler. + * + * get_token() + * if curr_token != NAMES + * err_abort() + * while (not at end of file) + * do an entry + * + */ + +void +compile() +{ + char line[1024]; + int token_type; + struct use_item *ptr; + int old_use_count; + + token_type = get_token(); + + if (token_type != NAMES) + err_abort( +"File does not start with terminal names in column one"); + + while (token_type != EOF) + token_type = do_entry((struct use_item *)NULL); + + DEBUG(2, "Starting handling of forward USE's\n", ""); + + for (part2 = 0; part2 < 2; part2++) { + old_use_count = -1; + DEBUG(2, "\n\nPART %d\n\n", part2); + while (use_list.head != NULL && old_use_count != use_count) { + old_use_count = use_count; + for (ptr = use_list.tail; ptr != NULL; + ptr = ptr->bptr) { + fseek(stdin, ptr->offset, 0); + reset_input(); + if ((token_type = get_token()) != NAMES) + syserr_abort( +"Token after a seek not NAMES"); + (void) do_entry(ptr); + if (complete) + dequeue(ptr); + } + + for (ptr = use_list.head; ptr != NULL; + ptr = ptr->fptr) { + fseek(stdin, ptr->offset, 0); + reset_input(); + if ((token_type = get_token()) != NAMES) + syserr_abort( +"Token after a seek not NAMES"); + (void) do_entry(ptr); + if (complete) + dequeue(ptr); + } + + DEBUG(2, +"Finished a pass through enqueued forward USE's\n", ""); + } + } + + if (use_list.head != NULL && !check_only) { + fprintf(stderr, +"\nError in following up use-links. Either there is\n"); + fprintf(stderr, +"a loop in the links or they reference non-existant\n"); + fprintf(stderr, + "terminals. The following is a list of the entries\n"); + fprintf(stderr, "involved:\n\n"); + + for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) { + fseek(stdin, ptr->offset, 0); + fgets(line, 1024, stdin); + fprintf(stderr, "%s", line); + } + + exit(1); + } +} + +dump_list(str) +char *str; +{ + struct use_item *ptr; + char line[512]; + + fprintf(stderr, "dump_list %s\n", str); + for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) { + fseek(stdin, ptr->offset, 0); + fgets(line, 1024, stdin); + fprintf(stderr, "ptr %x off %d bptr %x fptr %x str %s", + ptr, ptr->offset, ptr->bptr, ptr->fptr, line); + } + fprintf(stderr, "\n"); +} + +/* + * int + * do_entry(item_ptr) + * + * Compile one entry. During the first pass, item_ptr is NULL. In pass + * two, item_ptr points to the current entry in the use_list. + * + * found-forward-use = FALSE + * re-initialise internal arrays + * save names in string_table + * get_token() + * while (not EOF and not NAMES) + * if found-forward-use + * do nothing + * else if 'use' + * if handle_use() < 0 + * found-forward-use = TRUE + * else + * check for existance and type-correctness + * enter cap into structure + * if STRING + * save string in string_table + * get_token() + * if ! found-forward-use + * dump compiled entry into filesystem + * + */ + +int +do_entry(item_ptr) +struct use_item *item_ptr; +{ + long entry_offset; + register int token_type; + register struct name_table_entry *entry_ptr; + int found_forward_use = FALSE; + short Booleans[MAXBOOLS], + Numbers[MAXNUMS], + Strings[MAXSTRINGS]; + + init_structure(Booleans, Numbers, Strings); + complete = 0; + term_names = save_str(curr_token.tk_name); + DEBUG(2, "Starting '%s'\n", curr_token.tk_name); + entry_offset = curr_file_pos; + + for (token_type = get_token(); + token_type != EOF && token_type != NAMES; + token_type = get_token()) { + if (found_forward_use) + /* do nothing */; + else if (strcmp(curr_token.tk_name, "use") == 0) { + if (handle_use(item_ptr, entry_offset, + Booleans, Numbers, Strings) < 0) + found_forward_use = TRUE; + } else { + entry_ptr = find_entry(curr_token.tk_name); + + if (entry_ptr == NOTFOUND) { + warning("Unknown Capability - '%s'", + curr_token.tk_name); + continue; + } + + + if (token_type != CANCEL && + entry_ptr->nte_type != token_type) + warning("Wrong type used for capability '%s'", + curr_token.tk_name); + switch (token_type) { + case CANCEL: + switch (entry_ptr->nte_type) { + case BOOLEAN: + Booleans[entry_ptr->nte_index] = -2; + break; + + case NUMBER: + Numbers[entry_ptr->nte_index] = -2; + break; + + case STRING: + Strings[entry_ptr->nte_index] = -2; + break; + } + break; + + case BOOLEAN: + if (Booleans[entry_ptr->nte_index] == 0) + Booleans[entry_ptr->nte_index] = TRUE; + break; + + case NUMBER: + if (Numbers[entry_ptr->nte_index] == -1) + Numbers[entry_ptr->nte_index] = + curr_token.tk_valnumber; + break; + + case STRING: + if (Strings[entry_ptr->nte_index] == -1) + Strings[entry_ptr->nte_index] = + save_str(curr_token.tk_valstring); + break; + + default: + warning("Unknown token type"); + panic_mode(','); + continue; + } + } /* end else cur_token.name != "use" */ + + } /* endwhile (not EOF and not NAMES) */ + + if (found_forward_use) + return (token_type); + + dump_structure(Booleans, Numbers, Strings); + + complete = 1; + return (token_type); +} + +/* + Change all cancellations to a non-entry. + For booleans, @ -> false + For nums, @ -> -1 + For strings, @ -> -1 + + This only has to be done for entries which + have to be compatible with the pre-Vr3 format. +*/ +#ifndef NOCANCELCOMPAT +elim_cancellations(Booleans, Numbers, Strings) +short Booleans[]; +short Numbers[]; +short Strings[]; +{ + register int i; + for (i = 0; i < BoolCount; i++) { + if (Booleans[i] == -2) + Booleans[i] = FALSE; + } + + for (i = 0; i < NumCount; i++) { + if (Numbers[i] == -2) + Numbers[i] = -1; + } + + for (i = 0; i < StrCount; i++) { + if (Strings[i] == -2) + Strings[i] = -1; + } +} +#endif /* NOCANCELCOMPAT */ +/* + Change the cancellation signal from the -2 used internally to + the 2 used within the binary. +*/ +change_cancellations(Booleans) +short Booleans[]; +{ + register int i; + for (i = 0; i < BoolCount; i++) { + if (Booleans[i] == -2) + Booleans[i] = 2; + } + +} + +/* + * enqueue(offset) + * + * Put a record of the given offset onto the use-list. + * + */ + +enqueue(offset) +long offset; +{ + struct use_item *item; + + item = (struct use_item *)malloc(sizeof (struct use_item)); + + if (item == NULL) + syserr_abort("Not enough memory for use_list element"); + + item->offset = offset; + + if (use_list.head != NULL) { + item->bptr = use_list.tail; + use_list.tail->fptr = item; + item->fptr = NULL; + use_list.tail = item; + } else { + use_list.tail = use_list.head = item; + item->fptr = item->bptr = NULL; + } + + use_count ++; +} + +/* + * dequeue(ptr) + * + * remove the pointed-to item from the use_list + * + */ + +dequeue(ptr) +struct use_item *ptr; +{ + if (ptr->fptr == NULL) + use_list.tail = ptr->bptr; + else + (ptr->fptr)->bptr = ptr->bptr; + + if (ptr->bptr == NULL) + use_list.head = ptr->fptr; + else + (ptr->bptr)->fptr = ptr->fptr; + + use_count --; +} + +/* + * invalid_term_name(name) + * + * Look for invalid characters in a term name. These include + * space, tab and '/'. + * + * Generate an error message if given name does not begin with a + * digit or letter, then exit. + * + * return TRUE if name is invalid. + * + */ + +static int invalid_term_name(name) +register char *name; +{ + int error = 0; + if (! isdigit(*name) && ! islower(*name) && ! isupper(*name)) + error++; + + for (; *name; name++) + if (isalnum(*name)) + continue; + else if (isspace(*name) || (*name == '/')) + return (1); + if (error) { + fprintf(stderr, "%s: Line %d: Illegal terminal name - '%s'\n", + progname, curr_line, name); + fprintf(stderr, + "Terminal names must start with a letter or digit\n"); + exit(1); + } + return (0); +} + +/* + * dump_structure() + * + * Save the compiled version of a description in the filesystem. + * + * make a copy of the name-list + * break it up into first-name and all-but-last-name + * if necessary + * clear CANCELS out of the structure + * creat(first-name) + * write object information to first-name + * close(first-name) + * for each valid name + * link to first-name + * + */ + +dump_structure(Booleans, Numbers, Strings) +short Booleans[]; +short Numbers[]; +short Strings[]; +{ + struct stat64 statbuf; + FILE *fp; + char name_list[1024]; + register char *first_name, *other_names, *cur_name; + char filename[128 + 2 + 1]; + char linkname[128 + 2 + 1]; + int len; + int alphastart = 0; + extern char *strchr(), *strrchr(); + + strcpy(name_list, term_names + string_table); + DEBUG(7, "Name list = '%s'\n", name_list); + + first_name = name_list; + /* Set othernames to 1 past first '|' in the list. */ + /* Null out that '|' in the process. */ + other_names = strchr(first_name, '|'); + if (other_names) + *other_names++ = '\0'; + + if (invalid_term_name(first_name)) + warning("'%s': bad first term name.", first_name); + + + DEBUG(7, "First name = '%s'\n", first_name); + DEBUG(7, "Other names = '%s'\n", other_names ? other_names : "NULL"); + + if ((len = strlen(first_name)) > 128) + warning("'%s': terminal name too long.", first_name); + else if (len == 1) + warning("'%s': terminal name too short.", first_name); + + check_dir(first_name[0]); + + sprintf(filename, "%c/%s", first_name[0], first_name); + + if (strlen(filename) > 16) + warning("'%s' filename too long, truncating to '%.16s'\n", + filename, filename); + if (stat64(filename, &statbuf) >= 0 && statbuf.st_mtime >= start_time) { + warning("'%s' defined in more than one entry.", first_name); + fprintf(stderr, "Entry being used is '%s'.\n", + (unsigned)term_names + string_table); + } + + if (!check_only) { + unlink(filename); + fp = fopen(filename, "w"); + if (fp == NULL) { + perror(filename); + syserr_abort("Can't open %s/%s\n", + destination, filename); + } + DEBUG(1, "Created %.16s\n", filename); + } else DEBUG(1, "Would have created %.16s\n", filename); + +#ifndef NOCANCELCOMPAT + /* if there is no '+' in the name, eliminate */ + /* cancellation markings. */ + if (strchr(first_name, '+') == 0) + elim_cancellations(Booleans, Numbers, Strings); + else +#endif /* NOCANCELCOMPAT */ + change_cancellations(Booleans); + + if (!check_only) { + if (write_object(fp, Booleans, Numbers, Strings) < 0) { + syserr_abort("Error in writing %s/%s", + destination, filename); + } + fclose(fp); + } + + alphastart = isalpha(first_name[0]); + + while (other_names) { + cur_name = other_names; + other_names = strchr(cur_name, '|'); + if (other_names) + *other_names++ = '\0'; + if (*cur_name == '\0') + continue; + + if ((len = strlen(cur_name)) > 128) { + warning("'%s': terminal name too long.", cur_name); + continue; + } else if (len == 1) { + warning("'%s': terminal name too short.", first_name); + continue; + } + + if (invalid_term_name(cur_name)) { + if (other_names) + warning("'%s': bad term name found in list.", + cur_name); + continue; + } + + check_dir(cur_name[0]); + + sprintf(linkname, "%c/%s", cur_name[0], cur_name); + + if (strlen(linkname) > 16) { + if (other_names) { + warning( +"'%s' linkname too long, truncating to '%.16s'\n", linkname, linkname); + } else { + continue; + } + } + alphastart |= isalpha(cur_name[0]); + + if (strcmp(first_name, cur_name) == 0) { + warning("Terminal name '%s' synonym for itself", + first_name); + } else { + if (!check_only) { + if (stat64(linkname, &statbuf) >= 0 && + statbuf.st_mtime >= start_time) { + warning( +"'%s' defined in more than one entry.", cur_name); + fprintf(stderr, + "Entry being used is '%s'.\n", + (unsigned)term_names + + string_table); + } + unlink(linkname); + if (link(filename, linkname) < 0) + syserr_abort("Can't link %s to %s", + filename, linkname); + DEBUG(1, "Linked %.16s\n", linkname); + } else DEBUG(1, "Would have linked %.16s\n", linkname); + } + } + + if (!alphastart) { + warning("At least one synonym should begin with a letter."); + } +} + +/* + * int + * write_object(fp, Booleans, Numbers, Strings) + * + * Write out the compiled entry to the given file. + * Return 0 if OK or -1 if not. + * + */ + +#define swap(x) (((x >> 8) & 0377) + 256 * (x & 0377)) + +#define might_swap(x) (must_swap() ? swap(x) : (x)) + + +int +write_object(fp, Booleans, Numbers, Strings) +FILE *fp; +short Booleans[]; +short Numbers[]; +short Strings[]; +{ + struct header header; + char *namelist; + short namelen; + char zero = '\0'; + register int i; + char cBooleans[MAXBOOLS]; + register int l_next_free; + + namelist = term_names + string_table; + namelen = strlen(namelist) + 1; + + l_next_free = next_free; + if (l_next_free % 256 == 255) + l_next_free++; + + if (must_swap()) { + header.magic = swap(MAGIC); + header.name_size = swap(namelen); + header.bool_count = swap(BoolCount); + header.num_count = swap(NumCount); + header.str_count = swap(StrCount); + header.str_size = swap(l_next_free); + } else { + header.magic = MAGIC; + header.name_size = namelen; + header.bool_count = BoolCount; + header.num_count = NumCount; + header.str_count = StrCount; + header.str_size = l_next_free; + } + + for (i = 0; i < BoolCount; i++) + cBooleans[i] = Booleans[i]; + + if (fwrite(&header, sizeof (header), 1, fp) != 1 || + fwrite(namelist, sizeof (char), namelen, fp) != namelen || + fwrite(cBooleans, sizeof (char), BoolCount, fp) != + BoolCount) + return (-1); + + if ((namelen+BoolCount) % 2 != 0 && + fwrite(&zero, sizeof (char), 1, fp) != 1) + return (-1); + + if (must_swap()) { + for (i = 0; i < NumCount; i++) + Numbers[i] = swap(Numbers[i]); + for (i = 0; i < StrCount; i++) + Strings[i] = swap(Strings[i]); + } + + if (fwrite((char *)Numbers, sizeof (short), NumCount, fp) != NumCount || + fwrite((char *)Strings, sizeof (short), StrCount, fp) + != StrCount || + fwrite(string_table, sizeof (char), l_next_free, fp) + != l_next_free) + return (-1); + + return (0); +} + +/* + * int + * save_str(string) + * + * copy string into next free part of string_table, doing a realloc() + * if necessary. return offset of beginning of string from start of + * string_table. + * + */ + +int +save_str(string) +char *string; +{ + int old_next_free; + + /* Do not let an offset be 255. It reads as -1 in Vr2 binaries. */ + if (next_free % 256 == 255) + next_free++; + + old_next_free = next_free; + + if (table_size == 0) { + if ((string_table = malloc(1024)) == NULL) + syserr_abort("Out of memory"); + table_size = 1024; + DEBUG(5, "Made initial string table allocation. Size is %u\n", + table_size); + } + + while (table_size <= next_free + strlen(string)) { + if ((string_table = realloc(string_table, table_size + 1024)) + == NULL) + syserr_abort("Out of memory"); + table_size += 1024; + DEBUG(5, "Extended string table. Size now %u\n", table_size); + } + + strcpy(&string_table[next_free], string); + DEBUG(7, "Saved string '%s' ", string); + DEBUG(7, "at location %d\n", next_free); + next_free += strlen(string) + 1; + + return (old_next_free); +} + +/* + * init_structure(Booleans, Numbers, Strings) + * + * Initialise the given arrays + * Reset the next_free counter to zero. + * + */ + +init_structure(Booleans, Numbers, Strings) +short Booleans[]; +short Numbers[], Strings[]; +{ + int i; + + for (i = 0; i < BoolCount; i++) + Booleans[i] = FALSE; + + for (i = 0; i < NumCount; i++) + Numbers[i] = -1; + + for (i = 0; i < StrCount; i++) + Strings[i] = -1; + + next_free = 0; +} + +/* + * int + * handle_use(item_ptr, entry_offset, Booleans, Numbers, Strings) + * + * Merge the compiled file whose name is in cur_token.valstring + * with the current entry. + * + * if it's a forward use-link + * if item_ptr == NULL + * queue it up for later handling + * else + * ignore it (we're already going through the queue) + * else it's a backward use-link + * read in the object file for that terminal + * merge contents with current structure + * + * Returned value is 0 if it was a backward link and we + * successfully read it in, -1 if a forward link. + */ + +int +handle_use(item_ptr, entry_offset, Booleans, Numbers, Strings) +long entry_offset; +struct use_item *item_ptr; +short Booleans[]; +short Numbers[]; +short Strings[]; +{ + struct _bool_struct use_bools; + struct _num_struct use_nums; + struct _str_struct use_strs; + struct stat64 statbuf; + char filename[50]; + int i; + char *UB = &use_bools._auto_left_margin; /* first bool */ + short *UN = &use_nums._columns; /* first num */ + char **US = &use_strs.strs._back_tab; /* first str */ + + if (invalid_term_name(curr_token.tk_valstring)) + warning("%s: bad term name", curr_token.tk_valstring); + + sprintf(filename, "%c/%s", curr_token.tk_valstring[0], + curr_token.tk_valstring); + + if (stat64(filename, &statbuf) < 0 || + part2 == 0 && statbuf.st_mtime < start_time) { + DEBUG(2, "Forward USE to %s", curr_token.tk_valstring); + + if (item_ptr == NULL) { + DEBUG(2, " (enqueued)\n", ""); + enqueue(entry_offset); + } else DEBUG(2, " (skipped)\n", ""); + + return (-1); + } else { + DEBUG(2, "Backward USE to %s\n", curr_token.tk_valstring); + if (read_entry(filename, &use_bools, &use_nums, &use_strs) < 0) + syserr_abort("Error in re-reading compiled file %s", + filename); + + for (i = 0; i < BoolCount; i++) { + if (Booleans[i] == FALSE) + if (UB[i] == TRUE) /* now true */ + Booleans[i] = TRUE; + else if (UB[i] > TRUE) /* cancelled */ + Booleans[i] = -2; + } + + for (i = 0; i < NumCount; i++) { + if (Numbers[i] == -1) + Numbers[i] = UN[i]; + } + + for (i = 0; i < StrCount; i++) { + if (Strings[i] == -1) + if (US[i] == (char *)-1) + Strings[i] = -2; + else if (US[i] != (char *)0) + Strings[i] = save_str(US[i]); + } + + } + return (0); +} diff --git a/usr/src/cmd/tic/tic_read.c b/usr/src/cmd/tic/tic_read.c new file mode 100644 index 0000000000..b6acd1d7ce --- /dev/null +++ b/usr/src/cmd/tic/tic_read.c @@ -0,0 +1,296 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 (c) 1996-1997 by Sun Microsystems, Inc. + * All rights reserved. + */ + +/* 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. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * ******************************************************************** + * 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) * + * ******************************************************************** + */ + +/* + * read_entry.c -- Routine for reading in a compiled terminfo file + * + * $Log: RCS/read_entry.v $ + * Revision 2.1 82/10/25 14:49:55 pavel + * Added Copyright Notice + * + * Revision 2.0 82/10/24 15:18:22 pavel + * Beta-one Test Release + * + * Revision 1.3 82/08/23 22:31:15 pavel + * The REAL Alpha-one Release Version + * + * Revision 1.2 82/08/19 19:11:49 pavel + * Alpha Test Release One + * + * Revision 1.1 82/08/12 22:25:13 pavel + * Initial revision + * + * + */ + + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include "curses_inc.h" +#include "object.h" + +#define OFFSET_BUFSIZE 100 + +#define swap(x) (((x >> 8) & 0377) + 256 * (x & 0377)) + +#define min(a, b) ((a) > (b) ? (b) : (a)) + +/* + * int + * read_entry(filename, ptr) + * + * Read the compiled terminfo entry in the given file into the + * structure pointed to by ptr, allocating space for the string + * table and placing its address in ptr->str_table. + * + */ + +static char TermNames[128]; /* Buffer for terminal names for first term */ +static char StringTable[2048]; /* String table for first terminal */ +static int beencalled = 0; /* read_entry has been called before */ + +int +read_entry(filename, bptr, nptr, sptr) +char *filename; +struct _bool_struct *bptr; +struct _num_struct *nptr; +struct _str_struct *sptr; +{ + int fd; + int numread; + int num_strings; + int cur_string; + int i; + struct header header; + unsigned char bytebuf[2]; + char ch; + char *UB; /* booleans */ + short *UN; /* numbers */ + char **US; /* strings */ + char *pst; /* pointer to string table */ + int swapping = must_swap(); + extern int BoolCount; + extern int NumCount; + extern int StrCount; + extern long lseek(); + unsigned char byte[OFFSET_BUFSIZE][2]; + short number[OFFSET_BUFSIZE]; + + fd = open(filename, 0); + + if (fd < 0) + return (-1); + + read(fd, &header, sizeof (header)); + + if (swapping) { + header.magic = swap(header.magic); + header.name_size = swap(header.name_size); + header.bool_count = swap(header.bool_count); + header.num_count = swap(header.num_count); + header.str_count = swap(header.str_count); + header.str_size = swap(header.str_size); + } + + if (header.magic != MAGIC) { + close(fd); + return (-1); + } + + read(fd, TermNames, min(127, header.name_size)); + TermNames[127] = '\0'; + if (header.name_size > 127) + lseek(fd, (long)(header.name_size - 127), 1); + + UB = &(bptr->_auto_left_margin); + UN = &(nptr->_columns); + US = &(sptr->strs._back_tab); + read(fd, UB, min(BoolCount, header.bool_count)); + if (header.bool_count > BoolCount) + lseek(fd, (long)(header.bool_count - BoolCount), 1); + else + for (i = header.bool_count; i < BoolCount; i++) + UB[i] = 0; + + if ((header.name_size + header.bool_count) % 2 != 0) + read(fd, &ch, 1); + + if (!swapping) + read(fd, (char *)UN, min(NumCount, header.num_count) * 2); + else { + for (i = 0; i < min(header.num_count, NumCount); i++) { + read(fd, (char *)bytebuf, 2); + if (bytebuf[1] == 0377) { + if (bytebuf[0] == 0376) /* -2 == cancelled */ + UN[i] = -2; + else if (bytebuf[0] == 0377) + /* -1 == not there */ + UN[i] = -1; + else + UN[i] = bytebuf[0] + 256 * bytebuf[1]; + } else + UN[i] = bytebuf[0] + 256 * bytebuf[1]; + } + } + + if (header.num_count > NumCount) + lseek(fd, (long)(2 * (header.num_count - NumCount)), 1); + else + for (i = header.num_count; i < NumCount; i++) + UN[i] = -1; + + if (beencalled) { + /* beencalled is non-zero only if we've been called */ + pst = malloc((unsigned)header.str_size); + if (pst == NULL) { + close(fd); + return (-1); + } + } else { + pst = StringTable; + beencalled++; + } + + num_strings = min(StrCount, header.str_count); + cur_string = 0; + + while (num_strings > 0) { + + if (swapping) { + numread = read(fd, byte, 2*min(num_strings, + OFFSET_BUFSIZE)); + if (numread <= 0) { + close(fd); + return (-1); + } + for (i = 0; i < numread / 2; i++) { + if (byte[i][0] == 0377 && byte[i][1] == 0377) + /* -1 */ + US[i + cur_string] = 0; + else if (byte[i][0] == 0376 && + byte[i][1] == 0377) + /* -2 */ + US[i + cur_string] = (char *)-1; + else + US[i + cur_string] = (byte[i][0] + + 256*byte[i][1]) + pst; + } + } else { + numread = read(fd, number, 2*min(num_strings, + OFFSET_BUFSIZE)); + if (numread <= 0) { + close(fd); + return (-1); + } + for (i = 0; i < numread / 2; i++) { + if (number[i] == -1) /* not there */ + US[i + cur_string] = 0; + else if (number[i] == -2) /* cancelled */ + US[i + cur_string] = (char *)-1; + else + US[i + cur_string] = number[i] + pst; + } + } + + cur_string += numread / 2; + num_strings -= numread / 2; + } + + if (header.str_count > StrCount) + lseek(fd, (long)(2 * (header.str_count - StrCount)), 1); + else for (i = header.str_count; i < StrCount; i++) + US[i] = 0; + + numread = read(fd, pst, header.str_size); + close(fd); + if (numread != header.str_size) + return (-1); + + return (0); +} + +/* + * int + * must_swap() + * + * Test whether this machine will need byte-swapping + * + */ + +int +must_swap() +{ + union { + short num; + char byte[2]; + } test; + + test.num = 1; + return (test.byte[1]); +} diff --git a/usr/src/cmd/tic/tic_scan.c b/usr/src/cmd/tic/tic_scan.c new file mode 100644 index 0000000000..d669d91ac4 --- /dev/null +++ b/usr/src/cmd/tic/tic_scan.c @@ -0,0 +1,510 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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 (c) 1999 by Sun Microsystems, Inc. + * All rights reserved. + */ +/* 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. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * 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" + +#define iswhite(ch) (ch == ' ' || ch == '\t') + + +static int first_column; /* See 'next_char()' below */ + + + +/* + * 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 +get_token() +{ + long number; + int type; + register int ch; + static char buffer[1024]; + register char *ptr; + int dot_flag = FALSE; + + while ((ch = next_char()) == '\n' || (isascii(ch) && iswhite(ch))); + + if (ch == EOF) + type = EOF; + else { + if (ch == '.') { + dot_flag = TRUE; + + while ((ch = next_char()) == ' ' || ch == '\t'); + } + + if (! isascii(ch) || ! isalnum(ch)) { + warning("Illegal character - '%c'", ch); + panic_mode(','); + } + + ptr = buffer; + if (ch != '\n') *(ptr++) = ch; + + if (first_column) { + while ((ch = next_char()) != ',' && ch != '\n' && ch != EOF) + *(ptr++) = ch; + + if (ch == EOF) + err_abort("Premature EOF"); + else if (ch == '\n') { + warning("Newline in middle of terminal name"); + panic_mode(','); + } + + *ptr = '\0'; + curr_token.tk_name = buffer; + type = NAMES; + } else { + ch = next_char(); + while (isascii(ch) && isalnum(ch)) { + *(ptr++) = ch; + ch = next_char(); + } + + *ptr++ = '\0'; + switch (ch) { + case ',': + curr_token.tk_name = buffer; + type = BOOLEAN; + break; + + case '@': + if (next_char() != ',') + warning("Missing comma"); + curr_token.tk_name = buffer; + type = CANCEL; + break; + + case '#': + number = 0; + if ((ch = next_char()) == ',') + warning("Missing numeric value"); + backspace(); + if ((ch = next_char()) == '0') { + if ((ch = next_char()) == 'x' || ch == 'X') { + while (isascii(ch = next_char()) && + isxdigit(ch)) { + number *= 16; + if (isdigit(ch)) + number += ch - '0'; + else if (ch >= 'a' && ch <= 'f') + number += 10 + ch - 'a'; + else + number += 10 + ch - 'A'; + } + } else { + backspace(); + while ((ch = next_char()) >= '0' && + ch <= '7') + number = number * 8 + ch - '0'; + } + } else { + backspace(); + while (isascii(ch = next_char()) && + isdigit(ch)) + number = number * 10 + ch - '0'; + } + if (ch != ',') + warning("Missing comma"); + curr_token.tk_name = buffer; + curr_token.tk_valnumber = number; + type = NUMBER; + break; + + case '=': + ch = trans_string(ptr); + if (ch != NULL && ch != ',') + warning("Missing comma"); + if (ch == NULL) + warning("NULL string value"); + curr_token.tk_name = buffer; + curr_token.tk_valstring = ptr; + type = STRING; + break; + + default: + warning("Illegal character - '%c'", ch); + } + } /* end else (first_column == FALSE) */ + } /* end else (ch != EOF) */ + + if (dot_flag == TRUE) + DEBUG(8, "Commented out ", ""); + + if (debug_level >= 8) { + fprintf(stderr, "Token: "); + switch (type) { + case BOOLEAN: + fprintf(stderr, "Boolean; name='%s'\n", + curr_token.tk_name); + break; + + case NUMBER: + fprintf(stderr, "Number; name = '%s', value = %d\n", + curr_token.tk_name, curr_token.tk_valnumber); + break; + + case STRING: + fprintf(stderr, "String; name = '%s', value = '%s'\n", + curr_token.tk_name, curr_token.tk_valstring); + break; + + case CANCEL: + fprintf(stderr, "Cancel; name = '%s'\n", + curr_token.tk_name); + break; + + case NAMES: + fprintf(stderr, "Names; value = '%s'\n", + curr_token.tk_name); + break; + + case EOF: + fprintf(stderr, "End of file\n"); + break; + + default: + warning("Bad token type"); + } + } + + if (dot_flag == TRUE) /* if commented out, use the next one */ + type = get_token(); + + 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 curr_column = -1; +char line[1024]; + +int +next_char() +{ + char *rtn_value; + long ftell(); + char *p; + + if (curr_column < 0 || curr_column > 1023 || + line[curr_column] == '\0') { + do { + curr_file_pos = ftell(stdin); + + if ((rtn_value = fgets(line, 1024, stdin)) == NULL) + return (EOF); + curr_line++; + p = &line[0]; + while (*p && iswhite(*p)) { + p++; + } + } while (*p == '#'); + + curr_column = 0; + while (isascii(line[curr_column]) && iswhite(line[curr_column])) + curr_column++; + } + + if (curr_column == 0 && line[0] != '\n') + first_column = TRUE; + else + first_column = FALSE; + + return (line[curr_column++]); +} + + +backspace() +{ + 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. + * + */ + +reset_input() +{ + 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 +trans_string(char *ptr) +{ + register int count = 0; + int number; + register int i; + register int ch; + + while ((ch = next_char()) != ',' && ch != EOF && !first_column) { + if (ch == '^') { + ch = next_char(); + if (ch == EOF) + err_abort("Premature EOF"); + + if (!isascii(ch) || ! isprint(ch)) { + warning("Illegal ^ character - '%c'", ch); + } + + if (ch == '@') + *(ptr++) = 0200; + else + *(ptr++) = ch & 037; + } else if (ch == '\\') { + ch = next_char(); + if (ch == EOF) + err_abort("Premature EOF"); + + if (ch >= '0' && ch <= '7') { + number = ch - '0'; + for (i = 0; i < 2; i++) { + ch = next_char(); + if (ch == EOF) + err_abort("Premature EOF"); + + if (ch < '0' || ch > '7') { + backspace(); + break; + } + + number = number * 8 + ch - '0'; + } + + if (number == 0) + number = 0200; + *(ptr++) = (char)number; + } else { + switch (ch) { + case 'E': + case 'e': *(ptr++) = '\033'; break; + + case 'l': + case 'n': *(ptr++) = '\n'; break; + + case 'r': *(ptr++) = '\r'; break; + + case 'b': *(ptr++) = '\010'; break; + + case 's': *(ptr++) = ' '; break; + + case 'f': *(ptr++) = '\014'; break; + + case 't': *(ptr++) = '\t'; break; + + case '\\': *(ptr++) = '\\'; break; + + case '^': *(ptr++) = '^'; break; + + case ',': *(ptr++) = ','; break; + + case ':': *(ptr++) = ':'; break; + + default: + warning("Illegal character in \\ sequence - '%c'", + ch); + *(ptr++) = ch; + } /* endswitch (ch) */ + } /* endelse (ch < '0' || ch > '7') */ + } /* end else if (ch == '\\') */ + else { + if (ch != '\n') *(ptr++) = ch; + } + + count ++; + + if (count > 1000) + warning("Very long string found. Missing comma?"); + } /* end while */ + + if (ch == EOF) + 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. + */ +panic_mode(int ch) +{ + register int c; + + for (;;) { + c = next_char(); + if (c == ch) + return; + if (c == EOF) + return; + } +} |
