/saphire-3.6.5/src/saphire_parser.c

# · C · 2938 lines · 2716 code · 166 blank · 56 comment · 518 complexity · 3f3594dd790f3a0982a87d7b35920558 MD5 · raw file

  1. #include "config.h"
  2. #include <errno.h>
  3. #include <stdlib.h>
  4. #include <fcntl.h>
  5. #include <glob.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. #include <sys/stat.h>
  10. #include <sys/types.h>
  11. #include <pwd.h>
  12. #include <limits.h>
  13. #include "saphire/saphire.h"
  14. #include "saphire/saphire_inner.h"
  15. // ????????
  16. static void skip_spaces(char** p, string_obj* not_evaled)
  17. {
  18. while(**p == ' ' || **p == '\t') {
  19. string_push_back2(not_evaled, **p);
  20. (*p)++;
  21. }
  22. }
  23. // {}, <>, (), []????????????????????OK
  24. // ???????parse???
  25. // ???????
  26. static BOOL read_until_next_close_character(char first_char, char last_char, char** p, string_obj* not_evaled, int* read_end_of_statment, BOOL line_inc, char* sname, int* sline)
  27. {
  28. if(**p == first_char) {
  29. string_push_back2(not_evaled, **p);
  30. (*p)++;
  31. int nest = 0;
  32. BOOL squote = FALSE;
  33. BOOL dquote = FALSE;
  34. while(1) {
  35. if(gKitutukiSigInt) {
  36. err_msg("signal interrupt", sname, *sline);
  37. gKitutukiSigInt = FALSE;
  38. return FALSE;
  39. }
  40. /// ???? ///
  41. if(!squote && !dquote && **p == '\\') {
  42. string_push_back2(not_evaled, **p);
  43. (*p)++;
  44. if(line_inc && **p == '\n') {
  45. (*sline)++;
  46. }
  47. else if(**p == 0) {
  48. err_msg("unexpected end(0) after quote", sname, *sline);
  49. return FALSE;
  50. }
  51. string_push_back2(not_evaled, **p);
  52. (*p)++;
  53. }
  54. /// ???????? ///
  55. else if(!dquote && **p == '\'') {
  56. squote = !squote;
  57. string_push_back2(not_evaled, **p);
  58. (*p)++;
  59. }
  60. /// ??????? ///
  61. else if(!squote && **p == '"') {
  62. dquote = !dquote;
  63. string_push_back2(not_evaled, **p);
  64. (*p)++;
  65. }
  66. /// ?????????
  67. else if(!squote && **p == '$') {
  68. // ?????? $()
  69. if(*(*p+1) == '$' && *(*p+2) == '(' || *(*p+1) == '(')
  70. {
  71. if(*(*p+1) == '$') {
  72. string_push_back2(not_evaled, **p); // $
  73. (*p)++;
  74. string_push_back2(not_evaled, **p); // $
  75. (*p)++;
  76. }
  77. else {
  78. string_push_back2(not_evaled, **p); // $
  79. (*p)++;
  80. }
  81. if(!read_until_next_close_character('(', ')', p, not_evaled, read_end_of_statment, line_inc, sname, sline)) {
  82. return FALSE;
  83. }
  84. *read_end_of_statment = 1;
  85. }
  86. /// ???? ///
  87. else {
  88. BOOL quote;
  89. if(*(*p+1) == '$') {
  90. string_push_back2(not_evaled, **p); // $
  91. (*p)++;
  92. string_push_back2(not_evaled, **p); // $
  93. (*p)++;
  94. quote = FALSE;
  95. }
  96. else {
  97. string_push_back2(not_evaled, **p); // $
  98. (*p)++;
  99. quote = TRUE;
  100. }
  101. if(**p >= '0' && **p <= '9' || **p == '{' || **p >= 'a' && **p <= 'z' || **p >= 'A' && **p <= 'Z' || **p == '_') {
  102. if(**p == '{') {
  103. if(!read_until_next_close_character('{', '}', p, not_evaled, read_end_of_statment, TRUE, sname, sline)) {
  104. return FALSE;
  105. }
  106. }
  107. else {
  108. while(**p) {
  109. if(**p >= '0' && **p <= '9' || **p >= 'a' && **p <= 'z' || **p >= 'A' && **p <= 'Z' || **p == '_') {
  110. string_push_back2(not_evaled, **p); // ??
  111. (*p)++;
  112. }
  113. else {
  114. break;
  115. }
  116. }
  117. }
  118. *read_end_of_statment = 1;
  119. }
  120. else {
  121. if(quote) {
  122. string_push_back2(not_evaled, '$');
  123. }
  124. else {
  125. string_push_back2(not_evaled, '$');
  126. string_push_back2(not_evaled, '$');
  127. }
  128. }
  129. }
  130. }
  131. else if(squote || dquote) {
  132. if(**p == 0) {
  133. err_msg("close ' or \" before the end of source", sname, *sline);
  134. return FALSE;
  135. }
  136. else {
  137. if(line_inc && **p == '\n') {
  138. (*sline)++;
  139. }
  140. string_push_back2(not_evaled, **p);
  141. (*p)++;
  142. }
  143. }
  144. else if(**p == first_char) {
  145. nest++;
  146. string_push_back2(not_evaled, **p);
  147. (*p)++;
  148. }
  149. else if(**p == last_char) {
  150. string_push_back2(not_evaled, **p);
  151. (*p)++;
  152. if(nest == 0) {
  153. break;
  154. }
  155. nest--;
  156. }
  157. else if(**p == 0) {
  158. char buf[256];
  159. snprintf(buf, 256, "read_util_next_close_character: unexpected end(0). close with (%c)", last_char);
  160. err_msg(buf, sname, *sline);
  161. return FALSE;
  162. }
  163. else if(line_inc && **p == '\n') {
  164. (*sline)++;
  165. string_push_back2(not_evaled, **p);
  166. (*p)++;
  167. }
  168. else {
  169. string_push_back2(not_evaled, **p);
  170. (*p)++;
  171. }
  172. }
  173. }
  174. return TRUE;
  175. }
  176. // ??????????? contents????
  177. // ?????????????
  178. // ????????????
  179. static BOOL read_block(char** p, string_obj* contents, vector_obj* args, string_obj* not_evaled, BOOL line_inc, char* sname, int* sline)
  180. {
  181. int line_of_head = *sline;
  182. string_push_back2(not_evaled, **p); // {
  183. (*p)++;
  184. while(1) {
  185. if(**p == ' ') {
  186. string_push_back2(not_evaled, **p);
  187. string_push_back2(contents, *((*p)++));
  188. }
  189. else if(**p == '\t') {
  190. string_push_back2(not_evaled, **p);
  191. string_push_back2(contents, *((*p)++));
  192. }
  193. else if(**p == '\n') {
  194. line_inc && (*sline)++;
  195. string_push_back2(not_evaled, **p);
  196. string_push_back2(contents, *((*p)++));
  197. }
  198. else {
  199. break;
  200. }
  201. }
  202. /// ??
  203. if(args) {
  204. if(**p == ':') {
  205. string_push_back2(not_evaled, **p);
  206. (*p)++;
  207. while(**p) {
  208. string_obj* str = STRING_NEW("");
  209. skip_spaces(p, not_evaled);
  210. while(**p >= 'a' && **p <= 'z'
  211. || **p >= 'A' && **p <= 'Z'
  212. || **p == '_')
  213. {
  214. string_push_back2(str, **p);
  215. string_push_back2(not_evaled, **p);
  216. (*p)++;
  217. }
  218. skip_spaces(p, not_evaled);
  219. vector_add(args, str);
  220. if(**p >= 'a' && **p <= 'z'
  221. || **p >= 'A' && **p <= 'Z'
  222. || **p == '_')
  223. {
  224. }
  225. else {
  226. if(**p == ':') {
  227. string_push_back2(not_evaled, **p);
  228. (*p)++;
  229. break;
  230. }
  231. else {
  232. char buf[1024];
  233. snprintf(buf, 1024, "unexpected char(%c)", **p);
  234. err_msg(buf, sname, line_of_head);
  235. return FALSE;
  236. }
  237. }
  238. }
  239. }
  240. while(1) {
  241. if(**p == ' ') {
  242. string_push_back2(not_evaled, **p);
  243. string_push_back2(contents, *((*p)++));
  244. }
  245. else if(**p == '\t') {
  246. string_push_back2(not_evaled, **p);
  247. string_push_back2(contents, *((*p)++));
  248. }
  249. else if(**p == '\n') {
  250. line_inc && (*sline)++;
  251. string_push_back2(not_evaled, **p);
  252. string_push_back2(contents, *((*p)++));
  253. }
  254. else {
  255. break;
  256. }
  257. }
  258. }
  259. BOOL squote = FALSE;
  260. BOOL dquote = FALSE;
  261. int nest = 0;
  262. while(1) {
  263. /// ????
  264. if(!squote && !dquote && **p == '\\') {
  265. string_push_back2(not_evaled, **p);
  266. string_push_back2(contents, *((*p)++));
  267. if(line_inc && **p == '\n') {
  268. (*sline)++;
  269. }
  270. else if(*p == 0) {
  271. err_msg("unsigned end after quote",sname, *sline);
  272. return FALSE;
  273. }
  274. string_push_back2(not_evaled, **p);
  275. string_push_back2(contents, *((*p)++));
  276. }
  277. /// ????????
  278. else if(!dquote && **p == '\'') {
  279. string_push_back2(not_evaled, **p);
  280. string_push_back2(contents, *((*p)++));
  281. squote = !squote;
  282. }
  283. /// ???????
  284. else if(!squote && **p == '"') {
  285. string_push_back2(not_evaled, **p);
  286. string_push_back2(contents, *((*p)++));
  287. dquote = !dquote;
  288. }
  289. /// ????????????????? ///
  290. else if(squote || dquote) {
  291. if(**p == 0) {
  292. err_msg("get block: close \" or \' before the end of block", sname, line_of_head);
  293. return FALSE;
  294. }
  295. else if(line_inc && **p == '\n') {
  296. (*sline)++;
  297. }
  298. string_push_back2(not_evaled, **p);
  299. string_push_back2(contents, *((*p)++));
  300. }
  301. else if(**p == '(') {
  302. string_push_back2(not_evaled, **p);
  303. string_push_back2(contents, *((*p)++));
  304. nest++;
  305. }
  306. else if(**p == ')') {
  307. string_push_back2(not_evaled, **p);
  308. (*p)++;
  309. nest--;
  310. if(nest == -1) {
  311. break;
  312. }
  313. else {
  314. string_push_back2(contents, ')');
  315. }
  316. }
  317. else if(**p == 0) {
  318. err_msg("get block: found 0. close )", sname, line_of_head);
  319. return FALSE;
  320. }
  321. else if(**p == '\n') {
  322. line_inc && (*sline)++;
  323. string_push_back2(not_evaled, **p);
  324. string_push_back2(contents, **p);
  325. (*p)++;
  326. }
  327. else {
  328. string_push_back2(not_evaled, **p);
  329. string_push_back2(contents, **p);
  330. (*p)++;
  331. }
  332. }
  333. return TRUE;
  334. }
  335. /// ?????
  336. static void expand_tilda(string_obj* buf, string_obj* path)
  337. {
  338. char* p = string_c_str(buf);
  339. p++; // ~
  340. string_obj* user = STRING_NEW("");
  341. while(*p && *p != '/') {
  342. string_push_back2(user, *p);
  343. p++;
  344. }
  345. /// ???????????????????
  346. if(string_length(user) == 0) {
  347. char* home = getenv("HOME");
  348. if(home) {
  349. string_push_back(path, home);
  350. }
  351. else {
  352. struct passwd* pw = getpwuid(getuid());
  353. if(pw) {
  354. string_push_back(path, pw->pw_dir);
  355. }
  356. else {
  357. string_push_back(path, "~");
  358. }
  359. }
  360. }
  361. else {
  362. struct passwd* pw = getpwnam(string_c_str(user));
  363. if(pw) {
  364. string_push_back(path, pw->pw_dir);
  365. }
  366. else {
  367. string_push_back2(path, '~');
  368. string_push_back(path, string_c_str(user));
  369. }
  370. }
  371. /// ?????
  372. string_push_back(path, p);
  373. string_delete(user);
  374. }
  375. static BOOL add_arg_to_command(sCommand* command, MANAGED sArg* new_arg, char* sname, int* sline)
  376. {
  377. vector_add(command->mArgs, new_arg);
  378. if(vector_size(command->mArgs) == 1) {
  379. if(new_arg->mKind == 0) {
  380. /// ???????????????? ///
  381. command->mKind = get_command_kind(string_c_str(new_arg->mBody));
  382. }
  383. else {
  384. err_msg("command name must be determined staticaly", sname, *sline);
  385. return FALSE;
  386. }
  387. }
  388. return TRUE;
  389. }
  390. /// ???????
  391. static BOOL read_one_argument(char** p, string_obj* buf, string_obj* not_evaled, int* read_end_of_statment, sCommand* command, char* sname, int* sline, BOOL expand_quote)
  392. {
  393. /// ????????????????? 127????
  394. static unsigned char table[] = {
  395. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
  396. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  397. 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
  398. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0,
  399. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  400. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
  401. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  402. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
  403. };
  404. BOOL squote = FALSE;
  405. BOOL dquote = FALSE;
  406. while(**p) {
  407. if(gKitutukiSigInt) {
  408. gKitutukiSigInt = FALSE;
  409. err_msg("signal interrupt", sname, *sline);
  410. return FALSE;
  411. }
  412. /// ???
  413. if(!squote && !dquote && **p == '"' && *(*p+1) == '"') {
  414. break;
  415. }
  416. else if(!dquote && !squote && **p =='\'' && *(*p+1) == '\'') {
  417. break;
  418. }
  419. else if(**p == '\\' && *(*p+1) == 't') {
  420. string_push_back2(not_evaled, **p);
  421. string_push_back2(not_evaled, *(*p+1));
  422. string_push_back2(buf, '\t');
  423. (*p)+=2;
  424. }
  425. else if(**p == '\\' && *(*p+1) == 'n') {
  426. string_push_back2(not_evaled, **p);
  427. string_push_back2(not_evaled, *(*p+1));
  428. string_push_back2(buf, '\n');
  429. (*p)+=2;
  430. }
  431. else if(**p == '\\' && *(*p+1) == 'r') {
  432. string_push_back2(not_evaled, **p);
  433. string_push_back2(not_evaled, *(*p+1));
  434. string_push_back2(buf, '\r');
  435. (*p)+=2;
  436. }
  437. else if(**p == '\\' && *(*p+1) == 'a') {
  438. string_push_back2(not_evaled, **p);
  439. string_push_back2(not_evaled, *(*p+1));
  440. string_push_back2(buf, '\a');
  441. (*p)+=2;
  442. }
  443. else if(!squote && !dquote && **p == '\\') {
  444. if(expand_quote) {
  445. string_push_back2(not_evaled, **p);
  446. (*p)++;
  447. if(**p == 0) {
  448. err_msg("unexpected end. can't quote null.", sname, *sline);
  449. return FALSE;
  450. }
  451. else if(**p == '\n') {
  452. (*sline)++;
  453. }
  454. string_push_back2(not_evaled, **p);
  455. string_push_back2(buf, **p);
  456. (*p)++;
  457. }
  458. else {
  459. string_push_back2(not_evaled, **p);
  460. string_push_back2(buf, **p);
  461. (*p)++;
  462. }
  463. }
  464. else if(!dquote && **p == '\'') {
  465. if(expand_quote) {
  466. string_push_back2(not_evaled, **p);
  467. (*p)++;
  468. squote = !squote;
  469. }
  470. else {
  471. string_push_back2(not_evaled, **p);
  472. string_push_back2(buf, **p);
  473. (*p)++;
  474. }
  475. }
  476. else if(!squote && **p == '"') {
  477. if(expand_quote) {
  478. dquote = !dquote;
  479. string_push_back2(not_evaled, **p);
  480. (*p)++;
  481. }
  482. else {
  483. string_push_back2(not_evaled, **p);
  484. string_push_back2(buf, **p);
  485. (*p)++;
  486. }
  487. }
  488. /// ?????????
  489. else if(!squote && **p == '$') {
  490. // ?????? $()
  491. if(*(*p+1) == '(' || *(*p+1) == '$' && *(*p+2) == '(')
  492. {
  493. if(*(*p+1) == '$') {
  494. string_push_back2(not_evaled, **p); // $
  495. (*p)++;
  496. string_push_back2(not_evaled, **p); // $
  497. (*p)++;
  498. }
  499. else {
  500. string_push_back2(not_evaled, **p); // $
  501. (*p)++;
  502. }
  503. if(!read_until_next_close_character('(', ')', p, not_evaled, read_end_of_statment, TRUE, sname, sline)) {
  504. return FALSE;
  505. }
  506. *read_end_of_statment = 1;
  507. }
  508. /// ????
  509. else {
  510. BOOL quote;
  511. if(*(*p+1) == '$') {
  512. string_push_back2(not_evaled, **p); // $
  513. (*p)++;
  514. string_push_back2(not_evaled, **p); // $
  515. (*p)++;
  516. quote = FALSE;
  517. }
  518. else {
  519. string_push_back2(not_evaled, **p); // $
  520. (*p)++;
  521. quote = TRUE;
  522. }
  523. if(**p >= '0' && **p <= '9' || **p == '{' || **p >= 'a' && **p <= 'z' || **p >= 'A' && **p <= 'Z' || **p == '_') {
  524. if(**p == '{') {
  525. if(!read_until_next_close_character('{', '}', p, not_evaled, read_end_of_statment, TRUE, sname, sline)) {
  526. return FALSE;
  527. }
  528. }
  529. else {
  530. while(**p) {
  531. if(**p >= '0' && **p <= '9' || **p >= 'a' && **p <= 'z' || **p >= 'A' && **p <= 'Z' || **p == '_') {
  532. string_push_back2(not_evaled, **p); // ??
  533. (*p)++;
  534. }
  535. else {
  536. break;
  537. }
  538. }
  539. }
  540. *read_end_of_statment = 1;
  541. }
  542. else {
  543. if(quote) {
  544. string_push_back2(buf, '$');
  545. }
  546. else {
  547. string_push_back2(buf, '$');
  548. string_push_back2(buf, '$');
  549. }
  550. }
  551. }
  552. }
  553. /// ?????????????????
  554. else if(squote || dquote) {
  555. if(**p == 0) {
  556. err_msg("close single quote or double quote", sname, *sline);
  557. return FALSE;
  558. }
  559. else if(**p == '\n') {
  560. (*sline)++;
  561. }
  562. string_push_back2(not_evaled, **p);
  563. string_push_back2(buf, **p);
  564. (*p)++;
  565. }
  566. /*
  567. /// ?????
  568. else if(command && vector_size(command->mArgs) > 0 && command->mKind != kCommand && string_c_str(buf)[0] == 0 && **p == '-')
  569. {
  570. string_push_back2(not_evaled, **p);
  571. string_push_back2(buf, **p);
  572. (*p)++;
  573. if(!read_one_argument(p, buf, not_evaled, read_end_of_statment, NULL, sname, sline, FALSE))
  574. {
  575. return FALSE;
  576. }
  577. int i = 0;
  578. int options = 0;
  579. while(kCommandOptions[i]) {
  580. if(strcmp(string_c_str(buf), kCommandOptions[command->mKind][i]) == 0)
  581. {
  582. options |= 0x1 << i;
  583. }
  584. i++;
  585. }
  586. if(options) {
  587. command->mOptions |= options;
  588. string_put(buf, "");
  589. }
  590. else {
  591. if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
  592. {
  593. return FALSE;
  594. }
  595. }
  596. }
  597. */
  598. /// ????? ///
  599. else if(**p == '~') {
  600. string_push_back2(not_evaled, **p);
  601. string_push_back2(buf, **p);
  602. (*p)++;
  603. if(strlen(string_c_str(buf)) == 1 && command) {
  604. if(!read_one_argument(p, buf, not_evaled, read_end_of_statment, NULL, sname, sline, FALSE))
  605. {
  606. return FALSE;
  607. }
  608. string_obj* path = STRING_NEW("");
  609. expand_tilda(buf, path);
  610. string_obj* path2 = STRING_NEW("");
  611. BOOL glob_ = FALSE;
  612. char* p = string_c_str(path);
  613. BOOL squote = FALSE;
  614. BOOL dquote = FALSE;
  615. while(*p) {
  616. if(!dquote && *p == '\'') {
  617. p++;
  618. squote = !squote;
  619. }
  620. else if(!squote && *p == '"') {
  621. p++;
  622. dquote = !dquote;
  623. }
  624. else if(squote || dquote) {
  625. string_push_back2(path2, *p);
  626. p++;
  627. }
  628. else if(*p == '\\') {
  629. p++;
  630. string_push_back2(path2, *p);
  631. p++;
  632. }
  633. else if(*p == '[') {
  634. string_push_back2(path2, *p);
  635. p++;
  636. while(*p) {
  637. if(*p == ']') {
  638. glob_ = TRUE;
  639. string_push_back2(path2, *p);
  640. p++;
  641. break;
  642. }
  643. else {
  644. string_push_back2(path2, *p);
  645. p++;
  646. }
  647. }
  648. }
  649. else if(*p == '?' || *p == '*') {
  650. glob_ = TRUE;
  651. string_push_back2(path2, *p);
  652. p++;
  653. }
  654. else {
  655. string_push_back2(path2, *p);
  656. p++;
  657. }
  658. }
  659. string_delete(path);
  660. if(glob_) {
  661. glob_t result;
  662. int rc = glob(string_c_str(path2), 0, NULL, &result);
  663. if(rc == GLOB_NOSPACE) {
  664. err_msg("read_one_argument: out of space during glob operation", sname, *sline);
  665. string_delete(path2);
  666. return FALSE;
  667. }
  668. else if(rc == GLOB_NOMATCH) {
  669. }
  670. else {
  671. int i;
  672. for(i=0; i<result.gl_pathc; i++) {
  673. char* file = result.gl_pathv[i];
  674. if(strcmp(file, ".") != 0 && strcmp(file, "..") != 0)
  675. {
  676. string_obj* str = STRING_NEW(file);
  677. if(!add_arg_to_command(command, ARG_NEW(0, MANAGED str), sname, sline))
  678. {
  679. string_delete(path2);
  680. return FALSE;
  681. }
  682. }
  683. }
  684. string_put(buf, ""); // ?????????mArgs??????
  685. }
  686. string_delete(path2);
  687. }
  688. else {
  689. if(!add_arg_to_command(command, ARG_NEW(0, MANAGED path2), sname, sline))
  690. {
  691. return FALSE;
  692. }
  693. string_put(buf, ""); // ???????????mArgs??????
  694. }
  695. break;
  696. }
  697. }
  698. /// ??? ///
  699. else if(command && vector_size(command->mArgs) > 0 && (**p == '[' || **p == '?' || **p == '*'))
  700. {
  701. string_push_back2(not_evaled, **p);
  702. string_push_back2(buf, **p);
  703. (*p)++;
  704. if(!read_one_argument(p, buf, not_evaled, read_end_of_statment, NULL, sname, sline, TRUE))
  705. {
  706. return FALSE;
  707. }
  708. glob_t result;
  709. int rc = glob(string_c_str(buf), 0, NULL, &result);
  710. if(rc == GLOB_NOSPACE) {
  711. err_msg("read_one_argument: out of space during glob operation", sname, *sline);
  712. return FALSE;
  713. }
  714. else if(rc == GLOB_NOMATCH) {
  715. }
  716. else {
  717. int i;
  718. for(i=0; i<result.gl_pathc; i++) {
  719. char* file = result.gl_pathv[i];
  720. if(strcmp(file, ".") != 0 && strcmp(file, "..") != 0)
  721. {
  722. string_obj* str = STRING_NEW(file);
  723. if(!add_arg_to_command(command, ARG_NEW(0, MANAGED str), sname, sline))
  724. {
  725. return FALSE;
  726. }
  727. }
  728. }
  729. string_put(buf, ""); // ?????????mArgs??????
  730. }
  731. break;
  732. }
  733. // ->?????
  734. else if(command && vector_size(command->mArgs) == 0 && **p == '-' && *(*p+1) == '>')
  735. {
  736. string_push_back2(not_evaled, **p);
  737. string_push_back2(buf, **p);
  738. (*p)++;
  739. string_push_back2(not_evaled, **p);
  740. string_push_back2(buf, **p);
  741. (*p)++;
  742. }
  743. /// utf-8??????
  744. else if(((unsigned char)**p) > 127) {
  745. string_push_back2(not_evaled, **p);
  746. string_push_back2(buf, **p);
  747. (*p)++;
  748. }
  749. // ???????????????
  750. else if(**p == '@' && (*(*p+1) == '(') || (*(*p+1) == '@' && *(*p+2) == '(') || (*(*p+1) == '@' && *(*p+2) >= 'a' && *(*p+2) <= 'z' && *(*p+3) == '('))
  751. {
  752. break;
  753. }
  754. // % ????????????
  755. else if(**p == '%' && (*(*p+1) == '>' || *(*p+1) == '2')) {
  756. break;
  757. }
  758. else if(table[**p]) {
  759. break;
  760. }
  761. else {
  762. string_push_back2(not_evaled, **p);
  763. string_push_back2(buf, **p);
  764. (*p)++;
  765. }
  766. }
  767. if(squote) {
  768. err_msg("require to close '", sname, *sline);
  769. return FALSE;
  770. }
  771. if(dquote) {
  772. err_msg("require to close \"", sname, *sline);
  773. return FALSE;
  774. }
  775. return TRUE;
  776. }
  777. /// if?????
  778. static BOOL read_command_parse_if_statment(char** p, sCommand* command, sStatment* statment, string_obj* not_evaled, int* read_end_of_statment, char* sname, int* sline)
  779. {
  780. skip_spaces(p, not_evaled);
  781. if(**p != '(') {
  782. err_msg("expected (", sname, *sline);
  783. return FALSE;
  784. }
  785. /// ??????? ///
  786. string_obj* str = STRING_NEW("");
  787. int read_end_of_statment2 = -1;
  788. if(!read_until_next_close_character('(', ')', p, str, &read_end_of_statment2, FALSE, sname, sline)) {
  789. string_delete(str);
  790. return FALSE;
  791. }
  792. string_push_back(not_evaled, string_c_str(str));
  793. string_erase(str, 0, 1);
  794. string_trunc(str, string_length(str)-1);
  795. sStatments* condition = STATMENTS_NEW();
  796. if(!parse(string_c_str(str), sname, sline, condition))
  797. {
  798. string_delete(str);
  799. sStatments_delete(condition);
  800. return FALSE;
  801. }
  802. string_delete(str);
  803. skip_spaces(p, not_evaled);
  804. /// ??? ///
  805. sStatments* loop = STATMENTS_NEW();
  806. if(**p == '(') {
  807. string_obj* str = STRING_NEW("");
  808. if(!read_block(p, str, NULL, not_evaled, FALSE, sname, sline)) {
  809. string_delete(str);
  810. sStatments_delete(condition);
  811. sStatments_delete(loop);
  812. return FALSE;
  813. }
  814. if(!parse(string_c_str(str), sname, sline, loop))
  815. {
  816. sStatments_delete(condition);
  817. sStatments_delete(loop);
  818. string_delete(str);
  819. return FALSE;
  820. }
  821. string_delete(str);
  822. }
  823. else {
  824. err_msg("expected block.", sname, *sline);
  825. sStatments_delete(condition);
  826. sStatments_delete(loop);
  827. return FALSE;
  828. }
  829. skip_spaces(p, not_evaled);
  830. vector_obj* conditions = VECTOR_NEW(30);
  831. vector_obj* loops = VECTOR_NEW(30);
  832. vector_add(conditions, condition);
  833. vector_add(loops, loop);
  834. /// elif ?? ///
  835. if(**p == 'e' && *(*p+1) == 'l'
  836. && *(*p+2) == 'i' && *(*p+3) == 'f'
  837. && (*(*p+4) == ' ' || *(*p+4) == '\t' || *(*p+4) == '('))
  838. {
  839. while(**p == 'e' && *(*p+1) == 'l' && *(*p+2) == 'i'
  840. && *(*p+3) == 'f'
  841. && (*(*p+4) == ' ' || *(*p+4) == '\t' || *(*p+4) == '('))
  842. {
  843. string_push_back2(not_evaled, **p);
  844. (*p)++;
  845. string_push_back2(not_evaled, **p);
  846. (*p)++;
  847. string_push_back2(not_evaled, **p);
  848. (*p)++;
  849. string_push_back2(not_evaled, **p);
  850. (*p)++;
  851. skip_spaces(p, not_evaled);
  852. if(**p != '(') {
  853. err_msg("expected (", sname, *sline);
  854. int i;
  855. for(i=0; i<vector_size(conditions); i++) {
  856. sStatments_delete(vector_item(conditions, i));
  857. }
  858. vector_delete(conditions);
  859. for(i=0; i<vector_size(loops); i++) {
  860. sStatments_delete(vector_item(loops, i));
  861. }
  862. vector_delete(loops);
  863. return FALSE;
  864. }
  865. /// ??? ///
  866. string_obj* str = STRING_NEW("");
  867. int read_end_of_statment = -1;
  868. if(!read_until_next_close_character('(', ')', p, str, &read_end_of_statment, FALSE, sname, sline)) {
  869. string_delete(str);
  870. int i;
  871. for(i=0; i<vector_size(conditions); i++) {
  872. sStatments_delete(vector_item(conditions, i));
  873. }
  874. vector_delete(conditions);
  875. for(i=0; i<vector_size(loops); i++) {
  876. sStatments_delete(vector_item(loops, i));
  877. }
  878. vector_delete(loops);
  879. return FALSE;
  880. }
  881. string_push_back(not_evaled, string_c_str(str));
  882. sStatments* condition = STATMENTS_NEW();
  883. if(!parse(string_c_str(str), sname, sline, condition))
  884. {
  885. sStatments_delete(condition);
  886. int i;
  887. for(i=0; i<vector_size(conditions); i++) {
  888. sStatments_delete(vector_item(conditions, i));
  889. }
  890. vector_delete(conditions);
  891. for(i=0; i<vector_size(loops); i++) {
  892. sStatments_delete(vector_item(loops, i));
  893. }
  894. vector_delete(loops);
  895. string_delete(str);
  896. return FALSE;
  897. }
  898. string_delete(str);
  899. vector_add(conditions, condition);
  900. skip_spaces(p, not_evaled);
  901. /// ??? ///
  902. sStatments* loop = STATMENTS_NEW();
  903. if(**p == '(') {
  904. string_obj* str = STRING_NEW("");
  905. if(!read_block(p, str, NULL, not_evaled, FALSE, sname, sline)) {
  906. string_delete(str);
  907. sStatments_delete(loop);
  908. int i;
  909. for(i=0; i<vector_size(conditions); i++) {
  910. sStatments_delete(vector_item(conditions, i));
  911. }
  912. vector_delete(conditions);
  913. for(i=0; i<vector_size(loops); i++) {
  914. sStatments_delete(vector_item(loops, i));
  915. }
  916. vector_delete(loops);
  917. return FALSE;
  918. }
  919. if(!parse(string_c_str(str), sname, sline, loop))
  920. {
  921. sStatments_delete(loop);
  922. string_delete(str);
  923. int i;
  924. for(i=0; i<vector_size(conditions); i++) {
  925. sStatments_delete(vector_item(conditions, i));
  926. }
  927. vector_delete(conditions);
  928. for(i=0; i<vector_size(loops); i++) {
  929. sStatments_delete(vector_item(loops, i));
  930. }
  931. vector_delete(loops);
  932. return FALSE;
  933. }
  934. string_delete(str);
  935. }
  936. else {
  937. err_msg("expected block.", sname, *sline);
  938. sStatments_delete(loop);
  939. int i;
  940. for(i=0; i<vector_size(conditions); i++) {
  941. sStatments_delete(vector_item(conditions, i));
  942. }
  943. vector_delete(conditions);
  944. for(i=0; i<vector_size(loops); i++) {
  945. sStatments_delete(vector_item(loops, i));
  946. }
  947. vector_delete(loops);
  948. return FALSE;
  949. }
  950. skip_spaces(p, not_evaled);
  951. vector_add(loops, loop);
  952. }
  953. }
  954. /// else ?? ///
  955. if(**p == 'e' && *(*p+1) == 'l' && *(*p+2) == 's' && *(*p+3) == 'e' && (*(*p+4) == ' ' || *(*p+4) == '\t' || *(*p+4) == '('))
  956. {
  957. string_push_back2(not_evaled, **p);
  958. (*p)++;
  959. string_push_back2(not_evaled, **p);
  960. (*p)++;
  961. string_push_back2(not_evaled, **p);
  962. (*p)++;
  963. string_push_back2(not_evaled, **p);
  964. (*p)++;
  965. skip_spaces(p, not_evaled);
  966. /// ??? ///
  967. sStatments* loop = STATMENTS_NEW();
  968. if(**p == '(') {
  969. string_obj* str = STRING_NEW("");
  970. if(!read_block(p, str, NULL, not_evaled, FALSE, sname, sline)) {
  971. string_delete(str);
  972. sStatments_delete(loop);
  973. int i;
  974. for(i=0; i<vector_size(conditions); i++) {
  975. sStatments_delete(vector_item(conditions, i));
  976. }
  977. vector_delete(conditions);
  978. for(i=0; i<vector_size(loops); i++) {
  979. sStatments_delete(vector_item(loops, i));
  980. }
  981. vector_delete(loops);
  982. return FALSE;
  983. }
  984. if(!parse(string_c_str(str), sname, sline, loop))
  985. {
  986. string_delete(str);
  987. sStatments_delete(loop);
  988. int i;
  989. for(i=0; i<vector_size(conditions); i++) {
  990. sStatments_delete(vector_item(conditions, i));
  991. }
  992. vector_delete(conditions);
  993. for(i=0; i<vector_size(loops); i++) {
  994. sStatments_delete(vector_item(loops, i));
  995. }
  996. return FALSE;
  997. }
  998. string_delete(str);
  999. }
  1000. else {
  1001. err_msg("expected block.", sname, *sline);
  1002. int i;
  1003. for(i=0; i<vector_size(conditions); i++) {
  1004. sStatments_delete(vector_item(conditions, i));
  1005. }
  1006. vector_delete(conditions);
  1007. for(i=0; i<vector_size(loops); i++) {
  1008. sStatments_delete(vector_item(loops, i));
  1009. }
  1010. sStatments_delete(loop);
  1011. return FALSE;
  1012. }
  1013. skip_spaces(p, not_evaled);
  1014. vector_add(loops, loop);
  1015. }
  1016. command->mKind = kIf;
  1017. command->mExtra = sIf_new(MANAGED conditions, MANAGED loops);
  1018. return TRUE;
  1019. }
  1020. /// while?????
  1021. static BOOL read_command_parse_while_statment(char** p, sCommand* command, sStatment* statment, string_obj* not_evaled, int* read_end_of_statment, char* sname, int* sline)
  1022. {
  1023. skip_spaces(p, not_evaled);
  1024. if(**p != '(') {
  1025. err_msg("expected (", sname, *sline);
  1026. return FALSE;
  1027. }
  1028. /// ??????? ///
  1029. string_obj* str = STRING_NEW("");
  1030. int read_end_of_statment2 = -1;
  1031. if(!read_until_next_close_character('(', ')', p, str, &read_end_of_statment2, FALSE, sname, sline)) {
  1032. string_delete(str);
  1033. return FALSE;
  1034. }
  1035. string_push_back(not_evaled, string_c_str(str));
  1036. string_erase(str, 0, 1);
  1037. string_trunc(str, string_length(str)-1);
  1038. sStatments* conditions = STATMENTS_NEW();
  1039. if(!parse(string_c_str(str), sname, sline, conditions))
  1040. {
  1041. sStatments_delete(conditions);
  1042. string_delete(str);
  1043. return FALSE;
  1044. }
  1045. string_delete(str);
  1046. while(**p) {
  1047. if(**p == '\n') {
  1048. (*sline)++;
  1049. string_push_back2(not_evaled, **p);
  1050. (*p)++;
  1051. }
  1052. else if(**p == ' ' || **p == '\t') {
  1053. string_push_back2(not_evaled, **p);
  1054. (*p)++;
  1055. }
  1056. else {
  1057. break;
  1058. }
  1059. }
  1060. /// ???????? ///
  1061. sStatments* loops = STATMENTS_NEW();
  1062. if(**p == '(') {
  1063. string_obj* str = STRING_NEW("");
  1064. if(!read_block(p, str, NULL, not_evaled, FALSE, sname, sline)) {
  1065. sStatments_delete(conditions);
  1066. sStatments_delete(loops);
  1067. string_delete(str);
  1068. return FALSE;
  1069. }
  1070. if(!parse(string_c_str(str), sname, sline, loops))
  1071. {
  1072. string_delete(str);
  1073. sStatments_delete(conditions);
  1074. sStatments_delete(loops);
  1075. return FALSE;
  1076. }
  1077. string_delete(str);
  1078. }
  1079. else {
  1080. err_msg("expected block.", sname, *sline);
  1081. sStatments_delete(conditions);
  1082. sStatments_delete(loops);
  1083. return FALSE;
  1084. }
  1085. command->mKind = kWhile;
  1086. // ??????mNotEvaled????????????
  1087. // ???command??????
  1088. command->mExtra = sWhile_new(MANAGED conditions, MANAGED loops);
  1089. return TRUE;
  1090. }
  1091. /// ?????????
  1092. static BOOL read_command(char** p, sCommand* command, sStatment* statment, string_obj* not_evaled, int* read_end_of_statment, char* sname, int* sline)
  1093. {
  1094. while(**p) {
  1095. string_obj* buf = STRING_NEW("");
  1096. if(!read_one_argument(p, buf, not_evaled, read_end_of_statment, command, sname, sline, TRUE))
  1097. {
  1098. string_delete(buf);
  1099. return FALSE;
  1100. }
  1101. /// ??????? ///
  1102. if(strcmp(string_c_str(buf), "") != 0) {
  1103. if(vector_size(command->mArgs) == 0) {
  1104. if(strcmp(string_c_str(buf), "if") == 0) {
  1105. if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
  1106. {
  1107. return FALSE;
  1108. }
  1109. string_push_back(statment->mTitle, string_c_str(buf));
  1110. string_push_back(statment->mTitle, " ");
  1111. if(!read_command_parse_if_statment(p, command, statment, not_evaled, read_end_of_statment, sname, sline))
  1112. {
  1113. return FALSE;
  1114. }
  1115. }
  1116. else if(strcmp(string_c_str(buf), "while") == 0) {
  1117. if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
  1118. {
  1119. return FALSE;
  1120. }
  1121. string_push_back(statment->mTitle, string_c_str(buf));
  1122. string_push_back(statment->mTitle, " ");
  1123. if(!read_command_parse_while_statment(p, command, statment, not_evaled, read_end_of_statment, sname, sline))
  1124. {
  1125. return FALSE;
  1126. }
  1127. }
  1128. else {
  1129. if(vector_size(statment->mCommands) == 0 && strcmp(string_c_str(buf), "!") == 0)
  1130. {
  1131. statment->mRCodeReverse = TRUE;
  1132. }
  1133. if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
  1134. {
  1135. return FALSE;
  1136. }
  1137. string_push_back(statment->mTitle, string_c_str(buf));
  1138. string_push_back(statment->mTitle, " ");
  1139. }
  1140. }
  1141. else {
  1142. if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
  1143. {
  1144. return FALSE;
  1145. }
  1146. string_push_back(statment->mTitle, string_c_str(buf));
  1147. string_push_back(statment->mTitle, " ");
  1148. }
  1149. }
  1150. else {
  1151. /// ?????
  1152. if(**p == '\'') {
  1153. string_push_back(not_evaled, "''");
  1154. (*p)+=2;
  1155. if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
  1156. {
  1157. return FALSE;
  1158. }
  1159. string_push_back(statment->mTitle, "'");
  1160. string_push_back(statment->mTitle, " ");
  1161. continue;
  1162. }
  1163. else if(**p == '"') {
  1164. string_push_back(not_evaled, "\"\"");
  1165. (*p)+=2;
  1166. /// ???????????????? ///
  1167. if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
  1168. {
  1169. return FALSE;
  1170. }
  1171. string_push_back(statment->mTitle, "\"\"");
  1172. string_push_back(statment->mTitle, " ");
  1173. continue;
  1174. }
  1175. else {
  1176. string_delete(buf);
  1177. }
  1178. }
  1179. /// ?????????? ///
  1180. if((**p == '@' && *(*p+1) == '(') || (**p == '@' && *(*p+1) == '@' && *(*p+2) == '(') || (**p == '@' && *(*p+1) == '@' && *(*p+2) >= 'a' && *(*p+2) <= 'z' && *(*p+3) == '('))
  1181. {
  1182. string_push_back2(not_evaled, **p);
  1183. (*p)++;
  1184. BOOL double_;
  1185. enum eLineField lf;
  1186. if(**p == '@') {
  1187. string_push_back2(not_evaled, **p);
  1188. (*p)++;
  1189. double_ = TRUE;
  1190. if(**p == '(') {
  1191. lf = kLF;
  1192. }
  1193. else if(*(*p+1) == 'a') {
  1194. lf = kBel;
  1195. string_push_back2(not_evaled, **p);
  1196. (*p)++;
  1197. }
  1198. else if(*(*p+1) == 'm') {
  1199. lf = kCR;
  1200. string_push_back2(not_evaled, **p);
  1201. (*p)++;
  1202. }
  1203. else if(*(*p+1) == 'w') {
  1204. lf = kCRLF;
  1205. string_push_back2(not_evaled, **p);
  1206. (*p)++;
  1207. }
  1208. else {
  1209. lf = kLF;
  1210. string_push_back2(not_evaled, **p);
  1211. (*p)++;
  1212. }
  1213. }
  1214. else if(**p == '(') {
  1215. double_ = FALSE;
  1216. lf = kLF;
  1217. }
  1218. string_obj* str = STRING_NEW("");
  1219. int read_end_of_statment = -1;
  1220. if(!read_until_next_close_character('(', ')', p, str, &read_end_of_statment, FALSE, sname, sline)) {
  1221. string_delete(str);
  1222. return FALSE;
  1223. }
  1224. string_push_back(not_evaled, string_c_str(str));
  1225. string_push_back(statment->mTitle, string_c_str(str));
  1226. string_erase(str, 0, 1);
  1227. string_trunc(str, string_length(str)-1);
  1228. sStatments* statments = STATMENTS_NEW();
  1229. if(!parse(string_c_str(str), sname, sline, statments))
  1230. {
  1231. string_delete(str);
  1232. sStatments_delete(statments);
  1233. return FALSE;
  1234. }
  1235. string_delete(str);
  1236. if(double_) {
  1237. if(!add_arg_to_command(command, ARG_NEW(4, MANAGED sAtCommand_new(MANAGED statments, lf)), sname, sline))
  1238. {
  1239. return FALSE;
  1240. }
  1241. }
  1242. else {
  1243. if(!add_arg_to_command(command, ARG_NEW(2, MANAGED statments), sname, sline))
  1244. {
  1245. return FALSE;
  1246. }
  1247. }
  1248. }
  1249. else if(**p == '>') {
  1250. /// ?????? ///
  1251. if(*(*p+1) == '(') {
  1252. string_push_back2(not_evaled, **p);
  1253. (*p)++;
  1254. string_obj* cmd = STRING_NEW("");
  1255. if(!read_until_next_close_character('(', ')', p, cmd, read_end_of_statment, FALSE, sname, sline)) {
  1256. string_delete(cmd);
  1257. return FALSE;
  1258. }
  1259. string_push_back(not_evaled, string_c_str(cmd));
  1260. string_erase(cmd, 0, 1); // (???
  1261. string_trunc(cmd, string_length(cmd)-1); // )???
  1262. sStatments* statments = STATMENTS_NEW();
  1263. if(!parse(string_c_str(cmd), sname, sline, statments)) {
  1264. sStatments_delete(statments);
  1265. string_delete(cmd);
  1266. return FALSE;
  1267. }
  1268. string_delete(cmd);
  1269. if(vector_size(command->mArgs) == 0) {
  1270. err_msg("command name must be determined staticaly", sname, *sline);
  1271. sStatments_delete(statments);
  1272. return FALSE;
  1273. }
  1274. if(!add_arg_to_command(command, ARG_NEW(8, MANAGED statments), sname, sline))
  1275. {
  1276. return FALSE;
  1277. }
  1278. }
  1279. /// ??????
  1280. else if(*(*p+1) == '>') {
  1281. string_push_back(not_evaled, ">>");
  1282. (*p)+=2;
  1283. int fd = 1;
  1284. enum eRedirect type = kRedirectAppend;
  1285. skip_spaces(p, not_evaled);
  1286. if(!add_arg_to_command(command, ARG_NEW(9, MANAGED sRedirect_new(type, fd)), sname, sline))
  1287. {
  1288. return FALSE;
  1289. }
  1290. }
  1291. /// ??????
  1292. else {
  1293. string_push_back(not_evaled, ">");
  1294. (*p)++;
  1295. int fd = 1;
  1296. enum eRedirect type = kRedirectOverwrite;
  1297. skip_spaces(p, not_evaled);
  1298. if(!add_arg_to_command(command, ARG_NEW(9, MANAGED sRedirect_new(type, fd)), sname, sline))
  1299. {
  1300. return FALSE;
  1301. }
  1302. }
  1303. }
  1304. else if(**p == '<') {
  1305. /// ????????
  1306. if(*(*p+1) == '<') {
  1307. string_push_back2(not_evaled, **p);
  1308. (*p)++;
  1309. string_push_back2(not_evaled, **p);
  1310. (*p)++;
  1311. skip_spaces(p, not_evaled);
  1312. BOOL expand_env = TRUE;
  1313. BOOL squote = FALSE;
  1314. BOOL dquote = FALSE;
  1315. if(**p == '\'') {
  1316. squote = TRUE;
  1317. string_push_back2(not_evaled, **p);
  1318. (*p)++;
  1319. }
  1320. else if(**p == '"') {
  1321. dquote = TRUE;
  1322. string_push_back2(not_evaled, **p);
  1323. (*p)++;
  1324. }
  1325. string_obj* name = STRING_NEW("");
  1326. while(**p) {
  1327. if(**p == '\n') {
  1328. string_push_back2(not_evaled, **p);
  1329. (*p)++;
  1330. break;
  1331. }
  1332. else if(**p == ' ' || **p == '\t') {
  1333. skip_spaces(p, not_evaled);
  1334. if(**p != '\n') {
  1335. err_msg("invalid here document name1", sname, *sline);
  1336. string_delete(name);
  1337. return FALSE;
  1338. }
  1339. string_push_back2(not_evaled, **p);
  1340. (*p)++;
  1341. break;
  1342. }
  1343. else if(**p >='A' && ** p <= 'Z' || **p >='a' && **p <='z')
  1344. {
  1345. string_push_back2(name, **p);
  1346. string_push_back2(not_evaled, **p);
  1347. (*p)++;
  1348. }
  1349. else if(dquote && **p == '"') {
  1350. expand_env = TRUE;
  1351. dquote = FALSE;
  1352. string_push_back2(not_evaled, **p);
  1353. (*p)++;
  1354. skip_spaces(p, not_evaled);
  1355. if(**p != '\n') {
  1356. err_msg("invalid here document name2", sname, *sline);
  1357. string_delete(name);
  1358. return FALSE;
  1359. }
  1360. string_push_back2(not_evaled, **p);
  1361. (*p)++;
  1362. break;
  1363. }
  1364. else if(squote && **p == '\'') {
  1365. expand_env = FALSE;
  1366. squote = FALSE;
  1367. string_push_back2(not_evaled, **p);
  1368. (*p)++;
  1369. skip_spaces(p, not_evaled);
  1370. if(**p != '\n') {
  1371. err_msg("invalid here document name3", sname, *sline);
  1372. string_delete(name);
  1373. return FALSE;
  1374. }
  1375. string_push_back2(not_evaled, **p);
  1376. (*p)++;
  1377. break;
  1378. }
  1379. else {
  1380. err_msg("invalid here document name4", sname, *sline);
  1381. string_delete(name);
  1382. return FALSE;
  1383. }
  1384. }
  1385. if(dquote || squote|| string_c_str(name)[0] == 0) {
  1386. err_msg("invalid here document name5", sname, *sline);
  1387. string_delete(name);
  1388. return FALSE;
  1389. }
  1390. string_obj* text = STRING_NEW("");
  1391. string_obj* line = STRING_NEW("");
  1392. while(**p) {
  1393. if(**p == '\n') {
  1394. string_push_back2(not_evaled, **p);
  1395. (*p)++;
  1396. string_push_back(text, string_c_str(line));
  1397. string_push_back2(text, '\n');
  1398. string_put(line, "");
  1399. }
  1400. else {
  1401. string_push_back2(line, **p);
  1402. string_push_back2(not_evaled, **p);
  1403. (*p)++;
  1404. if(strstr(string_c_str(line), string_c_str(name)) == string_c_str(line))
  1405. {
  1406. break;
  1407. }
  1408. }
  1409. }
  1410. if(vector_size(command->mArgs) == 0) {
  1411. err_msg("command name must be determined staticaly", sname, *sline);
  1412. string_delete(line);
  1413. string_delete(name);
  1414. return FALSE;
  1415. }
  1416. if(!add_arg_to_command(command, ARG_NEW(7, sHereDoc_new(MANAGED text, expand_env)), sname, sline))
  1417. {
  1418. string_delete(line);
  1419. string_delete(name);
  1420. return FALSE;
  1421. }
  1422. string_delete(line);
  1423. string_delete(name);
  1424. }
  1425. /// ?????? ///
  1426. else if(*(*p+1) == '(') {
  1427. string_push_back2(not_evaled, **p);
  1428. (*p)++;
  1429. string_obj* cmd = STRING_NEW("");
  1430. if(!read_until_next_close_character('(', ')', p, cmd, read_end_of_statment, FALSE, sname, sline)) {
  1431. string_delete(cmd);
  1432. return FALSE;
  1433. }
  1434. string_push_back(not_evaled, string_c_str(cmd));
  1435. string_erase(cmd, 0, 1); // (???
  1436. string_trunc(cmd, string_length(cmd)-1); // )???
  1437. sStatments* statments = STATMENTS_NEW();
  1438. if(!parse(string_c_str(cmd), sname, sline, statments)) {
  1439. string_delete(cmd);
  1440. sStatments_delete(statments);
  1441. return FALSE;
  1442. }
  1443. string_delete(cmd);
  1444. if(!add_arg_to_command(command, ARG_NEW(6, MANAGED statments), sname, sline))
  1445. {
  1446. return FALSE;
  1447. }
  1448. }
  1449. /// ??????
  1450. else {
  1451. (*p)++;
  1452. string_push_back(not_evaled, "<");
  1453. int fd = 0;
  1454. enum eRedirect type = kRedirectInput;
  1455. skip_spaces(p, not_evaled);
  1456. if(!add_arg_to_command(command, ARG_NEW(9, MANAGED sRedirect_new(type, fd)), sname, sline))
  1457. {
  1458. return FALSE;
  1459. }
  1460. }
  1461. }
  1462. /// ?????? ///
  1463. else if(**p == '%') {
  1464. if(*(*p+1) == '>' && *(*p+2) == '>') {
  1465. string_push_back(not_evaled, "%>>");
  1466. break;
  1467. }
  1468. else if(*(*p+1) == '2' && *(*p+2) == '>' && *(*p+3) == '>')
  1469. {
  1470. string_push_back(not_evaled, "%2>>");
  1471. (*p)+=4;
  1472. int fd = 2;
  1473. enum eRedirect type = kRedirectAppend;
  1474. skip_spaces(p, not_evaled);
  1475. if(!add_arg_to_command(command, ARG_NEW(9, MANAGED sRedirect_new(type, fd)), sname, sline))
  1476. {
  1477. return FALSE;
  1478. }
  1479. }
  1480. else if(*(*p+1) == '2' && *(*p+2) == '>') {
  1481. string_push_back(not_evaled, "%2>");
  1482. (*p)+=3;
  1483. int fd = 2;
  1484. enum eRedirect type = kRedirectOverwrite;
  1485. skip_spaces(p, not_evaled);
  1486. if(vector_size(command->mArgs) == 0) {
  1487. err_msg("command name must be determined staticaly", sname, *sline);
  1488. return FALSE;
  1489. }
  1490. if(!add_arg_to_command(command, ARG_NEW(9, MANAGED sRedirect_new(type, fd)), sname, sline))
  1491. {
  1492. return FALSE;
  1493. }
  1494. }
  1495. else if(*(*p+1) == '>') {
  1496. string_push_back(not_evaled, "%>");
  1497. (*p)+=2;
  1498. int fd = 0;
  1499. enum eRedirect type = kRedirectErrAndOutput;
  1500. skip_spaces(p, not_evaled);
  1501. if(!add_arg_to_command(command, ARG_NEW(9, MANAGED sRedirect_new(type, fd)), sname, sline))
  1502. {
  1503. return FALSE;
  1504. }
  1505. }
  1506. else {
  1507. char buf[128];
  1508. snprintf(buf, 128, "unexpected token1 -->%c\n", **p);
  1509. err_msg(buf, sname, *sline);
  1510. return FALSE;
  1511. }
  1512. }
  1513. /// ?? ///
  1514. else if(**p == ' ' || **p == '\t') {
  1515. skip_spaces(p, not_evaled);
  1516. }
  1517. /// ?????????? ///
  1518. else if(**p == '(') {
  1519. /// ???????????????? ///
  1520. if(vector_size(command->mArgs) == 0) {
  1521. string_obj* str = STRING_NEW("");
  1522. int read_end_of_statment = -1;
  1523. if(!read_until_next_close_character('(', ')', p, str, &read_end_of_statment, FALSE, sname, sline)) {
  1524. string_delete(str);
  1525. return FALSE;
  1526. }
  1527. string_push_back(not_evaled, string_c_str(str));
  1528. string_push_back(statment->mTitle, string_c_str(str));
  1529. string_erase(str, 0, 1);
  1530. string_trunc(str, string_length(str)-1);
  1531. sStatments* statments = STATMENTS_NEW();
  1532. if(!parse(string_c_str(str), sname, sline, statments))
  1533. {
  1534. string_delete(str);
  1535. sStatments_delete(statments);
  1536. return FALSE;
  1537. }
  1538. string_delete(str);
  1539. command->mKind= kSubshell;
  1540. if(!add_arg_to_command(command, ARG_NEW(0, MANAGED STRING_NEW("subshell")), sname, sline))
  1541. {
  1542. return FALSE;
  1543. }
  1544. command->mExtra = sSubshell_new(MANAGED statments);
  1545. }
  1546. /// ???? ///
  1547. else {
  1548. string_obj* str = STRING_NEW("");
  1549. vector_obj* args = VECTOR_NEW(10);
  1550. if(!read_block(p, str, args, not_evaled, FALSE, sname, sline)) {
  1551. int i;
  1552. for(i=0; i<vector_size(args); i++) {
  1553. string_delete(vector_item(args, i));
  1554. }
  1555. vector_delete(args);
  1556. string_delete(str);
  1557. return FALSE;
  1558. }
  1559. sStatments* block = STATMENTS_NEW();
  1560. if(!parse(string_c_str(str), sname, sline, block))
  1561. {
  1562. sStatments_delete(block);
  1563. int i;
  1564. for(i=0; i<vector_size(args); i++) {
  1565. string_delete(vector_item(args, i));
  1566. }
  1567. vector_delete(args);
  1568. string_delete(str);
  1569. return FALSE;
  1570. }
  1571. int count = 0;
  1572. int i;
  1573. for(i=0; i<vector_size(command->mArgs); i++) {
  1574. sArg* arg = vector_item(command->mArgs, i);
  1575. if(arg->mKind != 5) {
  1576. count++;
  1577. }
  1578. }
  1579. if(vector_size(command->mArgs) == 0) {
  1580. err_msg("command name must be determined staticaly", sname, *sline);
  1581. sStatments_delete(block);
  1582. int i;
  1583. for(i=0; i<vector_size(args); i++) {
  1584. string_delete(vector_item(args, i));
  1585. }
  1586. vector_delete(args);
  1587. string_delete(str);
  1588. return FALSE;
  1589. }
  1590. if(!add_arg_to_command(command, ARG_NEW(5, MANAGED sBlock_new(MANAGED block, MANAGED args, count-1)), sname, sline))
  1591. {
  1592. string_delete(str);
  1593. return FALSE;
  1594. }
  1595. string_push_back(statment->mTitle, string_c_str(str));
  1596. string_push_back(statment->mTitle, " ");
  1597. skip_spaces(p, not_evaled);
  1598. string_delete(str);
  1599. }
  1600. }
  1601. else {
  1602. break;
  1603. }
  1604. }
  1605. return TRUE;
  1606. }
  1607. /// ??????
  1608. static BOOL read_statment(char**p, sStatment* statment, string_obj* not_evaled, int* read_end_of_statment, char* sname, int* sline)
  1609. {
  1610. /// ?? ///
  1611. if(**p == '!') {
  1612. string_push_back2(not_evaled, '!');
  1613. (*p)++;
  1614. statment->mRCodeReverse = TRUE;
  1615. skip_spaces(p, not_evaled);
  1616. }
  1617. /// ????????, STDIN??? ///
  1618. if(**p == '|' && *(*p+1) == '>') {
  1619. string_push_back2(not_evaled, **p);
  1620. (*p)++;
  1621. string_push_back2(not_evaled, **p);
  1622. (*p)++;
  1623. statment->mGlobalPipeIn = 1;
  1624. skip_spaces(p, not_evaled);
  1625. }
  1626. else if(**p == '|' && *(*p+1) >= '0' && *(*p+1) <= '9' && *(*p+2) == '>') {
  1627. string_push_back2(not_evaled, **p);
  1628. (*p)++;
  1629. int num = **p - '0';
  1630. string_push_back2(not_evaled, **p);
  1631. (*p)++;
  1632. string_push_back2(not_evaled, **p);
  1633. (*p)++;
  1634. statment->mGlobalPipeIn = 4;
  1635. statment->mGlobalPipeInNum = num;
  1636. skip_spaces(p, not_evaled);
  1637. }
  1638. else if(**p == '|' && *(*p+1) != '|') {
  1639. string_push_back2(not_evaled, **p);
  1640. (*p)++;
  1641. skip_spaces(p, not_evaled);
  1642. statment->mSTDINPipe = TRUE;
  1643. }
  1644. while(**p) {
  1645. sCommand* command = COMMAND_NEW();
  1646. if(!read_command(p, command, statment, not_evaled, read_end_of_statment, sname, sline))
  1647. {
  1648. sCommand_delete(command);
  1649. return FALSE;
  1650. }
  1651. /// ???? ///
  1652. if(*read_end_of_statment == -1
  1653. && vector_size((command)->mArgs) > 0)
  1654. {
  1655. vector_add(statment->mCommands, MANAGED command);
  1656. }
  1657. else {
  1658. sCommand_delete(command);
  1659. }
  1660. if(**p == '|' && *(*p+1) != '>' && (*(*p+1) < '0' || *(*p+1) > '9') && *(*p+1) != '|')
  1661. {
  1662. string_push_back(not_evaled, "|");
  1663. (*p)++;
  1664. }
  1665. else {
  1666. break;
  1667. }
  1668. }
  1669. return TRUE;
  1670. }
  1671. /// ?????gErrMsg??????????????????????
  1672. BOOL parse(char* cmdline, char* sname, int* sline, sStatments* statments)
  1673. {
  1674. char* p = cmdline;
  1675. string_put(statments->mSource, cmdline);
  1676. while(*p) {
  1677. /// ?????????? ///
  1678. while(*p == ' ' || *p == '\t' || *p == '\n' && (*sline)++) { p++; }
  1679. /// ?? ///
  1680. sStatment* statment = STATMENT_NEW();
  1681. string_obj* not_evaled = STRING_NEW("");
  1682. int read_end_of_statment = -1;
  1683. // ????????????????
  1684. // ???????????????????????
  1685. int line_of_head = *sline;
  1686. if(!read_statment(&p, statment, not_evaled, &read_end_of_statment, sname, sline))
  1687. {
  1688. sStatment_delete(statment);
  1689. string_delete(not_evaled);
  1690. return FALSE;
  1691. }
  1692. /// ????????
  1693. if(*p == '|' && *(p+1) >= '0' && *(p+1) <= '9' && *(p+2) == '>') {
  1694. string_push_back(not_evaled, "|");
  1695. p++;
  1696. int num = *p - '0';
  1697. string_push_back2(not_evaled, *p);
  1698. p++;
  1699. string_push_back2(not_evaled, *p);
  1700. p++;
  1701. if(*p == '>') {
  1702. string_push_back(not_evaled, ">");
  1703. p++;
  1704. statment->mGlobalPipeOut = 0x14;
  1705. statment->mGlobalPipeOutNum = num;
  1706. }
  1707. else {
  1708. statment->mGlobalPipeOut = 4;
  1709. statment->mGlobalPipeOutNum = num;
  1710. }
  1711. skip_spaces(&p, not_evaled);
  1712. }
  1713. else if(*p == '|' && *(p+1) == '>') {
  1714. string_push_back(not_evaled, "|");
  1715. p++;
  1716. string_push_back(not_evaled, ">");
  1717. p++;
  1718. if(*p == '>') {
  1719. string_push_back(not_evaled, ">");
  1720. p++;
  1721. statment->mGlobalPipeOut = 0x11;
  1722. }
  1723. else {
  1724. statment->mGlobalPipeOut = 0x01;
  1725. }
  1726. skip_spaces(&p, not_evaled);
  1727. }
  1728. /// ?????
  1729. if(*p == '&' && *(p+1) == '&') {
  1730. string_push_back(not_evaled, "&&");
  1731. p+=2;
  1732. statment->mTerminated = kTAndAnd;
  1733. statment->mLine = line_of_head;
  1734. string_put(statment->mFName, sname);
  1735. skip_spaces(&p, not_evaled);
  1736. }
  1737. else if(*p == '|' && *(p+1) == '|') {
  1738. string_push_back(not_evaled, "||");
  1739. p+=2;
  1740. statment->mTerminated = kTOrOr;
  1741. statment->mLine = line_of_head;
  1742. string_put(statment->mFName, sname);
  1743. skip_spaces(&p, not_evaled);
  1744. }
  1745. else if(*p == '&') {
  1746. string_push_back2(not_evaled, '&');
  1747. p++;
  1748. statment->mBackground = TRUE;
  1749. statment->mTerminated = kTNormal;
  1750. statment->mLine = line_of_head;
  1751. string_put(statment->mFName, sname);
  1752. skip_spaces(&p, not_evaled);
  1753. }
  1754. else if(*p == '\n') {
  1755. statment->mTerminated = kTNormal;
  1756. statment->mLine = line_of_head;
  1757. string_put(statment->mFName, sname);
  1758. (*sline)++;
  1759. string_push_back2(not_evaled, '\n');
  1760. p++;
  1761. skip_spaces(&p, not_evaled);
  1762. }
  1763. else if(*p == ';') {
  1764. statment->mTerminated = kTNormal;
  1765. statment->mLine = line_of_head;
  1766. string_put(statment->mFName, sname);
  1767. string_push_back2(not_evaled, ';');
  1768. p++;
  1769. skip_spaces(&p, not_evaled);
  1770. }
  1771. else if(*p == 0) {
  1772. statment->mTerminated = kTNormal;
  1773. statment->mLine = line_of_head;
  1774. string_put(statment->mFName, sname);
  1775. }
  1776. else {
  1777. char buf[128];
  1778. snprintf(buf, 128, "unexpected token3 -->%c\n", *p);
  1779. err_msg(buf, sname, *sline);
  1780. sStatment_delete(statment);
  1781. string_delete(not_evaled);
  1782. return FALSE;
  1783. }
  1784. /// ????????????
  1785. if(read_end_of_statment != -1) {
  1786. statment->mNotEvaled = MANAGED not_evaled;
  1787. }
  1788. else {
  1789. string_delete(not_evaled);
  1790. }
  1791. // ???????????????????????????
  1792. if(vector_size(statment->mCommands) > 0 || statment->mNotEvaled != NULL) {
  1793. vector_add(statments->mStatments, MANAGED statment);
  1794. }
  1795. else {
  1796. sStatment_delete(statment);
  1797. }
  1798. }
  1799. return TRUE;
  1800. }
  1801. // ????????????
  1802. static BOOL expand_env_get_quoted_str(char* fname, string_obj* quoted_fname, char* sname, int* sline)
  1803. {
  1804. char* p = fname;
  1805. while(*p) {
  1806. if(gKitutukiSigInt) {
  1807. gKitutukiSigInt = FALSE;
  1808. err_msg("signal interrupt", sname, *sline);
  1809. return FALSE;
  1810. }
  1811. if(*p == '\n') {
  1812. string_push_back(quoted_fname, "\\n");
  1813. p++;
  1814. }
  1815. else if(*p == '\r') {
  1816. string_push_back(quoted_fname, "\\r");
  1817. p++;
  1818. }
  1819. else if(*p == '\t') {
  1820. string_push_back(quoted_fname, "\\t");
  1821. p++;
  1822. }
  1823. else if(*p == '\a') {
  1824. string_push_back(quoted_fname, "\\a");
  1825. p++;
  1826. }
  1827. else if(*p==' ' || *p=='*' || *p=='&' || *p=='~'
  1828. || *p=='#' || *p =='$' || *p=='(' || *p==')'
  1829. || *p=='\\' || *p=='|' || *p=='[' || *p==']' || *p=='{'
  1830. || *p=='}' || *p==';'
  1831. || *p=='\'' || *p=='"' || *p=='<' || *p=='>' || *p=='?'
  1832. || *p=='%' || *p=='@')
  1833. {
  1834. string_push_back2(quoted_fname, '\\');
  1835. string_push_back2(quoted_fname, *p++);
  1836. }
  1837. else {
  1838. string_push_back2(quoted_fname, *p++);
  1839. }
  1840. }
  1841. return TRUE;
  1842. }
  1843. BOOL expand_env(char* p, string_obj* out, sRFd* rfd, char* sname, int* sline, sObject* object)
  1844. {
  1845. BOOL squote = FALSE;
  1846. BOOL dquote = FALSE;
  1847. while(*p) {
  1848. if(gKitutukiSigInt) {
  1849. err_msg("signal interrupt", sname, *sline);
  1850. gKitutukiSigInt = FALSE;
  1851. return FALSE;
  1852. }
  1853. /// ???? ///
  1854. if(!squote && !dquote && *p == '\\') {
  1855. string_push_back2(out, *p++);
  1856. if(*p == 0) {
  1857. err_msg("unexpected end after quote", sname, *sline);
  1858. return FALSE;
  1859. }
  1860. string_push_back2(out, *p++);
  1861. }
  1862. /// ???????? ///
  1863. else if(!dquote && *p == '\'') {
  1864. squote = !squote;
  1865. string_push_back2(out, *p++);
  1866. }
  1867. /// ??????? ///
  1868. else if(!squote && *p == '"') {
  1869. dquote = !dquote;
  1870. string_push_back2(out, *p++);
  1871. }
  1872. /// ??????
  1873. else if(!squote && *p == '$') {
  1874. /// ?????? $( ///
  1875. if(*(p+1) == '$' && *(p+2) == '(' || *(p+1) == '(')
  1876. {
  1877. BOOL quote;
  1878. if(*(p+1) == '$') {
  1879. p+=2;
  1880. quote = FALSE;
  1881. }
  1882. else {
  1883. p++;
  1884. quote = TRUE;
  1885. }
  1886. string_obj* str = STRING_NEW("");
  1887. int read_end_of_statment = -1;
  1888. if(!read_until_next_close_character('(', ')', &p, str, &read_end_of_statment, FALSE, sname, sline))
  1889. {
  1890. string_delete(str);
  1891. return FALSE;
  1892. }
  1893. string_erase(str, 0, 1); // (???
  1894. string_trunc(str, string_length(str)-1); // )???
  1895. sWFd* pipeout = WFD_NEW(-1);
  1896. char* fname = MALLOC(strlen(sname) + 256);
  1897. snprintf(fname, strlen(sname) + 256, "%s %d: expand command", sname, *sline);
  1898. int rcode = saphire_shell5(pipeout, string_c_str(str), fname, rfd, object);
  1899. FREE(fname);
  1900. string_delete(str);
  1901. if(rcode < 0) {
  1902. sWFd_delete(pipeout);
  1903. return FALSE;
  1904. }
  1905. if(quote) {
  1906. string_obj* quoted = STRING_NEW("");
  1907. if(!expand_env_get_quoted_str(pipeout->mBuffer, quoted, sname, sline))
  1908. {
  1909. sWFd_delete(pipeout);
  1910. string_delete(quoted);
  1911. return FALSE;
  1912. }
  1913. string_push_back(out, string_c_str(quoted));
  1914. string_delete(quoted);
  1915. }
  1916. else {
  1917. string_push_back(out, pipeout->mBuffer);
  1918. }
  1919. sWFd_delete(pipeout);
  1920. }
  1921. /// var, global, export ?? ///
  1922. else {
  1923. BOOL quote;
  1924. if(*(p+1) == '$') {
  1925. p+=2;
  1926. quote = FALSE;
  1927. }
  1928. else {
  1929. p++;
  1930. quote = TRUE;
  1931. }
  1932. if((*p >= '0' && *p <= '9' || *p >= 'a' && *p <= 'z' || *p >= 'A' && *p <= 'Z' || *p == '_') || *p == '{') {
  1933. string_obj* name = STRING_NEW("");
  1934. BOOL bracket;
  1935. if(*p == '{') {
  1936. int read_end_of_statment = -1;
  1937. if(!read_until_next_close_character('{', '}',&p, name, &read_end_of_statment, TRUE, sname, sline)) {
  1938. string_delete(name);
  1939. return FALSE;
  1940. }
  1941. string_erase(name, 0, 1);
  1942. string_trunc(name, string_length(name)-1);
  1943. bracket = TRUE;
  1944. }
  1945. else {
  1946. bracket = FALSE;
  1947. while(*p) {
  1948. if(*p >= '0' && *p <= '9' || *p >= 'a' && *p <= 'z' || *p >= 'A' && *p <= 'Z' || *p == '_') {
  1949. string_push_back2(name, *p); // $
  1950. p++;
  1951. }
  1952. else {
  1953. break;
  1954. }
  1955. }
  1956. }
  1957. char* name2 = string_c_str(name);
  1958. /// Var ///
  1959. string_obj* var = saphire_get_local_var(name2, object);
  1960. char* env = NULL;
  1961. if(var == NULL) {
  1962. var = saphire_get_global_var(name2, object, FALSE);
  1963. if(var == NULL) {
  1964. /// export ///
  1965. env = getenv(name2);
  1966. if(env) {
  1967. var = STRING_NEW(env);
  1968. }
  1969. else {
  1970. var = NULL;
  1971. }
  1972. }
  1973. }
  1974. if(var) {
  1975. if(quote) {
  1976. string_obj* quoted = STRING_NEW("");
  1977. if(!expand_env_get_quoted_str(string_c_str(var), quoted, sname, sline))
  1978. {
  1979. string_delete(name);
  1980. if(env) string_delete(var);
  1981. return FALSE;
  1982. }
  1983. string_push_back(out, string_c_str(quoted));
  1984. string_delete(quoted);
  1985. }
  1986. else {
  1987. string_push_back(out, string_c_str(var));
  1988. }
  1989. if(env) string_delete(var);
  1990. }
  1991. string_delete(name);
  1992. }
  1993. else {
  1994. if(quote) {
  1995. string_push_back2(out, '$');
  1996. }
  1997. else {
  1998. string_push_back(out, "$$");
  1999. }
  2000. }
  2001. }
  2002. }
  2003. else if(squote || dquote) {
  2004. if(*p == 0) {
  2005. err_msg("close ' or \" before the end of statment", sname, *sline);
  2006. return FALSE;
  2007. }
  2008. string_push_back2(out, *p++);
  2009. }
  2010. /// ????????????
  2011. else if(*p == '<' && *(p+1) == '<') {
  2012. string_push_back2(out, *p);
  2013. p++;
  2014. string_push_back2(out, *p);
  2015. p++;
  2016. skip_spaces(&p, out);
  2017. BOOL squote = FALSE;
  2018. BOOL dquote = FALSE;
  2019. if(*p == '\'') {
  2020. squote = TRUE;
  2021. string_push_back2(out, *p);
  2022. p++;
  2023. }
  2024. else if(*p == '"') {
  2025. dquote = TRUE;
  2026. string_push_back2(out, *p);
  2027. p++;
  2028. }
  2029. string_obj* name = STRING_NEW("");
  2030. while(*p) {
  2031. if(*p == '\n') {
  2032. string_push_back2(out, *p);
  2033. p++;
  2034. break;
  2035. }
  2036. else if(*p == ' ' || *p == '\t') {
  2037. skip_spaces(&p, out);
  2038. if(*p != '\n') {
  2039. err_msg("invalid here document name7", sname, *sline);
  2040. string_delete(name);
  2041. return FALSE;
  2042. }
  2043. string_push_back2(out, *p);
  2044. p++;
  2045. break;
  2046. }
  2047. else if(*p >='A' && * p <= 'Z' || *p >='a' && *p <='z')
  2048. {
  2049. string_push_back2(name, *p);
  2050. string_push_back2(out, *p);
  2051. p++;
  2052. }
  2053. else if(dquote && *p == '"') {
  2054. dquote = FALSE;
  2055. string_push_back2(out, *p);
  2056. p++;
  2057. skip_spaces(&p, out);
  2058. if(*p != '\n') {
  2059. err_msg("invalid here document name8", sname, *sline);
  2060. string_delete(name);
  2061. return FALSE;
  2062. }
  2063. string_push_back2(out, *p);
  2064. p++;
  2065. break;
  2066. }
  2067. else if(squote && *p == '\'') {
  2068. squote = FALSE;
  2069. string_push_back2(out, *p);
  2070. p++;
  2071. skip_spaces(&p, out);
  2072. if(*p != '\n') {
  2073. err_msg("invalid here document name9", sname, *sline);
  2074. string_delete(name);
  2075. return FALSE;
  2076. }
  2077. string_push_back2(out, *p);
  2078. p++;
  2079. break;
  2080. }
  2081. else {
  2082. err_msg("invalid here document name", sname, *sline);
  2083. string_delete(name);
  2084. return FALSE;
  2085. }
  2086. }
  2087. if(dquote || squote|| string_c_str(name)[0] == 0) {
  2088. err_msg("invalid here document name10", sname, *sline);
  2089. string_delete(name);
  2090. return FALSE;
  2091. }
  2092. string_obj* line = STRING_NEW("");
  2093. while(*p) {
  2094. if(*p == '\n') {
  2095. string_push_back2(out, *p);
  2096. p++;
  2097. }
  2098. else {
  2099. string_push_back2(line, *p);
  2100. string_push_back2(out, *p);
  2101. p++;
  2102. if(strstr(string_c_str(line), string_c_str(name)) == string_c_str(line))
  2103. {
  2104. break;
  2105. }
  2106. }
  2107. }
  2108. string_delete(line);
  2109. string_delete(name);
  2110. }
  2111. /// ??????????????????
  2112. else if(*p == '(') {
  2113. int read_end_of_statment = -1;
  2114. if(!read_until_next_close_character('(', ')', &p, out, &read_end_of_statment, FALSE, sname, sline))
  2115. {
  2116. return FALSE;
  2117. }
  2118. }
  2119. else {
  2120. string_push_back2(out, *p++);
  2121. }
  2122. }
  2123. return TRUE;
  2124. }
  2125. BOOL expand_brace_expression(string_obj* tail, vector_obj* v, string_obj* start, string_obj* end, char** p, char* sname, int* sline)
  2126. {
  2127. string_obj* str = STRING_NEW("");
  2128. while(1) {
  2129. if(**p == '\\') {
  2130. (*p)++;
  2131. string_push_back2(str, '\\');
  2132. string_push_back2(str, **p);
  2133. (*p)++;
  2134. }
  2135. else if(**p == '{') {
  2136. (*p)++;
  2137. vector_obj* v2 = VECTOR_NEW(10);
  2138. string_obj* tail2 = STRING_NEW("");
  2139. string_obj* start2 = STRING_NEW("");
  2140. string_obj* end2 = STRING_NEW("");
  2141. if(!expand_brace_expression(tail2, v2, start2, end2, p, sname, sline)) {
  2142. string_delete(str);
  2143. string_delete(tail2);
  2144. string_delete(start2);
  2145. string_delete(end2);
  2146. int i;
  2147. for(i=0; i<vector_size(v2); i++) {
  2148. string_delete(vector_item(v2, i));
  2149. }
  2150. vector_delete(v2);
  2151. return FALSE;
  2152. }
  2153. if(**p == ',') { (*p)++; }
  2154. /// string
  2155. if(string_c_str(start2)[0] == 0) {
  2156. if(vector_size(v2) == 0) {
  2157. err_msg("invalid brace expression2", sname, *sline);
  2158. string_delete(str);
  2159. string_delete(tail2);
  2160. vector_delete(v2);
  2161. string_delete(start2);
  2162. string_delete(end2);
  2163. return FALSE;
  2164. }
  2165. int i;
  2166. for(i=0; i<vector_size(v2); i++) {
  2167. string_obj* str2 = STRING_NEW("");
  2168. string_push_back(str2, string_c_str(str));
  2169. string_push_back(str2, string_c_str(vector_item(v2, i)));
  2170. string_push_back(str2, string_c_str(tail2));
  2171. vector_add(v, str2);
  2172. }
  2173. }
  2174. /// number
  2175. else {
  2176. int start3 = atoi(string_c_str(start2));
  2177. int end3 = atoi(string_c_str(end2));
  2178. int num_len = strlen(string_c_str(start2));
  2179. if(start3 < 0) num_len--;
  2180. char buf2[1024];
  2181. buf2[0] = '%';
  2182. snprintf(buf2 + 1, 1023, "0%dd", num_len);
  2183. if(start3 < end3) {
  2184. int i;
  2185. for(i=start3; i<=end3; i++) {
  2186. string_obj* str2 = STRING_NEW("");
  2187. string_push_back(str2, string_c_str(str));
  2188. char buf[1024];
  2189. if(i < 0) {
  2190. buf[0] = '-';
  2191. snprintf(buf + 1, 1023, buf2, abs(i));
  2192. }
  2193. else {
  2194. snprintf(buf, 1024, buf2, i);
  2195. }
  2196. string_push_back(str2, buf);
  2197. string_push_back(str2, string_c_str(tail2));
  2198. vector_add(v, str2);
  2199. }
  2200. }
  2201. else if(start3 == end3) {
  2202. vector_add(v, STRING_NEW(string_c_str(start2)));
  2203. }
  2204. else {
  2205. int i;
  2206. for(i=start3; i>=end3; i--) {
  2207. string_obj* str2 = STRING_NEW("");
  2208. string_push_back(str2, string_c_str(str));
  2209. char buf[1024];
  2210. if(i < 0) {
  2211. buf[0] = '-';
  2212. snprintf(buf + 1, 1023, buf2, abs(i));
  2213. }
  2214. else {
  2215. snprintf(buf, 1024, buf2, i);
  2216. }
  2217. string_push_back(str2, buf);
  2218. string_push_back(str2, string_c_str(tail2));
  2219. vector_add(v, str2);
  2220. }
  2221. }
  2222. }
  2223. string_put(str, "");
  2224. string_delete(tail2);
  2225. int i;
  2226. for(i=0; i<vector_size(v2); i++) {
  2227. string_delete(vector_item(v2, i));
  2228. }
  2229. vector_delete(v2);
  2230. string_delete(start2);
  2231. string_delete(end2);
  2232. }
  2233. else if(**p == '}') {
  2234. (*p)++;
  2235. if(*(*p-2) == ',') {
  2236. vector_add(v, str);
  2237. }
  2238. else {
  2239. if(string_c_str(str)[0] == 0) {
  2240. string_delete(str);
  2241. }
  2242. else {
  2243. vector_add(v, str);
  2244. }
  2245. }
  2246. while(**p) {
  2247. if(**p == '\\') {
  2248. (*p)++;
  2249. string_push_back2(tail, '\\');
  2250. string_push_back2(tail, **p);
  2251. (*p)++;
  2252. }
  2253. else if(**p == ' ' || **p == '\t' || **p == '\n' || **p == ',' || **p=='>' || **p=='}' || **p=='&' || **p=='~' || **p=='#' || **p =='$' || **p=='(' || **p==')' || **p=='|' || **p==';' || **p=='\'' || **p=='"' || **p=='<' || **p=='%' || **p=='@')
  2254. {
  2255. break;
  2256. }
  2257. else {
  2258. string_push_back2(tail, **p);
  2259. (*p)++;
  2260. }
  2261. }
  2262. break;
  2263. }
  2264. else if(**p == ',') {
  2265. (*p)++;
  2266. vector_add(v, str);
  2267. str = STRING_NEW("");
  2268. }
  2269. else if(**p == '.' && *(*p+1) == '.') {
  2270. (*p)+=2;
  2271. string_put(start, string_c_str(str));
  2272. string_put(str, "");
  2273. if(**p == '-') {
  2274. string_push_back2(str, **p);
  2275. (*p)++;
  2276. }
  2277. while(1) {
  2278. if(**p == '}') {
  2279. (*p)++;
  2280. break;
  2281. }
  2282. else if(**p >= '0' && **p <= '9') {
  2283. string_push_back2(str, **p);
  2284. (*p)++;
  2285. }
  2286. else {
  2287. err_msg("invalid brace expression", sname, *sline);
  2288. string_delete(str);
  2289. return FALSE;
  2290. }
  2291. }
  2292. string_put(end, string_c_str(str));
  2293. while(**p) {
  2294. if(**p == '\\') {
  2295. (*p)++;
  2296. string_push_back2(tail, '\\');
  2297. string_push_back2(tail, **p);
  2298. (*p)++;
  2299. }
  2300. else if(**p == ' ' || **p == '\t' || **p == '\n' || **p == ',' || **p=='}' || **p=='>' || **p=='&' || **p=='~' || **p=='#' || **p =='$' || **p=='(' || **p==')' || **p=='|' || **p==';' || **p=='\'' || **p=='"' || **p=='<' || **p=='%' || **p=='@')
  2301. {
  2302. break;
  2303. }
  2304. else {
  2305. string_push_back2(tail, **p);
  2306. (*p)++;
  2307. }
  2308. }
  2309. string_delete(str);
  2310. break;
  2311. }
  2312. else if(**p == 0) {
  2313. err_msg("invalid brace expression", sname, *sline);
  2314. string_delete(str);
  2315. return FALSE;
  2316. }
  2317. else {
  2318. string_push_back2(str, **p);
  2319. (*p)++;
  2320. }
  2321. }
  2322. return TRUE;
  2323. }
  2324. // ?????????
  2325. // ???????????????
  2326. // ?????????
  2327. BOOL delete_comments(char* p, string_obj* cmdline2, char* separator, char* sname, int* sline)
  2328. {
  2329. BOOL squote = FALSE;
  2330. BOOL dquote = FALSE;
  2331. string_obj* head = STRING_NEW("");
  2332. while(*p) {
  2333. if(!dquote && !squote && *p == '\\') {
  2334. string_push_back2(cmdline2, *p++);
  2335. string_push_back2(head, *p);
  2336. string_push_back2(cmdline2, *p++);
  2337. }
  2338. else if(!dquote && *p == '\'') {
  2339. string_push_back2(cmdline2, *p++);
  2340. squote = !squote;
  2341. }
  2342. else if(!squote && *p == '"') {
  2343. string_push_back2(cmdline2, *p++);
  2344. dquote = !dquote;
  2345. }
  2346. else if(squote || dquote) {
  2347. if(*p == 0) {
  2348. err_msg("close \" or \' before the end of comments", sname, *sline);
  2349. string_delete(head);
  2350. return FALSE;
  2351. }
  2352. else {
  2353. string_push_back2(head, *p);
  2354. string_push_back2(cmdline2, *p++);
  2355. }
  2356. }
  2357. /// ?????
  2358. else if(*p == '$' && *(p+1) == '{') {
  2359. string_push_back2(head, *p);
  2360. string_push_back2(cmdline2, *p++);
  2361. string_push_back2(head, *p);
  2362. string_push_back2(cmdline2, *p++);
  2363. }
  2364. /// ???? ///
  2365. else if(*p == '#') {
  2366. p++;
  2367. while(*p) {
  2368. if(*p == '\n') {
  2369. string_push_back2(cmdline2, '\n');
  2370. p++;
  2371. break;
  2372. }
  2373. else {
  2374. p++;
  2375. }
  2376. }
  2377. }
  2378. /// ??????
  2379. else if(*p == '{') {
  2380. p++;
  2381. vector_obj* v = VECTOR_NEW(10);
  2382. string_obj* tail = STRING_NEW("");
  2383. string_obj* start = STRING_NEW("");
  2384. string_obj* end = STRING_NEW("");
  2385. if(!expand_brace_expression(tail, v, start, end, &p, sname, sline)) {
  2386. string_delete(head);
  2387. string_delete(tail);
  2388. string_delete(start);
  2389. string_delete(end);
  2390. int i;
  2391. for(i=0; i<vector_size(v); i++) {
  2392. string_delete(vector_item(v, i));
  2393. }
  2394. vector_delete(v);
  2395. return FALSE;
  2396. }
  2397. /// string
  2398. if(string_c_str(start)[0] == 0) {
  2399. if(vector_size(v) == 0) {
  2400. err_msg("invalid brace expression", sname, *sline);
  2401. string_delete(head);
  2402. string_delete(tail);
  2403. string_delete(start);
  2404. string_delete(end);
  2405. vector_delete(v);
  2406. return FALSE;
  2407. }
  2408. string_push_back(cmdline2, string_c_str(vector_item(v, 0)));
  2409. string_push_back(cmdline2, string_c_str(tail));
  2410. string_push_back2(cmdline2, ' ');
  2411. int i;
  2412. for(i=1; i<vector_size(v); i++) {
  2413. string_push_back(cmdline2, string_c_str(head));
  2414. string_push_back(cmdline2, string_c_str(vector_item(v, i)));
  2415. string_push_back(cmdline2, string_c_str(tail));
  2416. if(i < vector_size(v)-1) string_push_back2(cmdline2, ' ');
  2417. }
  2418. }
  2419. /// number
  2420. else {
  2421. int start2 = atoi(string_c_str(start));
  2422. int end2 = atoi(string_c_str(end));
  2423. int num_len = strlen(string_c_str(start));
  2424. if(num_len < 0) num_len--;
  2425. char buf2[1024];
  2426. buf2[0] = '%';
  2427. snprintf(buf2 + 1, 1023, "0%dd", num_len);
  2428. if(start2 < end2) {
  2429. string_push_back(cmdline2, string_c_str(start));
  2430. string_push_back(cmdline2, string_c_str(tail));
  2431. string_push_back2(cmdline2, ' ');
  2432. int i;
  2433. for(i=start2+1; i<=end2; i++) {
  2434. string_push_back(cmdline2, string_c_str(head));
  2435. char buf[1024];
  2436. if(i < 0) {
  2437. buf[0] = '-';
  2438. snprintf(buf + 1, 1023, buf2, abs(i));
  2439. }
  2440. else {
  2441. snprintf(buf, 1024, buf2, i);
  2442. }
  2443. string_push_back(cmdline2, buf);
  2444. string_push_back(cmdline2, string_c_str(tail));
  2445. if(i <= end2-1) string_push_back2(cmdline2, ' ');
  2446. }
  2447. }
  2448. else if(start2 == end2) {
  2449. string_push_back(cmdline2, string_c_str(start));
  2450. string_push_back(cmdline2, string_c_str(tail));
  2451. string_push_back2(cmdline2, ' ');
  2452. }
  2453. else {
  2454. string_push_back(cmdline2, string_c_str(start));
  2455. string_push_back(cmdline2, string_c_str(tail));
  2456. string_push_back2(cmdline2, ' ');
  2457. int i;
  2458. for(i=start2-1; i>=end2; i--) {
  2459. string_push_back(cmdline2, string_c_str(head));
  2460. char buf[1024];
  2461. if(i < 0) {
  2462. buf[0] = '-';
  2463. snprintf(buf + 1, 1023, buf2, abs(i));
  2464. }
  2465. else {
  2466. snprintf(buf, 1024, buf2, i);
  2467. }
  2468. string_push_back(cmdline2, buf);
  2469. string_push_back(cmdline2, string_c_str(tail));
  2470. if(i>= end2 + 1) string_push_back2(cmdline2, ' ');
  2471. }
  2472. }
  2473. }
  2474. string_put(head, "");
  2475. string_delete(tail);
  2476. int i;
  2477. for(i=0; i<vector_size(v); i++) {
  2478. string_delete(vector_item(v, i));
  2479. }
  2480. vector_delete(v);
  2481. string_delete(start);
  2482. string_delete(end);
  2483. }
  2484. else if(*p == ' ' || *p == '\t' || *p == '\n') {
  2485. string_push_back2(cmdline2, *p++);
  2486. string_put(head, "");
  2487. }
  2488. else {
  2489. string_push_back2(head, *p);
  2490. string_push_back2(cmdline2, *p++);
  2491. }
  2492. }
  2493. string_delete(head);
  2494. return TRUE;
  2495. }
  2496. // ??????????????????????
  2497. // ??????????????
  2498. // ?????gErrMsg???????????????
  2499. BOOL saphire_compile(char* fname, char* out_fname)
  2500. {
  2501. /// ???? ///
  2502. string_obj* str = STRING_NEW("");
  2503. int f = open(fname, O_RDONLY);
  2504. if(f < 0) {
  2505. string_delete(str);
  2506. return FALSE;
  2507. }
  2508. char buf[BUFSIZ];
  2509. while(1) {
  2510. int size = read(f, buf, BUFSIZ-1);
  2511. if(size == 0) {
  2512. break;
  2513. }
  2514. if(size < 0) {
  2515. close(f);
  2516. string_delete(str);
  2517. return FALSE;
  2518. }
  2519. buf[size] = 0;
  2520. string_push_back(str, buf);
  2521. }
  2522. close(f);
  2523. /// ??? ///
  2524. int sline = 1;
  2525. string_obj* str2 = STRING_NEW("");
  2526. if(!delete_comments(string_c_str(str), str2, " ", fname, &sline)) {
  2527. string_delete(str);
  2528. string_delete(str2);
  2529. return FALSE;
  2530. }
  2531. string_delete(str);
  2532. sline = 1;
  2533. sStatments* statments = STATMENTS_NEW();
  2534. if(!parse(string_c_str(str2), fname, &sline, statments)) {
  2535. sStatments_delete(statments);
  2536. string_delete(str2);
  2537. return FALSE;
  2538. }
  2539. string_delete(str2);
  2540. /// ?????????? ///
  2541. int fd = open(out_fname, O_WRONLY|O_TRUNC|O_CREAT, 0644);
  2542. if(write(fd, gMagicNumber, strlen(gMagicNumber)) < 0) {
  2543. perror("write");
  2544. exit(1);
  2545. }
  2546. sStatments_save(statments, fd);
  2547. (void)close(fd);
  2548. sStatments_delete(statments);
  2549. return TRUE;
  2550. }
  2551. // ??????????(????????????)????????
  2552. // ??????
  2553. // ????-1???????????gErrMsg????????????????
  2554. int saphire_load_obj(char* fname, sWFd* pipeout, sRFd* pipein, int pipeerr, vector_obj* parent_blocks)
  2555. {
  2556. gKitutukiSigInt = FALSE;
  2557. int fd = open(fname, O_RDONLY);
  2558. if(fd < 0) {
  2559. return -1;
  2560. }
  2561. char magic_number[64];
  2562. if(read(fd, magic_number, strlen(gMagicNumber)) < 0) {
  2563. perror("read");
  2564. exit(1);
  2565. }
  2566. magic_number[strlen(gMagicNumber)] = 0;
  2567. if(strcmp(magic_number, gMagicNumber) != 0) {
  2568. return -1;
  2569. }
  2570. /// ?????????????? ///
  2571. sStatments* statments = sStatments_load(fd);
  2572. /// ?? ///
  2573. int return_ = FALSE;
  2574. int break_ = FALSE;
  2575. sRunInfo runinfo;
  2576. runinfo.return_ = &return_;
  2577. runinfo.break_ = &break_;
  2578. runinfo.envs = VECTOR_NEW(10);
  2579. runinfo.enable_return = TRUE;
  2580. runinfo.enable_break = FALSE;
  2581. runinfo.parent_blocks = parent_blocks;
  2582. runinfo.object = NULL;
  2583. runinfo.running_fun = NULL;
  2584. runinfo.running_class = NULL;
  2585. int rcode = run(&runinfo, statments, fname, pipeout, pipein, pipeerr , FALSE);
  2586. /// ?? ///
  2587. close(fd);
  2588. int i;
  2589. for(i=0; i<vector_size(runinfo.envs); i++) {
  2590. string_delete(vector_item(runinfo.envs, i));
  2591. }
  2592. vector_delete(runinfo.envs);
  2593. sStatments_delete(statments);
  2594. return rcode;
  2595. }