home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
bbs_mail
/
bsrc_250.arj
/
GET_LANG.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-15
|
16KB
|
408 lines
/*--------------------------------------------------------------------------*/
/* */
/* */
/* ------------ 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);
}