From 691bc281883f2f640b5b24770d944b1df798b5e8 Mon Sep 17 00:00:00 2001 From: CSRG Date: Thu, 5 Jun 1986 09:38:05 -0800 Subject: [PATCH] BSD 4_3 development Work on file usr/contrib/X/keycomp/keycomp.c Synthesized-from: CSRG/cd1/4.3 --- usr/contrib/X/keycomp/keycomp.c | 333 ++++++++++++++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 usr/contrib/X/keycomp/keycomp.c diff --git a/usr/contrib/X/keycomp/keycomp.c b/usr/contrib/X/keycomp/keycomp.c new file mode 100644 index 0000000000..e340e5a857 --- /dev/null +++ b/usr/contrib/X/keycomp/keycomp.c @@ -0,0 +1,333 @@ +#include + +/* Copyright 1985, Massachusetts Institute of Technology */ + +#ifndef lint +static char *rcsid_keycomp_c = "$Header: keycomp.c,v 10.4 86/02/01 15:45:26 tony Rel $"; +#endif + +#include +#include +#include "Xkeymap.h" + +#define isnum(c) (((c) >= '0') && ((c) <= '9')) +#define isoctal(c) (((c) >= '0') && ((c) <= '7')) +#define whitespace(c) (((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\0')) + +#define bool int +#define TRUE 1 +#define FALSE 0 + +#define MAXLENGTH 80 + +typedef struct _EscMapEntry { + char from, to;} EscMapEntry; + +typedef enum _ParseError { + e_NoError, + e_NoKeycode, + e_KeycodeTooBig, + e_Not1Or16Items, + e_NotNumber, + e_NumberTooBig, + e_SingleQuoteNotClosed, + e_StringTooLong, + e_DoubleQuoteNotClosed, + e_TooManyCharsBetweenQuotes, + e_Unrecognized + } ParseError; + +#define CT_ESC_ENTRIES 5 +static EscMapEntry EscMap [CT_ESC_ENTRIES] = { + {'n', '\n'}, + {'t', '\t'}, + {'b', '\b'}, + {'r', '\r'}, + {'f', '\f'}} ; + +static KeyMapElt keymap [256]; + +static int column_map[16] = + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + +/* the following variables are global to facilitate error-handling */ +static int line_no = 0, item_no = 0; + +/* the following variables are global to simplify initialization */ +char string_array [16][BUFSIZ]; +char *strings[16]; + +main () + { + char s[BUFSIZ]; + int i, j; + char magic = X_KEYMAP_MAGIC; + /* seek past end of keymap (to beginning of extension) */ + if (isatty(fileno(stdout)) + || (fseek (stdout, sizeof (keymap)+1, 0) == -1)) { + /* "+1" above is because magic number is first byte in file */ + fprintf (stderr, "Couldn't fseek output file\n"); + exit (-1); + } + for (i=0;i<256;i++) + for (j=0;j<16;j++) + keymap[i][j] = UNBOUND; + for (i=0;i<16;i++) + strings[i] = string_array[i]; + while (gets(s)) { + ProcessLine(s); + line_no++; + } + fseek (stdout, 0, 0); + if (!fwrite (&magic, 1, 1, stdout) + || !fwrite (keymap, sizeof(keymap), 1, stdout)) { + fprintf (stderr, "Error writing beginning of output file\n"); + exit (-1); + } + exit(0); + } + +ProcessLine (line) + char *line; + { + int lengths [MAXLENGTH]; + int i=0, items, keycode; + char c; + if (line[0] == '#' || line[0] == '\0') + /* ignore comment lines (starting with '#') and blank lines */ + return; + if (!isnum(line[0])) + Error(e_NoKeycode); /* line must start with key code */ + i++; + while (isnum(line[i])) + i++; + c = line[i]; + line[i] = '\0'; + sscanf (line, (line[0] == '0') ? "%o" : "%d", &keycode); + if (keycode > 255) + Error(e_KeycodeTooBig); + line[i] = c; + items = ScanForItems (&line[i], strings, lengths); + if (items == 1) { + unsigned char value; + int j; + if (lengths[0] == 0) + value = UNBOUND; + else if (lengths[0] > 1 || !SingleCharBound (strings[0][0])) { + value = EXTENSION_BOUND; + AddToExtension (keycode, DontCareMetaBits, strings[0], lengths[0]); + } + else + value = strings[0][0]; + for (j=0;j<16;j++) + keymap[keycode][j] = value; + } + else if (items == 16) { + int j; + for (j=0;j<16;j++) { + unsigned char value; + if (lengths[j] == 0) + value = UNBOUND; + else if (lengths[j] > 1 || !SingleCharBound (strings[j][0])) { + value = EXTENSION_BOUND; + AddToExtension (keycode, column_map[j], strings[j], lengths[j]); + } + else + value = strings[j][0]; + keymap [keycode] [column_map[j]] = value; + } + } + else Error(e_Not1Or16Items); + } + +AddToExtension (keycode, metabits, string, length) + unsigned int keycode, metabits; + char *string; + int length; + { + ExtensionHeader header; + header.keycode = keycode; + header.metabits = metabits; + header.length = length; + if (!fwrite (&header, ExtensionHeaderSize, 1, stdout) || + !fwrite (string, length, 1, stdout)) { + fprintf (stderr, "Error writing extension to output file\n"); + exit (-3); + } + } + +int ScanForItems (line, items, lengths) + char *line; + char *items[16]; + int lengths[16]; + { + int i = 0; + item_no = 0; + while (1) { + + /* skip over leading white space */ + while (whitespace(line[i])) { + if (line[i] == '\0') + return (item_no); + i++; + } + + if (isnum(line[i])) { + char *begin_num = &line[i]; + char c; + + /* find end of number string */ + while (c = line[++i], isnum (c)) + /* this CANNOT be written isnum(line[++i]) because of side + * effect in expression passed to macro */ + ; + + /* temporarily put null character at end of number string */ + c = line[i]; + line[i] = '\0'; + lengths [item_no] = TranslateNumber (begin_num, items[item_no]); + line[i] = c; + } + + else switch (line[i]) { + case '#': + return(item_no); /* rest of line is comment -- ignore it */ + + case 'U': /* "U" means "unbound" */ + lengths [item_no] = 0; + i++; /* increment past the "U" character */ + break; + + case '\'': + case '"': /* something between quotes */ { + char c; + char *begin_quote = &line[i++]; + bool backslash = FALSE; + while (1) + switch (c = line[i++]) { + case '\0': + Error ((*begin_quote == '\'') + ? e_SingleQuoteNotClosed + : e_DoubleQuoteNotClosed); + break; + case '\\': + backslash = !backslash; + break; + default: + if (c == *begin_quote && !backslash) + goto out1; + backslash = FALSE; + break; + } + out1: + c = line [i]; + line[i] = '\0'; + lengths[item_no] = TranslateQuote (begin_quote, items[item_no]); + if ((lengths[item_no] > 1) && (*begin_quote == '\'')) + Error (e_TooManyCharsBetweenQuotes); + line[i] = c; + break; + } + + default: + Error(e_Unrecognized); + break; + + } + + if (line[i] == ',') + i++; /* ignore terminating comma */ + if (!whitespace (line[i])) + Error(e_Unrecognized); + item_no++; + if (item_no == 16) + return (item_no); /* ignore anything on line after 16th char */ + } + + } + +int TranslateNumber (from, to) + char *from, *to; + { + int value; + sscanf (from, (from[0] == '0') ? "%o" : "%d", &value); + if (value > 255) + Error(e_NumberTooBig); + to[0] = value; + return (1); /* length */ + } + + +int TranslateQuote (from, to) + char *from, *to; + { + int from_length = strlen (from); + int i, to_length = 0; + for (i=1;i= MAXLENGTH) + Error(e_StringTooLong); + if (from[i] == '\\') { + if (isoctal (from[i+1])) { + /* backslash followed by octal digits */ + int digits = 1; /* how many successive digits (max 3) */ + int value; + if (isoctal (from[i+2])) + digits += (1 + isoctal (from[i+3])); + sscanf (from+i+1, "%3o", &value); + if (value > 255) + Error(e_NumberTooBig); + to[to_length++] = value; + i += digits; + } + else { + /* backslash followed by non-number */ + int j; + for (j=0;j