17d8a9cc2Snia/* 27d8a9cc2Snia * Copyright 1988 by Evans & Sutherland Computer Corporation, 37d8a9cc2Snia * Salt Lake City, Utah 47d8a9cc2Snia * Portions Copyright 1989 by the Massachusetts Institute of Technology 57d8a9cc2Snia * Cambridge, Massachusetts 6645f5050Syouri * 77d8a9cc2Snia * Copyright 1992 Claude Lecommandeur. 8645f5050Syouri */ 9645f5050Syouri 10645f5050Syouri/*********************************************************************** 11645f5050Syouri * 12645f5050Syouri * $XConsortium: parse.c,v 1.52 91/07/12 09:59:37 dave Exp $ 13645f5050Syouri * 14645f5050Syouri * parse the .twmrc file 15645f5050Syouri * 16645f5050Syouri * 17-Nov-87 Thomas E. LaStrange File created 17645f5050Syouri * 10-Oct-90 David M. Sternlicht Storing saved colors on root 18645f5050Syouri * 19645f5050Syouri * Do the necessary modification to be integrated in ctwm. 20645f5050Syouri * Can no longer be used for the standard twm. 21645f5050Syouri * 22645f5050Syouri * 22-April-92 Claude Lecommandeur. 23645f5050Syouri * 24645f5050Syouri ***********************************************************************/ 25645f5050Syouri 267d8a9cc2Snia#include "ctwm.h" 277d8a9cc2Snia 28645f5050Syouri#include <stdio.h> 297d8a9cc2Snia#include <stdlib.h> 307d8a9cc2Snia#include <string.h> 317d8a9cc2Snia#include <strings.h> 327d8a9cc2Snia#ifdef USEM4 337d8a9cc2Snia# include <sys/types.h> 347d8a9cc2Snia# include <sys/wait.h> 35645f5050Syouri#endif 367d8a9cc2Snia 377d8a9cc2Snia#include "ctwm_atoms.h" 38645f5050Syouri#include "screen.h" 39645f5050Syouri#include "parse.h" 407d8a9cc2Snia#include "parse_int.h" 417d8a9cc2Snia#include "deftwmrc.h" 42645f5050Syouri#ifdef SOUNDS 43645f5050Syouri# include "sound.h" 44645f5050Syouri#endif 45645f5050Syouri 467d8a9cc2Snia#ifndef SYSTEM_INIT_FILE 477d8a9cc2Snia#error "No SYSTEM_INIT_FILE set" 48645f5050Syouri#endif 49645f5050Syouri 507d8a9cc2Sniastatic bool ParseStringList(const char **sl); 51645f5050Syouri 527d8a9cc2Snia/* 537d8a9cc2Snia * With current bison, this is defined in the gram.tab.h, so this causes 547d8a9cc2Snia * a warning for redundant declaration. With older bisons and byacc, 557d8a9cc2Snia * it's not, so taking it out causes a warning for implicit declaration. 567d8a9cc2Snia * A little looking around doesn't show any handy #define's we could use 577d8a9cc2Snia * to be sure of the difference. This should quiet it down on gcc/clang 587d8a9cc2Snia * anyway... 597d8a9cc2Snia */ 607d8a9cc2Snia#ifdef __GNUC__ 617d8a9cc2Snia# pragma GCC diagnostic push 627d8a9cc2Snia# pragma GCC diagnostic ignored "-Wredundant-decls" 637d8a9cc2Sniaextern int yyparse(void); 647d8a9cc2Snia# pragma GCC diagnostic pop 65645f5050Syouri#else 66645f5050Syouriextern int yyparse(void); 677d8a9cc2Snia#endif 68645f5050Syouri 697d8a9cc2Snia// Because of how this winds up shared with callback funcs in the 707d8a9cc2Snia// parsing, it's difficult to unwind from being global, so just accept 717d8a9cc2Snia// it. 72645f5050Syouristatic FILE *twmrc; 737d8a9cc2Snia 74645f5050Syouristatic int ptr = 0; 75645f5050Syouristatic int len = 0; 767d8a9cc2Snia#define BUF_LEN 300 777d8a9cc2Sniastatic char buff[BUF_LEN + 1]; 787d8a9cc2Sniastatic const char **stringListSource, *currentString; 797d8a9cc2Snia 807d8a9cc2Snia#ifdef NON_FLEX_LEX 817d8a9cc2Snia/* 827d8a9cc2Snia * While these are (were) referenced in a number of places through the 837d8a9cc2Snia * file, overflowlen is initialized to 0, only possibly changed in 847d8a9cc2Snia * twmUnput(), and unless it's non-zero, neither is otherwise touched. 857d8a9cc2Snia * So this is purely a twmUnput()-related var, and with flex, never used 867d8a9cc2Snia * for anything. 877d8a9cc2Snia */ 887d8a9cc2Sniastatic char overflowbuff[20]; /* really only need one */ 89645f5050Syouristatic int overflowlen; 90645f5050Syouri#endif 91645f5050Syouri 927d8a9cc2Sniaint ConstrainedMoveTime = 400; /* milliseconds, event times */ 937d8a9cc2Sniabool ParseError; /* error parsing the .twmrc file */ 947d8a9cc2Sniaint RaiseDelay = 0; /* msec, for AutoRaise */ 957d8a9cc2Sniaint (*twmInputFunc)(void); /* used in lexer */ 96645f5050Syouri 977d8a9cc2Sniastatic int twmrc_lineno; 98645f5050Syouri 997d8a9cc2Snia 1007d8a9cc2Snia/* Actual file loader */ 1017d8a9cc2Sniastatic int ParseTwmrc(const char *filename); 1027d8a9cc2Snia 1037d8a9cc2Snia/* lex plumbing funcs */ 1047d8a9cc2Sniastatic bool doparse(int (*ifunc)(void), const char *srctypename, 1057d8a9cc2Snia const char *srcname); 106645f5050Syouri 107645f5050Syouristatic int twmStringListInput(void); 108645f5050Syouri#ifndef USEM4 109645f5050Syouristatic int twmFileInput(void); 110645f5050Syouri#else 1117d8a9cc2Sniastatic int m4twmFileInput(void); 112645f5050Syouri#endif 113645f5050Syouri 1147d8a9cc2Snia#if defined(YYDEBUG) && YYDEBUG 1157d8a9cc2Sniaint yydebug = 1; 1167d8a9cc2Snia#endif 117645f5050Syouri 118645f5050Syouri 1197d8a9cc2Snia/** 1207d8a9cc2Snia * Principal entry point from top-level code to parse the config file. 1217d8a9cc2Snia * This tries the various permutations of config files we could load. 1227d8a9cc2Snia * For most possible names, we try loading `$NAME.$SCREENNUM` before 1237d8a9cc2Snia * trying `$NAME`. If a `-f filename` is given on the command line, it's 1247d8a9cc2Snia * passed in here, and the normal `~/.[c]twmrc*` attempts are skipped if 1257d8a9cc2Snia * it's not found. 126645f5050Syouri * 1277d8a9cc2Snia * \param filename A filename given in the -f command-line argument (or 1287d8a9cc2Snia * NULL) 1297d8a9cc2Snia * \return true/false for whether a valid config was parsed out from 1307d8a9cc2Snia * somewhere. 131645f5050Syouri */ 1327d8a9cc2Sniabool 1337d8a9cc2SniaLoadTwmrc(const char *filename) 134645f5050Syouri{ 1357d8a9cc2Snia int ret = -1; 1367d8a9cc2Snia char *tryname = NULL; 1377d8a9cc2Snia 1387d8a9cc2Snia /* 1397d8a9cc2Snia * Check for the twmrc file in the following order: 1407d8a9cc2Snia * 0. -f filename.# 1417d8a9cc2Snia * 1. -f filename 1427d8a9cc2Snia * (skip to 6 if -f was given) 1437d8a9cc2Snia * 2. .ctwmrc.# 1447d8a9cc2Snia * 3. .ctwmrc 1457d8a9cc2Snia * 4. .twmrc.# 1467d8a9cc2Snia * 5. .twmrc 1477d8a9cc2Snia * 6. system.ctwmrc 1487d8a9cc2Snia */ 1497d8a9cc2Snia#define TRY(fn) if((ret = ParseTwmrc(fn)) != -1) { goto DONE_TRYING; } (void)0 1507d8a9cc2Snia 1517d8a9cc2Snia if(filename) { 1527d8a9cc2Snia /* -f filename.# */ 1537d8a9cc2Snia asprintf(&tryname, "%s.%d", filename, Scr->screen); 1547d8a9cc2Snia if(tryname == NULL) { 1557d8a9cc2Snia // Oh, we're _screwed_... 1567d8a9cc2Snia return false; 1577d8a9cc2Snia } 1587d8a9cc2Snia TRY(tryname); 159645f5050Syouri 1607d8a9cc2Snia /* -f filename */ 1617d8a9cc2Snia TRY(filename); 162645f5050Syouri 1637d8a9cc2Snia /* If we didn't get either from -f, don't try the ~ bits */ 1647d8a9cc2Snia goto TRY_FALLBACK; 1657d8a9cc2Snia } 166645f5050Syouri 1677d8a9cc2Snia if(Home) { 1687d8a9cc2Snia /* ~/.ctwmrc.screennum */ 1697d8a9cc2Snia free(tryname); 1707d8a9cc2Snia asprintf(&tryname, "%s/.ctwmrc.%d", Home, Scr->screen); 1717d8a9cc2Snia if(tryname == NULL) { 1727d8a9cc2Snia return false; 173645f5050Syouri } 1747d8a9cc2Snia TRY(tryname); 175645f5050Syouri 1767d8a9cc2Snia // All later attempts are guaranteed shorter strings than that, 1777d8a9cc2Snia // so we can just keep sprintf'ing over it. 178645f5050Syouri 1797d8a9cc2Snia /* ~/.ctwmrc */ 1807d8a9cc2Snia sprintf(tryname, "%s/.ctwmrc", Home); 1817d8a9cc2Snia TRY(tryname); 182645f5050Syouri 1837d8a9cc2Snia /* ~/.twmrc.screennum */ 1847d8a9cc2Snia sprintf(tryname, "%s/.twmrc.%d", Home, Scr->screen); 1857d8a9cc2Snia TRY(tryname); 186645f5050Syouri 1877d8a9cc2Snia /* ~/.twmrc */ 1887d8a9cc2Snia sprintf(tryname, "%s/.twmrc", Home); 1897d8a9cc2Snia TRY(tryname); 1907d8a9cc2Snia } 191645f5050Syouri 1927d8a9cc2SniaTRY_FALLBACK: 1937d8a9cc2Snia /* system.twmrc */ 1947d8a9cc2Snia if((ret = ParseTwmrc(SYSTEM_INIT_FILE)) != -1) { 1957d8a9cc2Snia if(ret && filename) { 1967d8a9cc2Snia // If we were -f'ing, fell back to the system default, and 1977d8a9cc2Snia // that succeeeded, we warn. It's "normal"(ish) to not have 1987d8a9cc2Snia // a personal twmrc and fall back... 1997d8a9cc2Snia fprintf(stderr, 2007d8a9cc2Snia "%s: unable to open twmrc file %s, using %s instead\n", 2017d8a9cc2Snia ProgramName, filename, SYSTEM_INIT_FILE); 2027d8a9cc2Snia } 2037d8a9cc2Snia goto DONE_TRYING; 204645f5050Syouri } 2057d8a9cc2Snia 2067d8a9cc2Snia 2077d8a9cc2SniaDONE_TRYING: 2087d8a9cc2Snia#undef TRY 2097d8a9cc2Snia free(tryname); 2107d8a9cc2Snia 2117d8a9cc2Snia /* 2127d8a9cc2Snia * If we wound up with -1 all the way, we totally failed to find a 2137d8a9cc2Snia * file to work with. Fall back to builtin config. 2147d8a9cc2Snia */ 2157d8a9cc2Snia if(ret == -1) { 2167d8a9cc2Snia // Only warn if -f. 2177d8a9cc2Snia if(filename) { 2187d8a9cc2Snia fprintf(stderr, 2197d8a9cc2Snia "%s: unable to open twmrc file %s, using built-in defaults instead\n", 2207d8a9cc2Snia ProgramName, filename); 2217d8a9cc2Snia } 2227d8a9cc2Snia return ParseStringList(defTwmrc); 223645f5050Syouri } 224645f5050Syouri 2257d8a9cc2Snia 2267d8a9cc2Snia /* Better have a useful value in ret... */ 2277d8a9cc2Snia return ret; 228645f5050Syouri} 229645f5050Syouri 230645f5050Syouri 2317d8a9cc2Snia/** 2327d8a9cc2Snia * Try parsing a file as a ctwmrc. 233645f5050Syouri * 2347d8a9cc2Snia * \param filename The filename to try opening and parsing. 2357d8a9cc2Snia * \return -1,0,1. 0/1 should be treated as false/true for whether 2367d8a9cc2Snia * parsing the file succeeded. -1 means the file couldn't be opened. 237645f5050Syouri */ 2387d8a9cc2Sniastatic int 2397d8a9cc2SniaParseTwmrc(const char *filename) 2407d8a9cc2Snia{ 2417d8a9cc2Snia bool status; 242645f5050Syouri 2437d8a9cc2Snia#if 0 2447d8a9cc2Snia fprintf(stderr, "%s(): Trying %s\n", __func__, filename); 2457d8a9cc2Snia#endif 246645f5050Syouri 2477d8a9cc2Snia /* See if we can open the file */ 2487d8a9cc2Snia if(!filename) { 2497d8a9cc2Snia return -1; 2507d8a9cc2Snia } 2517d8a9cc2Snia twmrc = fopen(filename, "r"); 2527d8a9cc2Snia if(!twmrc) { 2537d8a9cc2Snia return -1; 2547d8a9cc2Snia } 255645f5050Syouri 256645f5050Syouri 2577d8a9cc2Snia /* Got it. Kick off the parsing, however we do it. */ 2587d8a9cc2Snia#ifdef USEM4 2597d8a9cc2Snia FILE *raw = NULL; 2607d8a9cc2Snia if(CLarg.GoThroughM4) { 2617d8a9cc2Snia /* 2627d8a9cc2Snia * Hold onto raw filehandle so we can fclose() it below, and 2637d8a9cc2Snia * swap twmrc over to the output from m4 2647d8a9cc2Snia */ 2657d8a9cc2Snia raw = twmrc; 2667d8a9cc2Snia twmrc = start_m4(raw); 267645f5050Syouri } 2687d8a9cc2Snia status = doparse(m4twmFileInput, "file", filename); 2697d8a9cc2Snia fclose(twmrc); 2707d8a9cc2Snia if(raw) { 2717d8a9cc2Snia fclose(raw); 272645f5050Syouri } 2737d8a9cc2Snia#else 2747d8a9cc2Snia status = doparse(twmFileInput, "file", filename); 2757d8a9cc2Snia fclose(twmrc); 2767d8a9cc2Snia#endif 277645f5050Syouri 2787d8a9cc2Snia /* And we're done */ 2797d8a9cc2Snia return status; 280645f5050Syouri 2817d8a9cc2Snia /* NOTREACHED */ 282645f5050Syouri} 283645f5050Syouri 2847d8a9cc2Sniastatic bool 2857d8a9cc2SniaParseStringList(const char **sl) 286645f5050Syouri{ 2877d8a9cc2Snia stringListSource = sl; 2887d8a9cc2Snia currentString = *sl; 2897d8a9cc2Snia return doparse(twmStringListInput, "string list", NULL); 290645f5050Syouri} 291645f5050Syouri 292645f5050Syouri 2937d8a9cc2Snia/* 2947d8a9cc2Snia * Util used throughout the code (possibly often wrongly?) 295645f5050Syouri */ 2967d8a9cc2Sniavoid twmrc_error_prefix(void) 297645f5050Syouri{ 2987d8a9cc2Snia fprintf(stderr, "%s: line %d: ", ProgramName, twmrc_lineno); 299645f5050Syouri} 300645f5050Syouri 301645f5050Syouri 302645f5050Syouri 303645f5050Syouri/* 3047d8a9cc2Snia * Everything below here is related to plumbing and firing off lex/yacc 305645f5050Syouri */ 306645f5050Syouri 307645f5050Syouri 308645f5050Syouri/* 3097d8a9cc2Snia * Backend func that takes an input-providing func and hooks it up to the 3107d8a9cc2Snia * lex/yacc parser to do the work 311645f5050Syouri */ 3127d8a9cc2Sniastatic bool 3137d8a9cc2Sniadoparse(int (*ifunc)(void), const char *srctypename, 3147d8a9cc2Snia const char *srcname) 315645f5050Syouri{ 3167d8a9cc2Snia ptr = 0; 3177d8a9cc2Snia len = 0; 3187d8a9cc2Snia twmrc_lineno = 0; 3197d8a9cc2Snia ParseError = false; 3207d8a9cc2Snia twmInputFunc = ifunc; 3217d8a9cc2Snia#ifdef NON_FLEX_LEX 3227d8a9cc2Snia overflowlen = 0; 3237d8a9cc2Snia#endif 324645f5050Syouri 3257d8a9cc2Snia yyparse(); 326645f5050Syouri 3277d8a9cc2Snia if(ParseError) { 3287d8a9cc2Snia fprintf(stderr, "%s: errors found in twm %s", 3297d8a9cc2Snia ProgramName, srctypename); 3307d8a9cc2Snia if(srcname) { 3317d8a9cc2Snia fprintf(stderr, " \"%s\"", srcname); 3327d8a9cc2Snia } 3337d8a9cc2Snia fprintf(stderr, "\n"); 3347d8a9cc2Snia } 3357d8a9cc2Snia return !(ParseError); 3367d8a9cc2Snia} 337645f5050Syouri 338645f5050Syouri 3397d8a9cc2Snia/* 3407d8a9cc2Snia * Various input routines for the lexer for the various sources of 3417d8a9cc2Snia * config. 3427d8a9cc2Snia */ 343645f5050Syouri 3447d8a9cc2Snia#ifndef USEM4 3457d8a9cc2Snia#include <ctype.h> 346645f5050Syouri 3477d8a9cc2Snia/* This has Tom's include() funtionality. This is utterly useless if you 3487d8a9cc2Snia * can use m4 for the same thing. Chris P. Ross */ 349645f5050Syouri 3507d8a9cc2Snia#define MAX_INCLUDES 10 351645f5050Syouri 3527d8a9cc2Sniastatic struct incl { 3537d8a9cc2Snia FILE *fp; 3547d8a9cc2Snia char *name; 3557d8a9cc2Snia int lineno; 3567d8a9cc2Snia} rc_includes[MAX_INCLUDES]; 3577d8a9cc2Sniastatic int include_file = 0; 358645f5050Syouri 359645f5050Syouri 3607d8a9cc2Sniastatic int twmFileInput(void) 361645f5050Syouri{ 3627d8a9cc2Snia#ifdef NON_FLEX_LEX 3637d8a9cc2Snia if(overflowlen) { 3647d8a9cc2Snia return (int) overflowbuff[--overflowlen]; 365645f5050Syouri } 366645f5050Syouri#endif 3677d8a9cc2Snia 3687d8a9cc2Snia while(ptr == len) { 3697d8a9cc2Snia while(include_file) { 3707d8a9cc2Snia if(fgets(buff, BUF_LEN, rc_includes[include_file].fp) == NULL) { 3717d8a9cc2Snia free(rc_includes[include_file].name); 3727d8a9cc2Snia fclose(rc_includes[include_file].fp); 3737d8a9cc2Snia twmrc_lineno = rc_includes[include_file--].lineno; 3747d8a9cc2Snia } 3757d8a9cc2Snia else { 3767d8a9cc2Snia break; 3777d8a9cc2Snia } 3787d8a9cc2Snia } 3797d8a9cc2Snia 3807d8a9cc2Snia if(!include_file) 3817d8a9cc2Snia if(fgets(buff, BUF_LEN, twmrc) == NULL) { 3827d8a9cc2Snia return 0; 3837d8a9cc2Snia } 3847d8a9cc2Snia twmrc_lineno++; 3857d8a9cc2Snia 3867d8a9cc2Snia if(strncmp(buff, "include", 7) == 0) { 3877d8a9cc2Snia /* Whoops, an include file! */ 3887d8a9cc2Snia char *p = buff + 7, *q; 3897d8a9cc2Snia FILE *fp; 3907d8a9cc2Snia 3917d8a9cc2Snia while(isspace(*p)) { 3927d8a9cc2Snia p++; 3937d8a9cc2Snia } 3947d8a9cc2Snia for(q = p; *q && !isspace(*q); q++) { 3957d8a9cc2Snia continue; 3967d8a9cc2Snia } 3977d8a9cc2Snia *q = 0; 3987d8a9cc2Snia 3997d8a9cc2Snia if((fp = fopen(p, "r")) == NULL) { 4007d8a9cc2Snia fprintf(stderr, "%s: Unable to open included init file %s\n", 4017d8a9cc2Snia ProgramName, p); 4027d8a9cc2Snia continue; 4037d8a9cc2Snia } 4047d8a9cc2Snia if(++include_file >= MAX_INCLUDES) { 4057d8a9cc2Snia fprintf(stderr, "%s: init file includes nested too deep\n", 4067d8a9cc2Snia ProgramName); 4077d8a9cc2Snia continue; 4087d8a9cc2Snia } 4097d8a9cc2Snia rc_includes[include_file].fp = fp; 4107d8a9cc2Snia rc_includes[include_file].lineno = twmrc_lineno; 4117d8a9cc2Snia twmrc_lineno = 0; 4127d8a9cc2Snia rc_includes[include_file].name = strdup(p); 4137d8a9cc2Snia continue; 4147d8a9cc2Snia } 4157d8a9cc2Snia ptr = 0; 4167d8a9cc2Snia len = strlen(buff); 417645f5050Syouri } 4187d8a9cc2Snia return ((int)buff[ptr++]); 419645f5050Syouri} 4207d8a9cc2Snia#else /* USEM4 */ 4217d8a9cc2Snia/* If you're going to use m4, use this version instead. Much simpler. 4227d8a9cc2Snia * m4 ism's credit to Josh Osborne (stripes) */ 423645f5050Syouri 4247d8a9cc2Sniastatic int m4twmFileInput(void) 425645f5050Syouri{ 4267d8a9cc2Snia int line; 4277d8a9cc2Snia static FILE *cp = NULL; 4287d8a9cc2Snia 4297d8a9cc2Snia if(cp == NULL && CLarg.keepM4_filename) { 4307d8a9cc2Snia cp = fopen(CLarg.keepM4_filename, "w"); 4317d8a9cc2Snia if(cp == NULL) { 4327d8a9cc2Snia fprintf(stderr, 4337d8a9cc2Snia "%s: unable to create m4 output %s, ignoring\n", 4347d8a9cc2Snia ProgramName, CLarg.keepM4_filename); 4357d8a9cc2Snia CLarg.keepM4_filename = NULL; 4367d8a9cc2Snia } 437645f5050Syouri } 438645f5050Syouri 4397d8a9cc2Snia#ifdef NON_FLEX_LEX 4407d8a9cc2Snia if(overflowlen) { 4417d8a9cc2Snia return((int) overflowbuff[--overflowlen]); 442645f5050Syouri } 443645f5050Syouri#endif 444645f5050Syouri 4457d8a9cc2Snia while(ptr == len) { 4467d8a9cc2Snianextline: 4477d8a9cc2Snia if(fgets(buff, BUF_LEN, twmrc) == NULL) { 4487d8a9cc2Snia if(cp) { 4497d8a9cc2Snia fclose(cp); 4507d8a9cc2Snia } 4517d8a9cc2Snia return(0); 4527d8a9cc2Snia } 4537d8a9cc2Snia if(cp) { 4547d8a9cc2Snia fputs(buff, cp); 4557d8a9cc2Snia } 456645f5050Syouri 4577d8a9cc2Snia if(sscanf(buff, "#line %d", &line)) { 4587d8a9cc2Snia twmrc_lineno = line - 1; 4597d8a9cc2Snia goto nextline; 4607d8a9cc2Snia } 4617d8a9cc2Snia else { 4627d8a9cc2Snia twmrc_lineno++; 4637d8a9cc2Snia } 464645f5050Syouri 4657d8a9cc2Snia ptr = 0; 4667d8a9cc2Snia len = strlen(buff); 467645f5050Syouri } 4687d8a9cc2Snia return ((int)buff[ptr++]); 469645f5050Syouri} 4707d8a9cc2Snia#endif /* USEM4 */ 471645f5050Syouri 472645f5050Syouri 4737d8a9cc2Sniastatic int twmStringListInput(void) 474645f5050Syouri{ 4757d8a9cc2Snia#ifdef NON_FLEX_LEX 4767d8a9cc2Snia if(overflowlen) { 4777d8a9cc2Snia return (int) overflowbuff[--overflowlen]; 4787d8a9cc2Snia } 4797d8a9cc2Snia#endif 480645f5050Syouri 4817d8a9cc2Snia /* 4827d8a9cc2Snia * return the character currently pointed to 4837d8a9cc2Snia */ 4847d8a9cc2Snia if(currentString) { 4857d8a9cc2Snia unsigned int c = (unsigned int) * currentString++; 486645f5050Syouri 4877d8a9cc2Snia if(c) { 4887d8a9cc2Snia return c; /* if non-nul char */ 4897d8a9cc2Snia } 4907d8a9cc2Snia currentString = *++stringListSource; /* advance to next bol */ 4917d8a9cc2Snia return '\n'; /* but say that we hit last eol */ 4927d8a9cc2Snia } 4937d8a9cc2Snia return 0; /* eof */ 494645f5050Syouri} 495645f5050Syouri 496645f5050Syouri 497645f5050Syouri 498645f5050Syouri/* 4997d8a9cc2Snia * unput/output funcs for AT&T lex. No longer supported, and expected to 5007d8a9cc2Snia * be GC'd in a release or two. 501645f5050Syouri */ 5027d8a9cc2Snia#ifdef NON_FLEX_LEX 503645f5050Syouri 5047d8a9cc2Sniavoid twmUnput(int c) 505645f5050Syouri{ 5067d8a9cc2Snia if(overflowlen < sizeof overflowbuff) { 5077d8a9cc2Snia overflowbuff[overflowlen++] = (char) c; 508645f5050Syouri } 5097d8a9cc2Snia else { 5107d8a9cc2Snia twmrc_error_prefix(); 5117d8a9cc2Snia fprintf(stderr, "unable to unput character (%c)\n", 5127d8a9cc2Snia c); 513fb81d040Schristos } 514645f5050Syouri} 515645f5050Syouri 5167d8a9cc2Sniavoid TwmOutput(int c) 517645f5050Syouri{ 5187d8a9cc2Snia putchar(c); 519645f5050Syouri} 520645f5050Syouri 5217d8a9cc2Snia#endif /* NON_FLEX_LEX */ 522