parse.c 18 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078
  1. /******************************************************************************
  2. * This file is part of TinTin++ *
  3. * *
  4. * Copyright 2004-2019 Igor van den Hoven *
  5. * *
  6. * TinTin++ is free software; you can redistribute it and/or modify *
  7. * it under the terms of the GNU General Public License as published by *
  8. * the Free Software Foundation; either version 3 of the License, or *
  9. * (at your option) any later version. *
  10. * *
  11. * This program is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * *
  17. * You should have received a copy of the GNU General Public License *
  18. * along with TinTin++. If not, see https://www.gnu.org/licenses. *
  19. ******************************************************************************/
  20. /******************************************************************************
  21. * (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t *
  22. * *
  23. * coded by Peter Unold 1992 *
  24. * recoded by Igor van den Hoven 2005 *
  25. ******************************************************************************/
  26. #include "tintin.h"
  27. // whether str1 is an abbreviation of str2
  28. int case_table[256] =
  29. {
  30. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  31. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  32. 95, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  33. 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  34. 64,
  35. 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
  36. 91, 92, 93, 94,
  37. 95, 96,
  38. 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
  39. 123, 124, 125, 126, 127,
  40. 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
  41. 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
  42. 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
  43. 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
  44. 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
  45. 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
  46. 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
  47. 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
  48. };
  49. int is_abbrev(char *str1, char *str2)
  50. {
  51. char *str3 = gtd->is_result;
  52. if (*str1 == 0)
  53. {
  54. return false;
  55. }
  56. if (*str2 == 0)
  57. {
  58. tintin_printf2(gtd->ses, "\e[1;31mis_abbrev(%s,%s)", str1, str2);
  59. dump_stack();
  60. return false;
  61. }
  62. while (true)
  63. {
  64. if (*str1 == 0)
  65. {
  66. strcpy(str3, str2);
  67. return true;
  68. }
  69. if (case_table[(int) *str1] != case_table[(int) *str2])
  70. {
  71. return false;
  72. }
  73. str1++;
  74. *str3++ = *str2++;
  75. }
  76. }
  77. void filename_string(char *input, char *output)
  78. {
  79. while (*input)
  80. {
  81. *output++ = (char) case_table[(int) *input++];
  82. }
  83. *output = 0;
  84. }
  85. int is_suffix(char *str1, char *str2)
  86. {
  87. int len1, len2;
  88. len1 = strlen(str1);
  89. len2 = strlen(str2);
  90. if (len1 >= len2)
  91. {
  92. if (is_abbrev(str1 + len1 - len2, str2))
  93. {
  94. return TRUE;
  95. }
  96. }
  97. return FALSE;
  98. }
  99. struct session *parse_input(struct session *ses, char *input)
  100. {
  101. char *line;
  102. push_call("parse_input(%s,%s)",ses->name,input);
  103. if (*input == 0)
  104. {
  105. write_mud(ses, input, SUB_EOL);
  106. pop_call();
  107. return ses;
  108. }
  109. if (VERBATIM(ses))
  110. {
  111. line = (char *) malloc(BUFFER_SIZE);
  112. strcpy(line, input);
  113. if (check_all_aliases(ses, line))
  114. {
  115. ses = script_driver(ses, LIST_ALIAS, line);
  116. }
  117. else
  118. {
  119. write_mud(ses, line, SUB_EOL);
  120. }
  121. free(line);
  122. pop_call();
  123. return ses;
  124. }
  125. if (*input == gtd->verbatim_char)
  126. {
  127. write_mud(ses, input+1, SUB_EOL);
  128. pop_call();
  129. return ses;
  130. }
  131. line = (char *) malloc(BUFFER_SIZE);
  132. while (*input)
  133. {
  134. input = space_out(input);
  135. input = get_arg_all(ses, input, line, GET_ONE);
  136. if (parse_command(ses, line))
  137. {
  138. ses = script_driver(ses, LIST_COMMAND, line);
  139. }
  140. else if (check_all_aliases(ses, line))
  141. {
  142. ses = script_driver(ses, LIST_ALIAS, line);
  143. }
  144. else if (HAS_BIT(ses->flags, SES_FLAG_SPEEDWALK) && is_speedwalk(ses, line))
  145. {
  146. process_speedwalk(ses, line);
  147. }
  148. else
  149. {
  150. write_mud(ses, line, SUB_VAR|SUB_FUN|SUB_ESC|SUB_EOL);
  151. }
  152. if (*input == COMMAND_SEPARATOR)
  153. {
  154. input++;
  155. }
  156. }
  157. free(line);
  158. pop_call();
  159. return ses;
  160. }
  161. /*
  162. Deal with variables and functions used as commands.
  163. */
  164. struct session *parse_command(struct session *ses, char *input)
  165. {
  166. char *arg, line[BUFFER_SIZE], cmd1[BUFFER_SIZE], cmd2[BUFFER_SIZE];
  167. push_call("parse_command(%p,%p)",ses,input);
  168. arg = get_arg_stop_spaces(ses, input, cmd1, GET_ONE);
  169. substitute(ses, cmd1, cmd2, SUB_VAR|SUB_FUN);
  170. if (!strcmp(cmd1, cmd2))
  171. {
  172. pop_call();
  173. return NULL;
  174. }
  175. sprintf(line, "%s%s%s", cmd2, *arg ? " " : "", arg);
  176. strcpy(input, line);
  177. pop_call();
  178. return ses;
  179. }
  180. char *substitute_speedwalk(struct session *ses, char *input, char *output)
  181. {
  182. char num[NUMBER_SIZE], name[BUFFER_SIZE], *pti, *ptn, *pto;
  183. int cnt, max;
  184. pti = input;
  185. pto = output;
  186. while (*pti && pto - output < INPUT_SIZE)
  187. {
  188. while (isspace(*pti))
  189. {
  190. pti++;
  191. }
  192. if (isdigit(*pti))
  193. {
  194. ptn = num;
  195. while (isdigit(*pti))
  196. {
  197. if (ptn - num < 4)
  198. {
  199. *ptn++ = *pti++;
  200. }
  201. else
  202. {
  203. pti++;
  204. }
  205. }
  206. *ptn = 0;
  207. max = atoi(num);
  208. }
  209. else
  210. {
  211. max = 1;
  212. }
  213. pti = get_arg_stop_digits(ses, pti, name, GET_ONE);
  214. if (*name == 0)
  215. {
  216. break;
  217. }
  218. for (cnt = 0 ; cnt < max ; cnt++)
  219. {
  220. if (output != pto)
  221. {
  222. *pto++ = COMMAND_SEPARATOR;
  223. }
  224. pto += sprintf(pto, "%s", name);
  225. }
  226. if (*pti == COMMAND_SEPARATOR)
  227. {
  228. pti++;
  229. }
  230. }
  231. *pto = 0;
  232. return output;
  233. }
  234. int is_speedwalk(struct session *ses, char *input)
  235. {
  236. int digit = 0, flag = FALSE;
  237. while (*input)
  238. {
  239. switch (*input)
  240. {
  241. case 'n':
  242. case 'e':
  243. case 's':
  244. case 'w':
  245. case 'u':
  246. case 'd':
  247. if (digit > 3)
  248. {
  249. return FALSE;
  250. }
  251. digit = 0;
  252. flag = TRUE;
  253. break;
  254. case '0':
  255. case '1':
  256. case '2':
  257. case '3':
  258. case '4':
  259. case '5':
  260. case '6':
  261. case '7':
  262. case '8':
  263. case '9':
  264. digit++;
  265. flag = FALSE;
  266. break;
  267. default:
  268. return FALSE;
  269. }
  270. input++;
  271. }
  272. return flag;
  273. }
  274. void process_speedwalk(struct session *ses, char *input)
  275. {
  276. char dir[2];
  277. int cnt, i;
  278. for (dir[1] = 0 ; *input ; input++)
  279. {
  280. if (isdigit((int) *input))
  281. {
  282. sscanf(input, "%d%c", &cnt, dir);
  283. for (i = 0 ; i < cnt ; i++)
  284. {
  285. write_mud(ses, dir, SUB_EOL);
  286. }
  287. while (*input != dir[0])
  288. {
  289. input++;
  290. }
  291. }
  292. else
  293. {
  294. dir[0] = *input;
  295. write_mud(ses, dir, SUB_EOL);
  296. }
  297. }
  298. return;
  299. }
  300. /*
  301. Deals with all # stuff
  302. */
  303. struct session *parse_tintin_command(struct session *ses, char *input)
  304. {
  305. char line[BUFFER_SIZE];
  306. struct session *sesptr;
  307. input = get_arg_stop_spaces(ses, input, line, GET_ONE);
  308. substitute(ses, line, line, SUB_VAR|SUB_FUN);
  309. if (is_number(line))
  310. {
  311. int cnt = atoi(line);
  312. input = get_arg_in_braces(ses, input, line, GET_ALL);
  313. while (cnt-- > 0)
  314. {
  315. ses = script_driver(ses, LIST_COMMAND, line);
  316. }
  317. return ses;
  318. }
  319. sesptr = find_session(line);
  320. if (sesptr)
  321. {
  322. if (*input)
  323. {
  324. input = get_arg_in_braces(ses, input, line, GET_ALL);
  325. substitute(ses, line, line, SUB_VAR|SUB_FUN);
  326. script_driver(sesptr, LIST_COMMAND, line);
  327. return ses;
  328. }
  329. else
  330. {
  331. return activate_session(sesptr);
  332. }
  333. }
  334. tintin_printf2(ses, "#ERROR: #UNKNOWN TINTIN-COMMAND '%s'.", line);
  335. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 1, "UNKNOWN COMMAND", line);
  336. return ses;
  337. }
  338. int cnt_arg_all(struct session *ses, char *string, int flag)
  339. {
  340. char *arg, tmp[BUFFER_SIZE];
  341. int cnt;
  342. arg = string;
  343. cnt = 0;
  344. while (*arg)
  345. {
  346. cnt++;
  347. arg = get_arg_in_braces(ses, arg, tmp, flag);
  348. if (*arg == COMMAND_SEPARATOR)
  349. {
  350. arg++;
  351. }
  352. }
  353. return cnt;
  354. }
  355. /*
  356. get all arguments - only check for unescaped command separators
  357. */
  358. char *get_arg_all(struct session *ses, char *string, char *result, int verbatim)
  359. {
  360. char *pto, *pti;
  361. int skip, nest = 0;
  362. pti = string;
  363. pto = result;
  364. if (*pti == gtd->verbatim_char)
  365. {
  366. while (*pti)
  367. {
  368. *pto++ = *pti++;
  369. }
  370. *pto = 0;
  371. return pti;
  372. }
  373. while (*pti)
  374. {
  375. if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
  376. {
  377. *pto++ = *pti++;
  378. *pto++ = *pti++;
  379. continue;
  380. }
  381. skip = find_secure_color_code(pti);
  382. if (skip)
  383. {
  384. while (skip--)
  385. {
  386. *pto++ = *pti++;
  387. }
  388. continue;
  389. }
  390. if (*pti == '\\' && pti[1] == COMMAND_SEPARATOR)
  391. {
  392. *pto++ = *pti++;
  393. }
  394. else if (*pti == COMMAND_SEPARATOR && nest == 0 && !verbatim)
  395. {
  396. break;
  397. }
  398. else if (*pti == DEFAULT_OPEN)
  399. {
  400. nest++;
  401. }
  402. else if (*pti == DEFAULT_CLOSE)
  403. {
  404. nest--;
  405. }
  406. *pto++ = *pti++;
  407. if (pto - result >= BUFFER_SIZE - 3)
  408. {
  409. tintin_printf2(ses, "#ERROR: INPUT BUFFER OVERFLOW.");
  410. pto--;
  411. break;
  412. }
  413. }
  414. *pto = '\0';
  415. return pti;
  416. }
  417. /*
  418. Braces are stripped in braced arguments leaving all else as is.
  419. */
  420. char *get_arg_in_braces(struct session *ses, char *string, char *result, int flag)
  421. {
  422. char *pti, *pto;
  423. int skip, nest = 1;
  424. pti = space_out(string);
  425. pto = result;
  426. if (*pti != DEFAULT_OPEN)
  427. {
  428. if (!HAS_BIT(flag, GET_ALL))
  429. {
  430. pti = get_arg_stop_spaces(ses, pti, result, flag);
  431. }
  432. else
  433. {
  434. pti = get_arg_with_spaces(ses, pti, result, flag);
  435. }
  436. return pti;
  437. }
  438. pti++;
  439. while (*pti)
  440. {
  441. if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
  442. {
  443. *pto++ = *pti++;
  444. *pto++ = *pti++;
  445. continue;
  446. }
  447. skip = find_secure_color_code(pti);
  448. if (skip)
  449. {
  450. while (skip--)
  451. {
  452. *pto++ = *pti++;
  453. }
  454. continue;
  455. }
  456. if (*pti == DEFAULT_OPEN)
  457. {
  458. nest++;
  459. }
  460. else if (*pti == DEFAULT_CLOSE)
  461. {
  462. nest--;
  463. if (nest == 0)
  464. {
  465. break;
  466. }
  467. }
  468. *pto++ = *pti++;
  469. }
  470. if (*pti == 0)
  471. {
  472. tintin_printf2(ses, "#ERROR: GET BRACED ARGUMENT: UNMATCHED BRACE.");
  473. }
  474. else
  475. {
  476. pti++;
  477. }
  478. *pto = '\0';
  479. return pti;
  480. }
  481. char *sub_arg_in_braces(struct session *ses, char *string, char *result, int flag, int sub)
  482. {
  483. char *buffer = str_alloc(UMAX(strlen(string), BUFFER_SIZE));
  484. string = get_arg_in_braces(ses, string, buffer, flag);
  485. substitute(ses, buffer, result, sub);
  486. str_free(buffer);
  487. return string;
  488. }
  489. /*
  490. get all arguments
  491. */
  492. char *get_arg_with_spaces(struct session *ses, char *string, char *result, int flag)
  493. {
  494. char *pto, *pti;
  495. int skip, nest = 0;
  496. pti = space_out(string);
  497. pto = result;
  498. while (*pti)
  499. {
  500. if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
  501. {
  502. *pto++ = *pti++;
  503. *pto++ = *pti++;
  504. continue;
  505. }
  506. skip = find_secure_color_code(pti);
  507. if (skip)
  508. {
  509. while (skip--)
  510. {
  511. *pto++ = *pti++;
  512. }
  513. continue;
  514. }
  515. if (*pti == '\\' && pti[1] == COMMAND_SEPARATOR)
  516. {
  517. *pto++ = *pti++;
  518. }
  519. else if (*pti == COMMAND_SEPARATOR && nest == 0)
  520. {
  521. break;
  522. }
  523. else if (*pti == DEFAULT_OPEN)
  524. {
  525. nest++;
  526. }
  527. else if (*pti == DEFAULT_CLOSE)
  528. {
  529. nest--;
  530. }
  531. *pto++ = *pti++;
  532. }
  533. *pto = '\0';
  534. return pti;
  535. }
  536. /*
  537. get one arg, stop at spaces
  538. */
  539. char *get_arg_stop_spaces(struct session *ses, char *string, char *result, int flag)
  540. {
  541. char *pto, *pti;
  542. int skip, nest = 0;
  543. pti = space_out(string);
  544. pto = result;
  545. while (*pti)
  546. {
  547. if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
  548. {
  549. *pto++ = *pti++;
  550. *pto++ = *pti++;
  551. continue;
  552. }
  553. skip = find_secure_color_code(pti);
  554. if (skip)
  555. {
  556. while (skip--)
  557. {
  558. *pto++ = *pti++;
  559. }
  560. continue;
  561. }
  562. if (*pti == '\\' && pti[1] == COMMAND_SEPARATOR)
  563. {
  564. *pto++ = *pti++;
  565. }
  566. else if (*pti == COMMAND_SEPARATOR && nest == 0)
  567. {
  568. break;
  569. }
  570. else if (isspace((int) *pti) && nest == 0)
  571. {
  572. pti++;
  573. break;
  574. }
  575. else if (*pti == DEFAULT_OPEN)
  576. {
  577. nest++;
  578. }
  579. else if (*pti == '[' && HAS_BIT(flag, GET_NST))
  580. {
  581. nest++;
  582. }
  583. else if (*pti == DEFAULT_CLOSE)
  584. {
  585. nest--;
  586. }
  587. else if (*pti == ']' && HAS_BIT(flag, GET_NST))
  588. {
  589. nest--;
  590. }
  591. *pto++ = *pti++;
  592. }
  593. *pto = '\0';
  594. return pti;
  595. }
  596. // Get one arg, stop at numbers, used for speedwalks
  597. char *get_arg_stop_digits(struct session *ses, char *string, char *result, int flag)
  598. {
  599. char *pto, *pti;
  600. int nest = 0;
  601. pti = space_out(string);
  602. pto = result;
  603. while (*pti)
  604. {
  605. if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
  606. {
  607. *pto++ = *pti++;
  608. *pto++ = *pti++;
  609. continue;
  610. }
  611. if (*pti == '\\' && pti[1] == COMMAND_SEPARATOR)
  612. {
  613. *pto++ = *pti++;
  614. }
  615. else if (*pti == COMMAND_SEPARATOR && nest == 0)
  616. {
  617. break;
  618. }
  619. else if (isdigit((int) *pti) && nest == 0)
  620. {
  621. pti++;
  622. break;
  623. }
  624. else if (*pti == DEFAULT_OPEN)
  625. {
  626. nest++;
  627. }
  628. else if (*pti == '[' && HAS_BIT(flag, GET_NST))
  629. {
  630. nest++;
  631. }
  632. else if (*pti == DEFAULT_CLOSE)
  633. {
  634. nest--;
  635. }
  636. else if (*pti == ']' && HAS_BIT(flag, GET_NST))
  637. {
  638. nest--;
  639. }
  640. *pto++ = *pti++;
  641. }
  642. *pto = '\0';
  643. return pti;
  644. }
  645. /*
  646. advance ptr to next none-space
  647. */
  648. char *space_out(char *string)
  649. {
  650. while (isspace((int) *string))
  651. {
  652. string++;
  653. }
  654. return string;
  655. }
  656. /*
  657. For variable handling
  658. */
  659. char *get_arg_to_brackets(struct session *ses, char *string, char *result)
  660. {
  661. char *pti, *pto, *ptii, *ptoo;
  662. int nest1 = 0, nest2 = 0, nest3 = 0;
  663. pti = space_out(string);
  664. pto = result;
  665. ptii = ptoo = NULL;
  666. while (*pti)
  667. {
  668. if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
  669. {
  670. *pto++ = *pti++;
  671. *pto++ = *pti++;
  672. continue;
  673. }
  674. if (*pti == '[')
  675. {
  676. nest2++;
  677. if (nest1 == 0 && ptii == NULL)
  678. {
  679. ptii = pti;
  680. ptoo = pto;
  681. }
  682. }
  683. else if (*pti == ']')
  684. {
  685. if (nest2)
  686. {
  687. nest2--;
  688. }
  689. else
  690. {
  691. nest3 = 1;
  692. }
  693. if (*(pti+1) == 0 && ptii && nest1 == 0 && nest2 == 0 && nest3 == 0)
  694. {
  695. *ptoo = 0;
  696. return ptii;
  697. }
  698. }
  699. else if (*pti == DEFAULT_OPEN)
  700. {
  701. nest1++;
  702. }
  703. else if (*pti == DEFAULT_CLOSE)
  704. {
  705. nest1--;
  706. }
  707. *pto++ = *pti++;
  708. }
  709. *pto = 0;
  710. return pti;
  711. }
  712. char *get_arg_at_brackets(struct session *ses, char *string, char *result)
  713. {
  714. char *pti, *pto;
  715. int nest = 0;
  716. pti = string;
  717. pto = result;
  718. if (*pti != '[')
  719. {
  720. *pto = 0;
  721. return pti;
  722. }
  723. while (*pti)
  724. {
  725. if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
  726. {
  727. *pto++ = *pti++;
  728. *pto++ = *pti++;
  729. continue;
  730. }
  731. if (*pti == '[')
  732. {
  733. nest++;
  734. }
  735. else if (*pti == ']')
  736. {
  737. if (nest)
  738. {
  739. nest--;
  740. }
  741. else
  742. {
  743. break;
  744. }
  745. }
  746. else if (nest == 0)
  747. {
  748. break;
  749. }
  750. *pto++ = *pti++;
  751. }
  752. if (nest)
  753. {
  754. tintin_printf2(NULL, "#ERROR: GET BRACKETED VARIABLE: UNMATCHED BRACKET.");
  755. }
  756. *pto = 0;
  757. return pti;
  758. }
  759. char *get_arg_in_brackets(struct session *ses, char *string, char *result)
  760. {
  761. char *pti, *pto;
  762. int nest = 1;
  763. pti = string;
  764. pto = result;
  765. if (*pti != '[')
  766. {
  767. *pto = 0;
  768. return pti;
  769. }
  770. pti++;
  771. while (*pti)
  772. {
  773. if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
  774. {
  775. *pto++ = *pti++;
  776. *pto++ = *pti++;
  777. continue;
  778. }
  779. if (*pti == '[')
  780. {
  781. nest++;
  782. }
  783. else if (*pti == ']')
  784. {
  785. nest--;
  786. if (nest == 0)
  787. {
  788. break;
  789. }
  790. }
  791. *pto++ = *pti++;
  792. }
  793. if (*pti == 0)
  794. {
  795. tintin_printf2(NULL, "#ERROR: GET BRACKETED ARGUMENT: UNMATCHED BRACKET.");
  796. }
  797. else
  798. {
  799. pti++;
  800. }
  801. *pto = 0;
  802. return pti;
  803. }
  804. char *get_char(struct session *ses, char *string, char *result)
  805. {
  806. char *pti = string;
  807. if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, pti))
  808. {
  809. pti += sprintf(result, "%c%c", pti[0], pti[1]);
  810. }
  811. else if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8) && is_utf8_head(pti))
  812. {
  813. pti += sprintf(result, "%.*s", get_utf8_size(pti), pti);
  814. }
  815. else
  816. {
  817. pti += sprintf(result, "%c", pti[0]);
  818. }
  819. return pti;
  820. }
  821. /*
  822. send command to the mud
  823. */
  824. void write_mud(struct session *ses, char *command, int flags)
  825. {
  826. char output[BUFFER_SIZE];
  827. int size;
  828. size = substitute(ses, command, output, flags);
  829. if (HAS_BIT(ses->flags, SES_FLAG_PATHMAPPING))
  830. {
  831. if (ses->map == NULL || ses->map->nofollow == 0)
  832. {
  833. check_append_path(ses, command, NULL, 1);
  834. }
  835. }
  836. if (ses->map && ses->map->in_room && ses->map->nofollow == 0)
  837. {
  838. if (follow_map(ses, command))
  839. {
  840. return;
  841. }
  842. }
  843. write_line_mud(ses, output, size);
  844. }
  845. /*
  846. Check line for triggers
  847. */
  848. void do_one_line(char *line, struct session *ses)
  849. {
  850. char strip[BUFFER_SIZE];
  851. push_call("[%s] do_one_line(%s)",ses->name,line);
  852. if (gtd->level->ignore)
  853. {
  854. pop_call();
  855. return;
  856. }
  857. strip_vt102_codes(line, strip);
  858. if (!HAS_BIT(ses->list[LIST_ACTION]->flags, LIST_FLAG_IGNORE))
  859. {
  860. check_all_actions(ses, line, strip);
  861. }
  862. if (!HAS_BIT(ses->list[LIST_PROMPT]->flags, LIST_FLAG_IGNORE))
  863. {
  864. check_all_prompts(ses, line, strip);
  865. }
  866. if (!HAS_BIT(ses->list[LIST_GAG]->flags, LIST_FLAG_IGNORE))
  867. {
  868. check_all_gags(ses, line, strip);
  869. }
  870. if (!HAS_BIT(ses->list[LIST_SUBSTITUTE]->flags, LIST_FLAG_IGNORE))
  871. {
  872. check_all_substitutions(ses, line, strip);
  873. }
  874. if (!HAS_BIT(ses->list[LIST_HIGHLIGHT]->flags, LIST_FLAG_IGNORE))
  875. {
  876. check_all_highlights(ses, line, strip);
  877. }
  878. if (HAS_BIT(ses->logmode, LOG_FLAG_NEXT))
  879. {
  880. logit(ses, line, ses->lognext_file, LOG_FLAG_LINEFEED);
  881. DEL_BIT(ses->logmode, LOG_FLAG_NEXT);
  882. }
  883. pop_call();
  884. return;
  885. }