|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 13042 (0x32f2)
Types: TextFile
Names: »codeview.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/gnu-31mar87/chess/Xchess/scrollText/codeview.c«
/*
* C Code Viewer for X
*
* David Harrison
* University of California, 1986
*/
#include <stdio.h>
#include <ctype.h>
#include <X/Xlib.h>
#include "st.h"
st_table *keywords = (st_table *) 0;
int in_comment = 0;
int in_string = 0;
/* Table to define which delimiters are interesting */
#define MAXCHARS 256
char specialChar[MAXCHARS];
extern int strcmp();
extern char *strcpy();
extern char *strncpy();
main(argc,argv)
int argc;
char *argv[];
{
FILE *incFile;
Display *theDisp;
Window theWin;
OpaqueFrame theFrame;
XEvent theEvent;
FontInfo *theFont;
char *dispname;
char *fontNames[4];
int colorPixels[4];
char *filename;
char *ProcessLine();
char linebuf[2048];
int index, count;
int bgPixel, fgPixel, curPixel, borPixel;
/* read the argument list */
dispname = "";
filename = (char *) 0;
fontNames[0] = "timrom12";
fontNames[1] = "timrom12i";
fontNames[2] = "timrom12b";
fontNames[3] = "helv12";
for (index = 0; index < 4; index++) colorPixels[index] = BlackPixel;
bgPixel = WhitePixel;
curPixel = BlackPixel;
borPixel = BlackPixel;
index = 1;
while (index < argc) {
if (argv[index][0] == '-') {
/* Its an option */
switch (argv[index][1]) {
case 'f':
/* Read file into buffer */
filename = argv[index + 1];
index += 2;
break;
default:
printf("Unknown option\n");
printf("format: %s [-f file] [host:display]\n",
argv[0]);
exit(1);
}
} else {
/* Its the display */
dispname = argv[index];
index++;
}
}
theDisp = XOpenDisplay(dispname);
if (!theDisp) {
printf("Unable to open display\n");
exit(1);
}
readDefaults(argv[0], fontNames, colorPixels, &bgPixel, &fgPixel,
&curPixel, &borPixel);
theFrame.bdrwidth = 2;
theFrame.border = XMakeTile(borPixel);
theFrame.background = XMakeTile(bgPixel);
theWin = XCreate("C Code Viewer", "codeView",
"", "400x400+100+100", &theFrame, 50, 50);
XFreePixmap(theFrame.border);
XFreePixmap(theFrame.background);
if (!theWin) exit(1);
XSelectInput(theWin, ExposeRegion|ExposeCopy|ButtonReleased);
XMapWindow(theWin);
theFont = XOpenFont(fontNames[0]);
if (!TxtGrab(theWin, "codeView", theFont,
bgPixel, fgPixel, curPixel)) {
printf("Text grab failed\n");
exit(1);
}
XFlush();
for (index = 0; index < 4; index++) {
if (fontNames[index]) {
TxtAddFont(theWin, index, XOpenFont(fontNames[index]),
colorPixels[index]);
}
}
incFile = stdin;
if (filename) {
incFile = fopen(filename, "r");
if (!incFile) {
printf("can't read %s\n", filename);
exit(1);
}
}
/* Initialize tables */
InitTable();
/* Jam in the text */
while (fgets(linebuf, 2047, incFile)) {
TxtJamStr(theWin, ProcessLine(linebuf));
}
/* Main event loop */
count = 0;
for (;;) {
XNextEvent(&theEvent);
if (!TxtFilter(&theEvent)) {
switch (theEvent.type) {
case ButtonReleased:
if ((((XButtonEvent *) &theEvent)->detail & ValueMask) ==
MiddleButton)
{
count++;
if (count > 1) {
printf("done\n");
exit(0);
}
}
else {
XFeep(0);
}
}
}
}
}
readDefaults(name, fontNames, colorPixels, bg, fg, cur, bor)
char *name;
char *fontNames[3];
int colorPixels[3];
int *bg, *fg, *cur, *bor;
/*
* Reads all of the X defaults
*/
{
char *value;
char buffer[1024];
Color clrdef;
value = XGetDefault(name, "Normal.Font");
if (value) fontNames[0] = value;
value = XGetDefault(name, "Comment.Font");
if (value) fontNames[1] = value;
value = XGetDefault(name, "Keyword.Font");
if (value) fontNames[2] = value;
value = XGetDefault(name, "String.Font");
if (value) fontNames[3] = value;
value = XGetDefault(name, "Background");
strcpy(buffer, value);
if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
*bg = clrdef.pixel;
}
value = XGetDefault(name, "Foreground");
strcpy(buffer, value);
if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
*fg = clrdef.pixel;
colorPixels[0] = clrdef.pixel;
}
value = XGetDefault(name, "Border");
strcpy(buffer, value);
if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
*bor = clrdef.pixel;
}
value = XGetDefault(name, "Cursor");
strcpy(buffer, value);
if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
*cur = clrdef.pixel;
}
value = XGetDefault(name, "Normal.Color");
strcpy(buffer, value);
if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
colorPixels[0] = clrdef.pixel;
}
value = XGetDefault(name, "Comment.Color");
strcpy(buffer, value);
if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
colorPixels[1] = clrdef.pixel;
}
value = XGetDefault(name, "Keyword.Color");
strcpy(buffer, value);
if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
colorPixels[2] = clrdef.pixel;
}
value = XGetDefault(name, "String.Color");
strcpy(buffer, value);
if (value && XParseColor(buffer, &clrdef) && XGetHardwareColor(&clrdef)) {
colorPixels[3] = clrdef.pixel;
}
}
InitTable()
/*
* Initializes hash table of keywords and special character array
*/
{
int index;
for (index = 0; index < MAXCHARS; index++) {
specialChar[index] = 0;
}
specialChar['\0'] = 1; /* End of file */
specialChar[ ' '] = 1; /* Space */
specialChar['\t'] = 1; /* Tab */
specialChar['\n'] = 1; /* End of line */
specialChar[ '/'] = 1; /* Slash */
specialChar[ '*'] = 1; /* Star */
specialChar[ '"'] = 1; /* Quote */
keywords = st_init_table(strcmp, st_strhash);
st_insert(keywords, "int", (char *) 0);
st_insert(keywords, "char", (char *) 0);
st_insert(keywords, "float", (char *) 0);
st_insert(keywords, "double", (char *) 0);
st_insert(keywords, "struct", (char *) 0);
st_insert(keywords, "union", (char *) 0);
st_insert(keywords, "long", (char *) 0);
st_insert(keywords, "short", (char *) 0);
st_insert(keywords, "unsigned", (char *) 0);
st_insert(keywords, "auto", (char *) 0);
st_insert(keywords, "extern", (char *) 0);
st_insert(keywords, "register", (char *) 0);
st_insert(keywords, "typedef", (char *) 0);
st_insert(keywords, "static", (char *) 0);
st_insert(keywords, "goto", (char *) 0);
st_insert(keywords, "return", (char *) 0);
st_insert(keywords, "sizeof", (char *) 0);
st_insert(keywords, "break", (char *) 0);
st_insert(keywords, "continue", (char *) 0);
st_insert(keywords, "if", (char *) 0);
st_insert(keywords, "else", (char *) 0);
st_insert(keywords, "for", (char *) 0);
st_insert(keywords, "do", (char *) 0);
st_insert(keywords, "while", (char *) 0);
st_insert(keywords, "switch", (char *) 0);
st_insert(keywords, "case", (char *) 0);
st_insert(keywords, "default", (char *) 0);
st_insert(keywords, "entry", (char *) 0);
}
#define SPACE 1
#define TAB 2
#define COMBEGIN 3
#define COMEND 4
#define IDENT 5
#define USRIDENT 6
#define STR 7
#define OTHER 8
#define ENDLINE 9
char *ProcessLine(someline)
char *someline;
/*
* This routine takes a line, expands out its tabs into spaces
* italicizes comments and boldfaces keywords.
*/
{
static char outbuf[2048];
int start, len, token, outspot, index, target;
/* Reinitializes the token generator */
get_token((char *) 0, (int *) 0, (int *) 0, (int *) 0);
outspot = 0;
while (get_token(someline, &start, &len, &token)) {
#ifdef
print_token(someline, start, len, token);
#endif
switch (token) {
case SPACE:
for (index = 0; index < len; index++) {
outbuf[outspot] = ' ';
outspot++;
}
break;
case TAB:
/* Expand out using spaces */
target = ((outspot / 8) + 1) * 8;
for (index = outspot; index < target; index++) {
outbuf[index] = ' ';
outspot++;
}
break;
case COMBEGIN:
/* Put it in and then change fonts */
if (!in_string) {
outbuf[outspot++] = '\006';
outbuf[outspot++] = '1';
in_comment = 1;
}
outbuf[outspot++] = '/';
outbuf[outspot++] = '*';
break;
case COMEND:
/* Change font back to normal and output */
outbuf[outspot++] = '*';
outbuf[outspot++] = '/';
if (!in_string) {
outbuf[outspot++] = '\006';
outbuf[outspot++] = '0';
in_comment = 0;
}
break;
case STR:
if (in_comment) {
outbuf[outspot++] = '"';
} else {
if (in_string) {
/* Change font back to normal and output */
outbuf[outspot++] = '"';
outbuf[outspot++] = '\006';
outbuf[outspot++] = '0';
in_string = 0;
} else {
/* Put in string mode and change fonts */
outbuf[outspot++] = '\006';
outbuf[outspot++] = '3';
outbuf[outspot++] = '"';
in_string = 1;
}
}
break;
case IDENT:
/* Output in boldface if not in comment */
if (!(in_comment || in_string)) {
outbuf[outspot++] = '\006';
outbuf[outspot++] = '2';
}
for (index = 0; index < len; index++) {
outbuf[outspot++] = someline[start+index];
}
if (!(in_comment || in_string)) {
outbuf[outspot++] = '\006';
outbuf[outspot++] = '0';
}
break;
case USRIDENT:
case OTHER:
/* Simply output */
for (index = 0; index < len; index++) {
outbuf[outspot++] = someline[start+index];
}
break;
case ENDLINE:
/* Output it */
outbuf[outspot++] = '\n';
break;
}
}
outbuf[outspot] = '\0';
return outbuf;
}
\f
/* Macro to find special delimiters - see table initialization in main */
#define isspecial(c) (specialChar[c])
/* Macro to ram don't care delimiters into an OTHER token */
#define EATDELIM \
while (!isalnum(line[pos]) && !isspecial(line[pos])) pos++; \
*len = pos - *start; \
*token = OTHER;
int get_token(line, start, len, token)
char *line;
int *start, *len, *token;
/*
* Reads a token from 'line'. If all are zero, resets the lexing
* system.
*/
{
static int pos;
static char ident[2048];
char *item;
if ((line == 0) && (start == 0) && (len == 0) && (token == 0)) {
pos = 0;
return 0;
}
*start = pos;
if (isspecial(line[pos])) {
/* One of the special punctuation characters */
if (line[pos] == '\0') {
return 0;
} else if (line[pos] == '\t') {
/* Generate a tab token */
pos++;
*len = 1;
*token = TAB;
} else if (line[pos] == '\n') {
/* End of line */
*len = 1;
*token = ENDLINE;
pos++;
} else if (line[pos] == ' ') {
/* Generate a space token */
while (line[pos] == ' ') pos++;
*len = pos - *start;
*token = SPACE;
} else if (line[pos] == '/') {
/* Possible beginning of comment */
if (line[++pos] == '*') {
/* Start of comment */
*len = 2;
*token = COMBEGIN;
pos++;
} else {
/* Something else */
EATDELIM;
}
} else if (line[pos] == '*') {
/* Could be an end to a comment */
if (line[++pos] == '/') {
/* End of a comment */
*len = 2;
*token = COMEND;
pos++;
} else {
/* Something else */
EATDELIM;
}
} else if (line[pos] == '"') {
/* Possible start or end of string */
if ((pos == 0) ||
(((line[pos-1] == '\'') ? (line[pos+1] != '\'') : 1)
&& (line[pos] != '\\')))
{
*len = 1;
*token = STR;
pos++;
} else {
/* Something else */
pos++;
EATDELIM;
}
}
} else if (isalnum(line[pos])) {
/* Go get an identifier */
do pos++; while (isalnum(line[pos]));
*len = pos - *start;
strncpy(ident, &(line[*start]), *len);
ident[*len] = '\0';
/* Try to look it up */
if (st_lookup(keywords, ident, &item)) {
*token = IDENT;
} else {
*token = USRIDENT;
}
} else {
/* Random delimiters */
pos++;
EATDELIM;
}
return 1;
}
/* Debugging */
print_token(someline, start, len, token)
char *someline;
int start, len, token;
/* Prints out a token */
{
char buffer[1024];
int index;
switch (token) {
case SPACE:
printf("space\n");
break;
case TAB:
printf("tab\n");
break;
/*
* We try to break it by doing this
* many times over.
*/
case COMBEGIN:
printf("start comment\n");
break;
case COMEND:
printf("end comment\n");
break;
case STR:
printf("string\n");
break;
case IDENT:
printf("identifier: '");
for (index = start; index < start+len; index++) {
putchar(someline[index]);
}
printf("'\n");
break;
case USRIDENT:
printf("user identifier: '");
for (index = start; index < start+len; index++) {
putchar(someline[index]);
}
printf("'\n");
break;
case OTHER:
printf("delimiters: I");
for (index = start; index < start+len; index++) {
putchar(someline[index]);
}
printf("I\n");
break;
}
}