home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1996 October / PCO_10.ISO / filesbbs / bsrc_260.arj / SRC.ZIP / get_lang.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-23  |  12.1 KB  |  432 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*              (C) Copyright 1987-96, Bit Bucket Software Co.              */
  11. /*                                                                          */
  12. /*               This module was written by Vince Perriello                 */
  13. /*                                                                          */
  14. /*             BinkleyTerm Language Compiler Raw Input Module               */
  15. /*                                                                          */
  16. /*                                                                          */
  17. /*    For complete  details  of the licensing restrictions, please refer    */
  18. /*    to the License  agreement,  which  is published in its entirety in    */
  19. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.260.    */
  20. /*                                                                          */
  21. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  22. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  23. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  24. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  25. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  26. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  27. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  28. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  29. /*                                                                          */
  30. /*                                                                          */
  31. /* You can contact Bit Bucket Software Co. at any one of the following      */
  32. /* addresses:                                                               */
  33. /*                                                                          */
  34. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
  35. /* P.O. Box 460398                AlterNet 7:42/1491                        */
  36. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  37. /*                                Internet f491.n343.z1.fidonet.org         */
  38. /*                                                                          */
  39. /* Please feel free to contact us at any time to share your comments about  */
  40. /* our software and/or licensing policies.                                  */
  41. /*                                                                          */
  42. /*--------------------------------------------------------------------------*/
  43.  
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47. #ifdef __TURBOC__
  48. #include <mem.h>
  49. #else
  50. #ifdef _MSC_VER_
  51. #include <memory.h>
  52. #else
  53. #include <string.h>
  54. #endif
  55. #endif
  56.  
  57. #define DOS16
  58.  
  59. #ifdef OS_2
  60. #define OS_IDENT "OS2"
  61. #undef DOS16
  62. #endif
  63.  
  64. #ifdef _WIN32
  65. #define OS_IDENT "WNT"
  66. #undef DOS16
  67. #endif
  68.  
  69. #ifdef DOS16
  70. #define OS_IDENT "DOS"
  71. #endif
  72.  
  73. #include "language.h"
  74.  
  75. int parse_escapes (char *);
  76.  
  77. /*
  78.  *  get_language - read in BinkleyTerm language source
  79.  *
  80.  * Read lines into table, ignoring blanks and comments
  81.  * Store into a contiguous block of memory with the individual
  82.  *     members being referenced by an array of pointers
  83.  * Store number of lines read into pointer_size
  84.  * Store amount of memory used into memory_size
  85.  *
  86.  */
  87.  
  88. int 
  89. get_language (char *name_of_file)
  90. {
  91.     int len;                    /* length of current string  */
  92.     int count_from_file;        /* no. of strings in file    */
  93.     int file_version;            /* version of file           */
  94.     char *p, *q;                /* miscellaneous pointers    */
  95.     char *storage;                /* where we're storing now   */
  96.     char **load_pointers;        /* pointer to pointer array  */
  97.     char linebuf[255];            /* biggest line we'll allow  */
  98.     FILE *fpt;                    /* stream pointer            */
  99.     int internal_count;            /* How many strings we got   */
  100.     int total_size;                /* How big it all is         */
  101.     int error;                    /* Internal error value      */
  102.     int PrdctCode;                /* Product Code              */
  103.     char *PrdctNm;
  104.     char *PrdctPtr = PrdctMem;
  105.     char *n;
  106.     char *LangStart;
  107.     unsigned int ansival;        /* Scanned ANSI keymap value */
  108.  
  109.     internal_count = 0;            /* zero out internal counter */
  110.     count_from_file = 0;        /* zero out internal counter */
  111.     total_size = 0;                /* Initialize storage size   */
  112.     error = 0;                    /* Initialize error value    */
  113.  
  114.     load_pointers = pointers;    /* Start at the beginning    */
  115.     storage = memory;            /* A very good place to start*/
  116.  
  117.     /*
  118.      * Open the file now. Then read in the appropriate table. First line of
  119.      * the file contains the number of lines we want Second line through end:
  120.      * ignore if it starts with a ; and store only up to ;
  121.      *
  122.      */
  123.  
  124.     fpt = fopen (name_of_file, "r");    /* Open the file             */
  125.     if (fpt == NULL)                    /* Were we successful?       */
  126.     {
  127.         (void) fprintf (stderr, "Can not open input file %s\n", name_of_file);
  128.         return (-1);                    /* Return failure to caller  */
  129.     }
  130.  
  131.     while (fgets (linebuf, 254, fpt) != NULL)    /* read a line in            */
  132.     {
  133.         p = q = linebuf;                /* set up for scan           */
  134.  
  135. /*
  136.  * This label is only hit when a ? line is seen.
  137.  *
  138.  * The format of a ? line is:
  139.  *
  140.  *        ?xxx ....
  141.  *
  142.  * where xxx is a 3-character platform identifier. For DOS systems,
  143.  * the identifier is DOS and for OS/2 it is OS2. The text following
  144.  * ?xxx is the same format as any other language file line.
  145.  *
  146.  * When we see a ?, we compare the following string to the ID of our
  147.  * current platform. If it matches, we point p and q at the text following
  148.  * the expression, and (I'm sorry) jump back. If it doesn't match, we throw
  149.  * the line away.
  150.  */
  151.  
  152. re_cycle:
  153.  
  154.         switch (*p)
  155.         {
  156.  
  157.         case '?':
  158.  
  159.             if (strncmp (++p, OS_IDENT, 3) == 0)
  160.             {
  161.                 q = p += 3;
  162.                 goto re_cycle;
  163.             }
  164.             break;
  165.  
  166.         case ';':                            /* Comment                   */
  167.         case 'C':                            /* Comment                   */
  168.  
  169.             break;
  170.  
  171.         case 'L':                            /* Language Line             */
  172.  
  173.             LangStart = ++p;
  174.             (void) parse_escapes (p);
  175.             if ((len = strlen (p)) == 0)    /* Is anything there?        */
  176.                 continue;                    /* No -- ignore.             */
  177.  
  178.             if (!count_from_file)
  179.             {
  180.                 (void) sscanf (LangStart, "%d %d", &count_from_file, &file_version);
  181.                 if (count_from_file <= pointer_size)
  182.                     continue;
  183.  
  184.                 (void) fprintf (stderr,
  185.                     "Messages in file = %d, Pointer array size = %d\n",
  186.                     count_from_file, pointer_size);
  187.                 error = -2;
  188.                 break;
  189.             }
  190.  
  191.             ++len;                            /* Allow for the terminator  */
  192.             if (((total_size += len) < memory_size)    /* Make sure it fits */
  193.                 && (internal_count < pointer_size))
  194.             {
  195.                 (void) memcpy (storage, LangStart, len);    /* Copy it   */
  196.                 *load_pointers++ = storage;    /* Point to start of string  */
  197.                 storage += len;                /* Move pointer into memory  */
  198.             }
  199.  
  200.             ++internal_count;                /* bump count */
  201.             break;
  202.  
  203.         case 'A':                            /* ANSI key output map       */
  204.  
  205.             (void) sscanf (++p, "%4x", &ansival);
  206.             if (*(p += 4) != ' ')
  207.                 break;
  208.             if (*++p == ' ')
  209.                 break;
  210.             for (q = p; *q != '\0' && *q != ' '; q++)
  211.                 ;
  212.             *q = '\0';
  213.  
  214.             q = AnsiMem + AnsiHdr.PoolSize;
  215.             len = parse_escapes (p);
  216.             *((unsigned int *) q) = ansival;
  217.             q += sizeof (unsigned int);
  218.  
  219.             *q++ = (char) len;
  220.             strncpy (q, p, len);
  221.             AnsiHdr.ElemCnt++;
  222.             AnsiHdr.PoolSize = (int) ((q += len) - AnsiMem);
  223.             break;
  224.  
  225.         case 'P':                            /* Product Code              */
  226.                                             /* Format: nnn ProductName   */
  227.             PrdctCode = (int) strtol (++p, &PrdctNm, 10);
  228.             while (' ' == *PrdctNm)
  229.                 ++PrdctNm;
  230.             n = PrdctNm + strlen (PrdctNm) - 1;
  231.             while ((PrdctNm <= n) && ((*n == ' ') || (*n == '\n')))
  232.                 *n-- = '\0';
  233.  
  234.             if (PrdctCode == -1)
  235.             {
  236.                 strcpy (PrdctMem, PrdctNm);
  237.                 PrdctPtr = PrdctMem + strlen (PrdctMem) + 1;
  238.                 PrdctHdr.PoolSize += strlen (PrdctNm) + 1;
  239.             }
  240.             else if ((0 <= PrdctCode) && (MAX_PRDCTS > PrdctCode))
  241.             {
  242.                 switch (strlen (PrdctNm))
  243.                 {
  244.                 case 0:
  245.                     PrdctTbl[PrdctCode] = PrdctMem;
  246.                     break;
  247.                 default:
  248.                     PrdctTbl[PrdctCode] = PrdctPtr;
  249.                     strcpy (PrdctPtr, PrdctNm);
  250.                     PrdctPtr += strlen (PrdctNm) + 1;
  251.                     PrdctHdr.PoolSize += strlen (PrdctNm) + 1;
  252.                     break;
  253.                 }                    /* end of switch (strlen (PrdctNm))   */
  254.             }                        /* end of if (...)                    */
  255.             break;
  256.  
  257.         case 'T':                    /* Terminal Mode                      */
  258.                                     /* Format: KeyVal KeyXlate            */
  259.             {
  260.                 int ScanCode, FncIdx;
  261.  
  262.                 (void) sscanf (++p, "%4x %4x", &ScanCode, &FncIdx);
  263.                 TrmnlAccelTbl[TrmnlAccelCnt].ScanCode = (short) ScanCode;
  264.                 TrmnlAccelTbl[TrmnlAccelCnt].FncIdx = (short) FncIdx;
  265.                 ++TrmnlAccelCnt;
  266.             }
  267.             break;
  268.  
  269.         case 'U':                    /* Unattended Mode                    */
  270.                                     /* Format: KeyVal KeyXlate            */
  271.             {
  272.                 int ScanCode, FncIdx;
  273.  
  274.                 (void) sscanf (++p, "%4x %4x", &ScanCode, &FncIdx);
  275.                 UnattendedAccelTbl[UnattendedAccelCnt].ScanCode = (short) ScanCode;
  276.                 UnattendedAccelTbl[UnattendedAccelCnt].FncIdx = (short) FncIdx;
  277.                 ++UnattendedAccelCnt;
  278.             }
  279.             break;
  280.  
  281.         default:
  282.             break;
  283.         }                            /* end of switch (...)                */
  284.     }                                /* end of while (...)                 */
  285.     /*
  286.      * Close the file. Make sure the counts match and that memory size was
  287.      * not exceeded. If so, we have a winner! If not, snort and puke.
  288.      *
  289.      */
  290.  
  291.     (void) fclose (fpt);
  292.  
  293.     if (internal_count > pointer_size)        /* Enough pointers?          */
  294.     {
  295.         (void) fprintf (stderr,
  296.             "%d messages read exceeds pointer array size of %d\n",
  297.             internal_count, pointer_size);
  298.         error = -3;
  299.     }
  300.  
  301.     if (total_size > memory_size)            /* Did we fit?               */
  302.     {
  303.         (void) fprintf (stderr,
  304.             "Required memory of %d bytes exceeds %d bytes available\n",
  305.             total_size, memory_size);
  306.         error = -4;
  307.     }
  308.  
  309.     if (count_from_file != internal_count)
  310.     {
  311.         (void) fprintf (stderr,
  312.             "Count of %d lines does not match %d lines actually read\n",
  313.             count_from_file, internal_count);
  314.         error = -5;
  315.     }
  316.  
  317.     if (!error)
  318.     {
  319.         pointer_size = internal_count;        /* Store final usage counts  */
  320.         memory_size = total_size;
  321.         *load_pointers = NULL;                /* Terminate pointer table   */
  322.     }
  323.  
  324.     return (error);
  325. }
  326.  
  327. int 
  328. parse_escapes (char *string)
  329. {
  330.     char c;
  331.     char *p, *q;
  332.     int escape_on = 0;
  333.  
  334.     p = q = string;
  335.  
  336.     while ((c = *p++) != '\0')
  337.     {
  338.         switch (c)
  339.         {
  340.         case ';':
  341.             if (escape_on)
  342.             {
  343.                 *q++ = ';';
  344.                 --escape_on;
  345.                 break;
  346.             }
  347.             /* Otherwise drop into newline code */
  348.  
  349.         case '\n':
  350.             *q = *p = '\0';
  351.             break;
  352.  
  353.         case '\\':
  354.             if (escape_on)
  355.             {
  356.                 *q++ = '\\';
  357.                 --escape_on;
  358.             }
  359.             else
  360.                 ++escape_on;
  361.             break;
  362.  
  363.         case 'n':
  364.             if (escape_on)
  365.             {
  366.                 *q++ = '\n';
  367.                 --escape_on;
  368.             }
  369.             else
  370.                 *q++ = c;
  371.             break;
  372.  
  373.         case 'r':
  374.             if (escape_on)
  375.             {
  376.                 *q++ = '\r';
  377.                 --escape_on;
  378.             }
  379.             else
  380.                 *q++ = c;
  381.             break;
  382.  
  383.         case 'b':
  384.             if (escape_on)
  385.             {
  386.                 *q++ = ' ';
  387.                 --escape_on;
  388.             }
  389.             else
  390.                 *q++ = c;
  391.             break;
  392.  
  393.         case 'X':
  394.         case 'x':
  395.             if (escape_on)
  396.             {
  397.                 *q++ = (char) strtol (p, &p, 16);
  398.                 --escape_on;
  399.             }
  400.             else
  401.                 *q++ = c;
  402.             break;
  403.  
  404.         case '0':
  405.             if (escape_on)
  406.             {
  407.                 *q++ = (char) strtol (p, &p, 8);
  408.                 --escape_on;
  409.             }
  410.             else
  411.                 *q++ = c;
  412.             break;
  413.  
  414.         case 's':
  415.             if (escape_on)
  416.             {
  417.                 *q++ = ' ';
  418.                 --escape_on;
  419.             }
  420.             else
  421.                 *q++ = c;
  422.             break;
  423.  
  424.         default:
  425.             *q++ = c;
  426.             escape_on = 0;
  427.             break;
  428.         }
  429.     }
  430.     return (int) (q - string);
  431. }
  432.