sltoken.c 7.0 KB

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