home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* */
- /* ------------ Bit-Bucket Software, Co. */
- /* \ 10001101 / Writers and Distributors of */
- /* \ 011110 / Freely Available<tm> Software. */
- /* \ 1011 / */
- /* ------ */
- /* */
- /* (C) Copyright 1987-91, Bit Bucket Software Co., a Delaware Corporation. */
- /* */
- /* */
- /* This module was written by Vince Perriello */
- /* */
- /* */
- /* BinkleyTerm Language Compiler Raw Input Module */
- /* */
- /* */
- /* For complete details of the licensing restrictions, please refer */
- /* to the License agreement, which is published in its entirety in */
- /* the MAKEFILE and BT.C, and also contained in the file LICENSE.250. */
- /* */
- /* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
- /* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
- /* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
- /* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT BIT BUCKET */
- /* SOFTWARE CO. AT ONE OF THE ADDRESSES LISTED BELOW. IN NO EVENT */
- /* SHOULD YOU PROCEED TO USE THIS FILE WITHOUT HAVING ACCEPTED THE */
- /* TERMS OF THE BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER */
- /* AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO. */
- /* */
- /* */
- /* You can contact Bit Bucket Software Co. at any one of the following */
- /* addresses: */
- /* */
- /* Bit Bucket Software Co. FidoNet 1:104/501, 1:343/491 */
- /* P.O. Box 460398 AlterNet 7:491/0 */
- /* Aurora, CO 80046 BBS-Net 86:2030/1 */
- /* Internet f491.n343.z1.fidonet.org */
- /* */
- /* Please feel free to contact us at any time to share your comments about */
- /* our software and/or licensing policies. */
- /* */
- /*--------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #ifdef __TURBOC__
- #include <mem.h>
- #else
- #ifdef _MSC_VER_
- #include <memory.h>
- #else
- #include <string.h>
- #endif
- #endif
-
- #ifdef OS_2
- #define OS_IDENT "OS2"
- #else
- #define OS_IDENT "DOS"
- #endif
-
-
- #include "language.h"
-
- int parse_escapes (char *);
-
- /*
- * get_language - read in BinkleyTerm language source
- *
- * Read lines into table, ignoring blanks and comments
- * Store into a contiguous block of memory with the individual
- * members being referenced by an array of pointers
- * Store number of lines read into pointer_size
- * Store amount of memory used into memory_size
- *
- */
-
- int get_language (char *name_of_file)
- {
- int len; /* length of current string */
- int count_from_file; /* no. of strings in file */
- int file_version; /* version of file */
- char *p, *q; /* miscellaneous pointers */
- char *storage; /* where we're storing now */
- char **load_pointers; /* pointer to pointer array */
- char linebuf[255]; /* biggest line we'll allow */
- FILE *fpt; /* stream pointer */
- int internal_count; /* How many strings we got */
- int total_size; /* How big it all is */
- int error; /* Internal error value */
- int PrdctCode; /* Product Code */
- char *PrdctNm;
- char *PrdctPtr = PrdctMem;
- char *n;
- char *LangStart;
- unsigned int ansival; /* Scanned ANSI keymap value */
-
- internal_count = 0; /* zero out internal counter */
- count_from_file = 0; /* zero out internal counter */
- total_size = 0; /* Initialize storage size */
- error = 0; /* Initialize error value */
-
- load_pointers = pointers; /* Start at the beginning */
- storage = memory; /* A very good place to start*/
-
- /*
- * Open the file now. Then read in the appropriate table. First line of
- * the file contains the number of lines we want Second line through end:
- * ignore if it starts with a ; and store only up to ;
- *
- */
-
- fpt = fopen (name_of_file, "r"); /* Open the file */
- if (fpt == NULL) /* Were we successful? */
- {
- (void) fprintf (stderr, "Can not open input file %s\n", name_of_file);
- return (-1); /* Return failure to caller */
- }
-
- while (fgets (linebuf, 254, fpt) != NULL) /* read a line in */
- {
- p = q = linebuf; /* set up for scan */
-
- /*
- * This label is only hit when a ? line is seen.
- *
- * The format of a ? line is:
- *
- * ?xxx ....
- *
- * where xxx is a 3-character platform identifier. For DOS systems,
- * the identifier is DOS and for OS/2 it is OS2. The text following
- * ?xxx is the same format as any other language file line.
- *
- * When we see a ?, we compare the following string to the ID of our
- * current platform. If it matches, we point p and q at the text following
- * the expression, and (I'm sorry) jump back. If it doesn't match, we throw
- * the line away.
- */
-
- re_cycle:
-
- switch (*p)
- {
-
- case '?':
-
- if (strncmp (++p, OS_IDENT, 3) == 0)
- {
- q = p += 3;
- goto re_cycle;
- }
- break;
-
- case ';': /* Comment */
- case 'C': /* Comment */
-
- break;
-
- case 'L': /* Language Line */
-
- LangStart = ++p;
- (void) parse_escapes (p);
- if ((len = strlen (p)) == 0) /* Is anything there? */
- continue; /* No -- ignore. */
-
- if (!count_from_file)
- {
- (void) sscanf (LangStart,"%d %d",&count_from_file, &file_version);
- if (count_from_file <= pointer_size)
- continue;
-
- (void) fprintf (stderr,
- "Messages in file = %d, Pointer array size = %d\n",
- count_from_file, pointer_size);
- error = -2;
- break;
- }
-
- ++len; /* Allow for the terminator */
- if (((total_size += len) < memory_size) /* Make sure it will fit */
- && (internal_count < pointer_size))
- {
- (void) memcpy (storage, LangStart, len); /* Copy it now (with term)*/
- *load_pointers++ = storage; /* Point to start of string */
- storage += len; /* Move pointer into memory */
- }
-
- ++internal_count; /* bump count */
- break;
-
-
- case 'A': /* ANSI key output map */
-
- (void) sscanf (++p, "%4x", &ansival);
- if (*(p += 4) != ' ')
- break;
- if (*++p == ' ')
- break;
- for (q = p; *q != '\0' && *q != ' '; q++)
- ;
- *q = '\0';
-
- q = AnsiMem + AnsiHdr.PoolSize;
- len = parse_escapes (p);
- *((unsigned int *)q) = ansival;
- q += sizeof (unsigned int);
- *q++ = (char) len;
- strncpy (q, p, len);
- AnsiHdr.ElemCnt++;
- AnsiHdr.PoolSize = (int) ((q += len) - AnsiMem);
- break;
-
- case 'P': /* Product Code */
- /* Format: nnn ProductName */
- PrdctCode = (int) strtol (++p, &PrdctNm, 10);
- while (' ' == *PrdctNm) ++PrdctNm;
- n = PrdctNm + strlen (PrdctNm) - 1;
- while ((PrdctNm <= n) && ((*n == ' ') || (*n == '\n')))
- *n-- = '\0';
-
- if (PrdctCode == -1)
- {
- strcpy (PrdctMem, PrdctNm);
- PrdctPtr = PrdctMem + strlen (PrdctMem) + 1;
- PrdctHdr.PoolSize += strlen (PrdctNm) + 1;
- }
- else if ((0 <= PrdctCode) && (MAX_PRDCTS > PrdctCode))
- {
- switch (strlen (PrdctNm))
- {
- case 0:
- PrdctTbl[PrdctCode] = PrdctMem;
- break;
- default:
- PrdctTbl[PrdctCode] = PrdctPtr;
- strcpy (PrdctPtr, PrdctNm);
- PrdctPtr += strlen (PrdctNm) + 1;
- PrdctHdr.PoolSize += strlen (PrdctNm) + 1;
- break;
- } /* end of switch (strlen (PrdctNm)) */
- } /* end of if (...) */
- break;
-
- case 'T': /* Terminal Mode */
- /* Format: KeyVal KeyXlate */
- (void) sscanf (++p,
- "%x %x",
- &TrmnlAccelTbl[TrmnlAccelCnt].ScanCode,
- &TrmnlAccelTbl[TrmnlAccelCnt].FncIdx);
- ++TrmnlAccelCnt;
- break;
-
- case 'U': /* Unattended Mode */
- /* Format: KeyVal KeyXlate */
- (void) sscanf (++p,
- "%x %x",
- &UnattendedAccelTbl[UnattendedAccelCnt].ScanCode,
- &UnattendedAccelTbl[UnattendedAccelCnt].FncIdx);
- ++UnattendedAccelCnt;
- break;
-
- default:
- break;
- } /* end of switch (...) */
- } /* end of while (...) */
- /*
- * Close the file. Make sure the counts match and that memory size was
- * not exceeded. If so, we have a winner! If not, snort and puke.
- *
- */
-
- (void) fclose (fpt);
-
- if (internal_count > pointer_size) /* Enough pointers? */
- {
- (void) fprintf (stderr,
- "%d messages read exceeds pointer array size of %d\n",
- internal_count, pointer_size);
- error = -3;
- }
-
- if (total_size > memory_size) /* Did we fit? */
- {
- (void) fprintf (stderr,
- "Required memory of %d bytes exceeds %d bytes available\n",
- total_size, memory_size);
- error = -4;
- }
-
- if (count_from_file != internal_count)
- {
- (void) fprintf (stderr,
- "Count of %d lines does not match %d lines actually read\n",
- count_from_file, internal_count);
- error = -5;
- }
-
- if (!error)
- {
- pointer_size = internal_count; /* Store final usage counts */
- memory_size = total_size;
- *load_pointers = NULL; /* Terminate pointer table */
- }
-
- return (error);
- }
-
- int parse_escapes (char *string)
- {
- char c;
- char *p, *q;
- int escape_on = 0;
-
- p = q = string;
-
- while ((c = *p++) != '\0')
- {
- switch (c)
- {
- case ';':
- if (escape_on)
- {
- *q++ = ';';
- --escape_on;
- break;
- }
- /* Otherwise drop into newline code */
-
- case '\n':
- *q = *p = '\0';
- break;
-
- case '\\':
- if (escape_on)
- {
- *q++ = '\\';
- --escape_on;
- }
- else
- ++escape_on;
- break;
-
- case 'n':
- if (escape_on)
- {
- *q++ = '\n';
- --escape_on;
- }
- else
- *q++ = c;
- break;
-
- case 'r':
- if (escape_on)
- {
- *q++ = '\r';
- --escape_on;
- }
- else
- *q++ = c;
- break;
-
- case 'b':
- if (escape_on)
- {
- *q++ = ' ';
- --escape_on;
- }
- else
- *q++ = c;
- break;
-
-
- case 'X':
- case 'x':
- if (escape_on)
- {
- *q++ = (char) strtol (p, &p, 16);
- --escape_on;
- }
- else
- *q++ = c;
- break;
-
- case '0':
- if (escape_on)
- {
- *q++ = (char) strtol (p, &p, 8);
- --escape_on;
- }
- else
- *q++ = c;
- break;
-
- default:
- *q++ = c;
- escape_on = 0;
- break;
- }
- }
- return (int) (q - string);
- }
-
-