home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / file / managers / mc-3.2 / mc-3 / mc-3.2.1 / slang / sltoken.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  7.0 KB  |  350 lines

  1. /*--------------------------------*-C-*---------------------------------*
  2.  * File:    sltoken.c
  3.  *
  4.  * Descript:    ---
  5.  *
  6.  * Requires:    ---
  7.  *
  8.  * Public:    SLexpand_escaped_char ();
  9.  *        SLexpand_escaped_string ();
  10.  *        SLang_extract_token ();
  11.  *        SLang_guess_type ();
  12.  *        SLatoi ();
  13.  *
  14.  * Private:    ---
  15.  *
  16.  * Notes:    ---
  17.  *
  18.  * Copyright (c) 1992, 1995 John E. Davis
  19.  * All rights reserved.
  20.  *
  21.  * You may distribute under the terms of either the GNU General Public
  22.  * License or the Perl Artistic License.
  23. \*----------------------------------------------------------------------*/
  24.  
  25. #include <stdio.h>
  26. #ifndef NO_STDLIB_H
  27. # include <stdlib.h>
  28. #endif
  29. #include <string.h>
  30. #include "slang.h"
  31. #include "_slang.h"
  32.  
  33. /* There are non-zeros at positions "\t %()*,/:;[]{}" */
  34.  
  35. static unsigned char special_chars[256] =
  36. {
  37.    /* 0 */    0,0,0,0,0,0,0,0,    0,'\t',0,0,0,0,0,0,
  38.    /* 16 */    0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,
  39.    /* 32 */    ' ',0,0,0,0,'%',0,0,    '(',')','*',0,',',0,0,'/',
  40.    /* 48 */    0,0,0,0,0,0,0,0,    0,0,':',';',0,0,0,0,
  41.    /* 64 */    0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,
  42.    /* 80 */    0,0,0,0,0,0,0,0,    0,0,0,'[',0,']',0,0,
  43.    /* 96 */    0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,
  44.    /* 112 */    0,0,0,0,0,0,0,0,    0,0,0,'{',0,'}',0,0,
  45.    /* 8-bit characters */
  46.    /* 128 */    0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,
  47.    /* 144 */    0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,
  48.    /* 160 */    0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,
  49.    /* 176 */    0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,
  50.    /* 192 */    0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,
  51.    /* 208 */    0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,
  52.    /* 224 */    0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,
  53.    /* 240 */    0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0
  54. };
  55.  
  56. char *SLexpand_escaped_char(char *p, char *ch)
  57. {
  58.    int i = 0;
  59.    int max = 0, num, base = 0;
  60.    char ch1;
  61.    
  62.    ch1 = *p++;
  63.    
  64.    switch (ch1)
  65.      {
  66.       default: num = ch1; break;
  67.       case 'n': num = '\n'; break;
  68.       case 't': num = '\t'; break;
  69.       case 'v': num = '\v'; break;
  70.       case 'b': num = '\b'; break;
  71.       case 'r': num = '\r'; break;
  72.       case 'f': num = '\f'; break;
  73.       case 'E': case 'e': num = 27; break;
  74.       case 'a': num = 7; 
  75.     break;
  76.     
  77.     /* octal */
  78.       case '0': case '1': case '2': case '3': 
  79.       case '4': case '5': case '6': case '7': 
  80.     max = '7'; 
  81.     base = 8; i = 2; num = ch1 - '0';
  82.     break;
  83.     
  84.       case 'd':                   /* decimal -- S-Lang extension */
  85.     base = 10; 
  86.     i = 3;
  87.     max = '9';
  88.     num = 0;
  89.     break;
  90.     
  91.       case 'x':                   /* hex */
  92.     base = 16;
  93.     max = '9';
  94.     i = 2;
  95.     num = 0;
  96.     break;
  97.      }
  98.    
  99.    while (i--)
  100.      {
  101.     ch1 = *p;
  102.     
  103.     if ((ch1 <= max) && (ch1 >= '0'))
  104.       {
  105.          num = base * num + (ch1 - '0');
  106.       }
  107.     else if (base == 16)
  108.       {
  109.          ch1 |= 0x20;
  110.          if ((ch1 < 'a') || ((ch1 > 'f'))) break;
  111.          num = base * num + 10 + (ch1 - 'a');
  112.       }
  113.     else break;
  114.     p++;
  115.      }
  116.    
  117.    *ch = (char) num;
  118.    return p;
  119. }
  120.  
  121. void SLexpand_escaped_string (register char *s, register char *t, 
  122.                   register char *tmax)
  123. {
  124.    char ch;
  125.    
  126.    while (t < tmax)
  127.      {
  128.     ch = *t++;
  129.     if (ch == '\\')
  130.       {
  131.          t = SLexpand_escaped_char (t, &ch);
  132.       }
  133.     *s++ = ch;
  134.      }
  135.    *s = 0;
  136. }
  137.  
  138.  
  139. int SLang_extract_token (char **linep, char *word_parm, int byte_comp)
  140. {
  141.    register char ch, *line, *word = word_parm;
  142.    int string;
  143.    char ch1;
  144.    char *word_max;
  145.    
  146.    word_max = word + 250;
  147.    
  148.     line = *linep;
  149.  
  150.     /* skip white space */
  151.     while (ch = *line++, (ch == ' ') || (ch == '\t'));
  152.  
  153.     if ((!ch) || (ch == '\n'))
  154.       {
  155.      *linep = line;
  156.      return(0);
  157.       }
  158.  
  159.    *word++ = ch;
  160.    
  161.    /* Look for -something and rule out --something and -= something */
  162.    if ((ch == '-') && 
  163.        (*line != '-') && (*line != '=') && ((*line > '9') || (*line < '0')))
  164.      {
  165.     *word = 0;
  166.     *linep = line;
  167.     return 1;
  168.      }
  169.    
  170.        
  171.    if (ch == '"') string = 1; else string = 0;
  172.    if (ch == '\'')
  173.      {
  174.     if ((ch = *line++) != 0)
  175.       {
  176.          if (ch == '\\') 
  177.            {
  178.           line = SLexpand_escaped_char(line, &ch1);
  179.           ch = ch1;
  180.            }
  181.          if (*line++ == '\'')
  182.            {
  183.           --word;
  184.           sprintf(word, "%d", (int) ((unsigned char) ch));
  185.           word += strlen (word);  ch = '\'';
  186.            }
  187.          else SLang_Error = SYNTAX_ERROR;
  188.       }
  189.     else SLang_Error = SYNTAX_ERROR;
  190.      }
  191.    else  if (!special_chars[(unsigned char) ch])
  192.      {
  193.     while (ch = *line++, 
  194.            (ch > '"') || 
  195.            ((ch != '\n') && (ch != 0) && (ch != '"')))
  196.       {
  197.          if (string)
  198.            {
  199.           if (ch == '\\')
  200.             {
  201.                ch = *line++;
  202.                if ((ch == 0) || (ch == '\n')) break;
  203.                if (byte_comp) *word++ = '\\';
  204.                else 
  205.              {
  206.                 line = SLexpand_escaped_char(line - 1, &ch1);
  207.                 ch = ch1;
  208.              }
  209.             }
  210.            }
  211.          else if (special_chars[(unsigned char) ch])
  212.            {
  213.           line--;
  214.           break;
  215.            }
  216.          
  217.          *word++ = ch;
  218.          if (word > word_max)
  219.            {
  220.           SLang_doerror ("Token to large.");
  221.           break;
  222.            }
  223.       }
  224.      }
  225.    
  226.    if ((!ch) || (ch == '\n')) line--;
  227.    if ((ch == '"') && string) *word++ = '"'; else if (string) SLang_Error = SYNTAX_ERROR;
  228.    *word = 0;
  229.    *linep = line;
  230.    /* massage variable-- and ++ into --variable, etc... */
  231.    if (((int) (word - word_parm) > 2)
  232.        && (ch = *(word - 1), (ch == '+') || (ch == '-'))
  233.        && (ch == *(word - 2)))
  234.      {
  235.     word--;
  236.     while (word >= word_parm + 2)
  237.       {
  238.          *word = *(word - 2);
  239.          word--;
  240.       }
  241.     *word-- = ch;
  242.     *word-- = ch;
  243.      }
  244.    return(1);
  245. }
  246.  
  247.  
  248. int SLang_guess_type (char *t)
  249. {
  250.    char *p;
  251.    register char ch;
  252.  
  253.    if (*t == '-') t++;
  254.    p = t;
  255. #ifdef FLOAT_TYPE
  256.    if (*p != '.') 
  257.      {
  258. #endif
  259.     while ((*p >= '0') && (*p <= '9')) p++;
  260.     if (t == p) return(STRING_TYPE);
  261.     if ((*p == 'x') && (p == t + 1))   /* 0x?? */
  262.       {
  263.          p++;
  264.          while (ch = *p, 
  265.             ((ch >= '0') && (ch <= '9'))
  266.             || (((ch | 0x20) >= 'a') && ((ch | 0x20) <= 'f'))) p++;
  267.       }
  268.     if (*p == 0) return(INT_TYPE);
  269. #ifndef FLOAT_TYPE
  270.     return(STRING_TYPE);
  271. #else
  272.      }
  273.    
  274.    /* now down to float case */
  275.    if (*p == '.')
  276.      {
  277.     p++;
  278.     while ((*p >= '0') && (*p <= '9')) p++;
  279.      }
  280.    if (*p == 0) return(FLOAT_TYPE);
  281.    if ((*p != 'e') && (*p != 'E')) return(STRING_TYPE);
  282.    p++;
  283.    if (*p == '-') p++;
  284.    while ((*p >= '0') && (*p <= '9')) p++;
  285.    if (*p != 0) return(STRING_TYPE); else return(FLOAT_TYPE);
  286. #endif
  287. }
  288.  
  289. int SLatoi (unsigned char *s)
  290. {
  291.    register unsigned char ch;
  292.    register unsigned int value;
  293.    register int base;
  294.    
  295.    if (*s != '0') return atoi((char *) s);
  296.  
  297.    /* look for 'x' which indicates hex */
  298.    s++;
  299.    if ((*s | 0x20) == 'x') 
  300.      {
  301.     base = 16;
  302.     s++;
  303.     if (*s == 0) 
  304.       {
  305.          SLang_Error = SYNTAX_ERROR;
  306.          return -1;
  307.       }
  308.      }
  309.    else base = 8;
  310.    
  311.    
  312.    value = 0;
  313.    while ((ch = *s++) != 0)
  314.      {
  315.     char ch1 = ch | 0x20;
  316.     switch (ch1)
  317.       {
  318.        default:
  319.          SLang_Error = SYNTAX_ERROR;
  320.          break;
  321.        case '8':
  322.        case '9':
  323.          if (base != 16) SLang_Error = SYNTAX_ERROR;
  324.          /* drop */
  325.        case '0':
  326.        case '1':
  327.        case '2':
  328.        case '3':
  329.        case '4':
  330.        case '5':
  331.        case '6':
  332.        case '7':
  333.          ch1 -= '0';
  334.          break;
  335.          
  336.        case 'a':
  337.        case 'b':
  338.        case 'c':
  339.        case 'd':
  340.        case 'e':
  341.        case 'f':
  342.          if (base != 16) SLang_Error = SYNTAX_ERROR;
  343.          ch1 = (ch1 - 'a') + 10;
  344.          break;
  345.       }
  346.     value = value * base + ch1;
  347.      }
  348.    return (int) value;
  349. }
  350.