/saphire-3.6.5/src/saphire_parser.c
# · C · 2938 lines · 2716 code · 166 blank · 56 comment · 518 complexity · 3f3594dd790f3a0982a87d7b35920558 MD5 · raw file
Large files are truncated click here to view the full file
- #include "config.h"
- #include <errno.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <glob.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <pwd.h>
- #include <limits.h>
- #include "saphire/saphire.h"
- #include "saphire/saphire_inner.h"
- // ????????
- static void skip_spaces(char** p, string_obj* not_evaled)
- {
- while(**p == ' ' || **p == '\t') {
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- }
- // {}, <>, (), []????????????????????OK
- // ???????parse???
- // ???????
- 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)
- {
- if(**p == first_char) {
- string_push_back2(not_evaled, **p);
- (*p)++;
- int nest = 0;
- BOOL squote = FALSE;
- BOOL dquote = FALSE;
- while(1) {
- if(gKitutukiSigInt) {
- err_msg("signal interrupt", sname, *sline);
- gKitutukiSigInt = FALSE;
- return FALSE;
- }
- /// ???? ///
- if(!squote && !dquote && **p == '\\') {
- string_push_back2(not_evaled, **p);
- (*p)++;
- if(line_inc && **p == '\n') {
- (*sline)++;
- }
- else if(**p == 0) {
- err_msg("unexpected end(0) after quote", sname, *sline);
- return FALSE;
- }
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- /// ???????? ///
- else if(!dquote && **p == '\'') {
- squote = !squote;
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- /// ??????? ///
- else if(!squote && **p == '"') {
- dquote = !dquote;
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- /// ?????????
- else if(!squote && **p == '$') {
- // ?????? $()
- if(*(*p+1) == '$' && *(*p+2) == '(' || *(*p+1) == '(')
- {
- if(*(*p+1) == '$') {
- string_push_back2(not_evaled, **p); // $
- (*p)++;
- string_push_back2(not_evaled, **p); // $
- (*p)++;
- }
- else {
- string_push_back2(not_evaled, **p); // $
- (*p)++;
- }
- if(!read_until_next_close_character('(', ')', p, not_evaled, read_end_of_statment, line_inc, sname, sline)) {
- return FALSE;
- }
- *read_end_of_statment = 1;
- }
- /// ???? ///
- else {
- BOOL quote;
- if(*(*p+1) == '$') {
- string_push_back2(not_evaled, **p); // $
- (*p)++;
- string_push_back2(not_evaled, **p); // $
- (*p)++;
- quote = FALSE;
- }
- else {
- string_push_back2(not_evaled, **p); // $
- (*p)++;
- quote = TRUE;
- }
- if(**p >= '0' && **p <= '9' || **p == '{' || **p >= 'a' && **p <= 'z' || **p >= 'A' && **p <= 'Z' || **p == '_') {
- if(**p == '{') {
- if(!read_until_next_close_character('{', '}', p, not_evaled, read_end_of_statment, TRUE, sname, sline)) {
- return FALSE;
- }
- }
- else {
- while(**p) {
- if(**p >= '0' && **p <= '9' || **p >= 'a' && **p <= 'z' || **p >= 'A' && **p <= 'Z' || **p == '_') {
- string_push_back2(not_evaled, **p); // ??
- (*p)++;
- }
- else {
- break;
- }
- }
- }
- *read_end_of_statment = 1;
- }
- else {
- if(quote) {
- string_push_back2(not_evaled, '$');
- }
- else {
- string_push_back2(not_evaled, '$');
- string_push_back2(not_evaled, '$');
- }
- }
- }
- }
- else if(squote || dquote) {
- if(**p == 0) {
- err_msg("close ' or \" before the end of source", sname, *sline);
- return FALSE;
- }
- else {
- if(line_inc && **p == '\n') {
- (*sline)++;
- }
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- }
- else if(**p == first_char) {
- nest++;
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- else if(**p == last_char) {
- string_push_back2(not_evaled, **p);
- (*p)++;
- if(nest == 0) {
- break;
- }
- nest--;
- }
- else if(**p == 0) {
- char buf[256];
- snprintf(buf, 256, "read_util_next_close_character: unexpected end(0). close with (%c)", last_char);
- err_msg(buf, sname, *sline);
- return FALSE;
- }
- else if(line_inc && **p == '\n') {
- (*sline)++;
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- else {
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- }
- }
-
- return TRUE;
- }
- // ??????????? contents????
- // ?????????????
- // ????????????
- static BOOL read_block(char** p, string_obj* contents, vector_obj* args, string_obj* not_evaled, BOOL line_inc, char* sname, int* sline)
- {
- int line_of_head = *sline;
- string_push_back2(not_evaled, **p); // {
- (*p)++;
-
- while(1) {
- if(**p == ' ') {
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, *((*p)++));
- }
- else if(**p == '\t') {
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, *((*p)++));
- }
- else if(**p == '\n') {
- line_inc && (*sline)++;
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, *((*p)++));
- }
- else {
- break;
- }
- }
- /// ??
- if(args) {
- if(**p == ':') {
- string_push_back2(not_evaled, **p);
- (*p)++;
- while(**p) {
- string_obj* str = STRING_NEW("");
- skip_spaces(p, not_evaled);
- while(**p >= 'a' && **p <= 'z'
- || **p >= 'A' && **p <= 'Z'
- || **p == '_')
- {
- string_push_back2(str, **p);
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- skip_spaces(p, not_evaled);
- vector_add(args, str);
- if(**p >= 'a' && **p <= 'z'
- || **p >= 'A' && **p <= 'Z'
- || **p == '_')
- {
- }
- else {
- if(**p == ':') {
- string_push_back2(not_evaled, **p);
- (*p)++;
- break;
- }
- else {
- char buf[1024];
- snprintf(buf, 1024, "unexpected char(%c)", **p);
- err_msg(buf, sname, line_of_head);
- return FALSE;
- }
- }
- }
- }
- while(1) {
- if(**p == ' ') {
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, *((*p)++));
- }
- else if(**p == '\t') {
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, *((*p)++));
- }
- else if(**p == '\n') {
- line_inc && (*sline)++;
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, *((*p)++));
- }
- else {
- break;
- }
- }
- }
- BOOL squote = FALSE;
- BOOL dquote = FALSE;
- int nest = 0;
- while(1) {
- /// ????
- if(!squote && !dquote && **p == '\\') {
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, *((*p)++));
- if(line_inc && **p == '\n') {
- (*sline)++;
- }
- else if(*p == 0) {
- err_msg("unsigned end after quote",sname, *sline);
- return FALSE;
- }
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, *((*p)++));
- }
- /// ????????
- else if(!dquote && **p == '\'') {
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, *((*p)++));
- squote = !squote;
- }
- /// ???????
- else if(!squote && **p == '"') {
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, *((*p)++));
- dquote = !dquote;
- }
- /// ????????????????? ///
- else if(squote || dquote) {
- if(**p == 0) {
- err_msg("get block: close \" or \' before the end of block", sname, line_of_head);
- return FALSE;
- }
- else if(line_inc && **p == '\n') {
- (*sline)++;
- }
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, *((*p)++));
- }
- else if(**p == '(') {
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, *((*p)++));
- nest++;
- }
- else if(**p == ')') {
- string_push_back2(not_evaled, **p);
- (*p)++;
- nest--;
- if(nest == -1) {
- break;
- }
- else {
- string_push_back2(contents, ')');
- }
- }
- else if(**p == 0) {
- err_msg("get block: found 0. close )", sname, line_of_head);
- return FALSE;
- }
- else if(**p == '\n') {
- line_inc && (*sline)++;
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, **p);
- (*p)++;
- }
- else {
- string_push_back2(not_evaled, **p);
- string_push_back2(contents, **p);
- (*p)++;
- }
- }
- return TRUE;
- }
- /// ?????
- static void expand_tilda(string_obj* buf, string_obj* path)
- {
- char* p = string_c_str(buf);
- p++; // ~
- string_obj* user = STRING_NEW("");
- while(*p && *p != '/') {
- string_push_back2(user, *p);
- p++;
- }
- /// ???????????????????
- if(string_length(user) == 0) {
- char* home = getenv("HOME");
- if(home) {
- string_push_back(path, home);
- }
- else {
- struct passwd* pw = getpwuid(getuid());
- if(pw) {
- string_push_back(path, pw->pw_dir);
- }
- else {
- string_push_back(path, "~");
- }
- }
- }
- else {
- struct passwd* pw = getpwnam(string_c_str(user));
- if(pw) {
- string_push_back(path, pw->pw_dir);
- }
- else {
- string_push_back2(path, '~');
- string_push_back(path, string_c_str(user));
- }
- }
- /// ?????
- string_push_back(path, p);
- string_delete(user);
- }
- static BOOL add_arg_to_command(sCommand* command, MANAGED sArg* new_arg, char* sname, int* sline)
- {
- vector_add(command->mArgs, new_arg);
- if(vector_size(command->mArgs) == 1) {
- if(new_arg->mKind == 0) {
- /// ???????????????? ///
- command->mKind = get_command_kind(string_c_str(new_arg->mBody));
- }
- else {
- err_msg("command name must be determined staticaly", sname, *sline);
- return FALSE;
- }
- }
- return TRUE;
- }
- /// ???????
- 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)
- {
- /// ????????????????? 127????
- static unsigned char table[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0
- };
- BOOL squote = FALSE;
- BOOL dquote = FALSE;
- while(**p) {
- if(gKitutukiSigInt) {
- gKitutukiSigInt = FALSE;
- err_msg("signal interrupt", sname, *sline);
- return FALSE;
- }
- /// ???
- if(!squote && !dquote && **p == '"' && *(*p+1) == '"') {
- break;
- }
- else if(!dquote && !squote && **p =='\'' && *(*p+1) == '\'') {
- break;
- }
- else if(**p == '\\' && *(*p+1) == 't') {
- string_push_back2(not_evaled, **p);
- string_push_back2(not_evaled, *(*p+1));
- string_push_back2(buf, '\t');
- (*p)+=2;
- }
- else if(**p == '\\' && *(*p+1) == 'n') {
- string_push_back2(not_evaled, **p);
- string_push_back2(not_evaled, *(*p+1));
- string_push_back2(buf, '\n');
- (*p)+=2;
- }
- else if(**p == '\\' && *(*p+1) == 'r') {
- string_push_back2(not_evaled, **p);
- string_push_back2(not_evaled, *(*p+1));
- string_push_back2(buf, '\r');
- (*p)+=2;
- }
- else if(**p == '\\' && *(*p+1) == 'a') {
- string_push_back2(not_evaled, **p);
- string_push_back2(not_evaled, *(*p+1));
- string_push_back2(buf, '\a');
- (*p)+=2;
- }
- else if(!squote && !dquote && **p == '\\') {
- if(expand_quote) {
- string_push_back2(not_evaled, **p);
- (*p)++;
- if(**p == 0) {
- err_msg("unexpected end. can't quote null.", sname, *sline);
- return FALSE;
- }
- else if(**p == '\n') {
- (*sline)++;
- }
- string_push_back2(not_evaled, **p);
- string_push_back2(buf, **p);
- (*p)++;
- }
- else {
- string_push_back2(not_evaled, **p);
- string_push_back2(buf, **p);
- (*p)++;
- }
- }
- else if(!dquote && **p == '\'') {
- if(expand_quote) {
- string_push_back2(not_evaled, **p);
- (*p)++;
- squote = !squote;
- }
- else {
- string_push_back2(not_evaled, **p);
- string_push_back2(buf, **p);
- (*p)++;
- }
- }
- else if(!squote && **p == '"') {
- if(expand_quote) {
- dquote = !dquote;
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- else {
- string_push_back2(not_evaled, **p);
- string_push_back2(buf, **p);
- (*p)++;
- }
- }
- /// ?????????
- else if(!squote && **p == '$') {
- // ?????? $()
- if(*(*p+1) == '(' || *(*p+1) == '$' && *(*p+2) == '(')
- {
- if(*(*p+1) == '$') {
- string_push_back2(not_evaled, **p); // $
- (*p)++;
- string_push_back2(not_evaled, **p); // $
- (*p)++;
- }
- else {
- string_push_back2(not_evaled, **p); // $
- (*p)++;
- }
- if(!read_until_next_close_character('(', ')', p, not_evaled, read_end_of_statment, TRUE, sname, sline)) {
- return FALSE;
- }
- *read_end_of_statment = 1;
- }
- /// ????
- else {
- BOOL quote;
- if(*(*p+1) == '$') {
- string_push_back2(not_evaled, **p); // $
- (*p)++;
- string_push_back2(not_evaled, **p); // $
- (*p)++;
- quote = FALSE;
- }
- else {
- string_push_back2(not_evaled, **p); // $
- (*p)++;
- quote = TRUE;
- }
- if(**p >= '0' && **p <= '9' || **p == '{' || **p >= 'a' && **p <= 'z' || **p >= 'A' && **p <= 'Z' || **p == '_') {
- if(**p == '{') {
- if(!read_until_next_close_character('{', '}', p, not_evaled, read_end_of_statment, TRUE, sname, sline)) {
- return FALSE;
- }
- }
- else {
- while(**p) {
- if(**p >= '0' && **p <= '9' || **p >= 'a' && **p <= 'z' || **p >= 'A' && **p <= 'Z' || **p == '_') {
- string_push_back2(not_evaled, **p); // ??
- (*p)++;
- }
- else {
- break;
- }
- }
- }
- *read_end_of_statment = 1;
- }
- else {
- if(quote) {
- string_push_back2(buf, '$');
- }
- else {
- string_push_back2(buf, '$');
- string_push_back2(buf, '$');
- }
- }
- }
- }
- /// ?????????????????
- else if(squote || dquote) {
- if(**p == 0) {
- err_msg("close single quote or double quote", sname, *sline);
- return FALSE;
- }
- else if(**p == '\n') {
- (*sline)++;
- }
- string_push_back2(not_evaled, **p);
- string_push_back2(buf, **p);
- (*p)++;
- }
- /*
- /// ?????
- else if(command && vector_size(command->mArgs) > 0 && command->mKind != kCommand && string_c_str(buf)[0] == 0 && **p == '-')
- {
- string_push_back2(not_evaled, **p);
- string_push_back2(buf, **p);
- (*p)++;
- if(!read_one_argument(p, buf, not_evaled, read_end_of_statment, NULL, sname, sline, FALSE))
- {
- return FALSE;
- }
- int i = 0;
- int options = 0;
- while(kCommandOptions[i]) {
- if(strcmp(string_c_str(buf), kCommandOptions[command->mKind][i]) == 0)
- {
- options |= 0x1 << i;
- }
- i++;
- }
- if(options) {
- command->mOptions |= options;
- string_put(buf, "");
- }
- else {
- if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
- {
- return FALSE;
- }
- }
- }
- */
- /// ????? ///
- else if(**p == '~') {
- string_push_back2(not_evaled, **p);
- string_push_back2(buf, **p);
- (*p)++;
- if(strlen(string_c_str(buf)) == 1 && command) {
- if(!read_one_argument(p, buf, not_evaled, read_end_of_statment, NULL, sname, sline, FALSE))
- {
- return FALSE;
- }
- string_obj* path = STRING_NEW("");
- expand_tilda(buf, path);
- string_obj* path2 = STRING_NEW("");
- BOOL glob_ = FALSE;
- char* p = string_c_str(path);
- BOOL squote = FALSE;
- BOOL dquote = FALSE;
- while(*p) {
- if(!dquote && *p == '\'') {
- p++;
- squote = !squote;
- }
- else if(!squote && *p == '"') {
- p++;
- dquote = !dquote;
- }
- else if(squote || dquote) {
- string_push_back2(path2, *p);
- p++;
- }
- else if(*p == '\\') {
- p++;
- string_push_back2(path2, *p);
- p++;
- }
- else if(*p == '[') {
- string_push_back2(path2, *p);
- p++;
- while(*p) {
- if(*p == ']') {
- glob_ = TRUE;
- string_push_back2(path2, *p);
- p++;
- break;
- }
- else {
- string_push_back2(path2, *p);
- p++;
- }
- }
- }
- else if(*p == '?' || *p == '*') {
- glob_ = TRUE;
- string_push_back2(path2, *p);
- p++;
- }
- else {
- string_push_back2(path2, *p);
- p++;
- }
- }
- string_delete(path);
- if(glob_) {
- glob_t result;
- int rc = glob(string_c_str(path2), 0, NULL, &result);
- if(rc == GLOB_NOSPACE) {
- err_msg("read_one_argument: out of space during glob operation", sname, *sline);
- string_delete(path2);
- return FALSE;
- }
- else if(rc == GLOB_NOMATCH) {
- }
- else {
- int i;
- for(i=0; i<result.gl_pathc; i++) {
- char* file = result.gl_pathv[i];
- if(strcmp(file, ".") != 0 && strcmp(file, "..") != 0)
- {
- string_obj* str = STRING_NEW(file);
- if(!add_arg_to_command(command, ARG_NEW(0, MANAGED str), sname, sline))
- {
- string_delete(path2);
- return FALSE;
- }
- }
- }
- string_put(buf, ""); // ?????????mArgs??????
- }
- string_delete(path2);
- }
- else {
- if(!add_arg_to_command(command, ARG_NEW(0, MANAGED path2), sname, sline))
- {
- return FALSE;
- }
- string_put(buf, ""); // ???????????mArgs??????
- }
- break;
- }
- }
- /// ??? ///
- else if(command && vector_size(command->mArgs) > 0 && (**p == '[' || **p == '?' || **p == '*'))
- {
- string_push_back2(not_evaled, **p);
- string_push_back2(buf, **p);
- (*p)++;
- if(!read_one_argument(p, buf, not_evaled, read_end_of_statment, NULL, sname, sline, TRUE))
- {
- return FALSE;
- }
- glob_t result;
- int rc = glob(string_c_str(buf), 0, NULL, &result);
- if(rc == GLOB_NOSPACE) {
- err_msg("read_one_argument: out of space during glob operation", sname, *sline);
- return FALSE;
- }
- else if(rc == GLOB_NOMATCH) {
- }
- else {
- int i;
- for(i=0; i<result.gl_pathc; i++) {
- char* file = result.gl_pathv[i];
- if(strcmp(file, ".") != 0 && strcmp(file, "..") != 0)
- {
- string_obj* str = STRING_NEW(file);
- if(!add_arg_to_command(command, ARG_NEW(0, MANAGED str), sname, sline))
- {
- return FALSE;
- }
- }
- }
- string_put(buf, ""); // ?????????mArgs??????
- }
- break;
- }
- // ->?????
- else if(command && vector_size(command->mArgs) == 0 && **p == '-' && *(*p+1) == '>')
- {
- string_push_back2(not_evaled, **p);
- string_push_back2(buf, **p);
- (*p)++;
- string_push_back2(not_evaled, **p);
- string_push_back2(buf, **p);
- (*p)++;
- }
- /// utf-8??????
- else if(((unsigned char)**p) > 127) {
- string_push_back2(not_evaled, **p);
- string_push_back2(buf, **p);
- (*p)++;
- }
- // ???????????????
- else if(**p == '@' && (*(*p+1) == '(') || (*(*p+1) == '@' && *(*p+2) == '(') || (*(*p+1) == '@' && *(*p+2) >= 'a' && *(*p+2) <= 'z' && *(*p+3) == '('))
- {
- break;
- }
- // % ????????????
- else if(**p == '%' && (*(*p+1) == '>' || *(*p+1) == '2')) {
- break;
- }
- else if(table[**p]) {
- break;
- }
- else {
- string_push_back2(not_evaled, **p);
- string_push_back2(buf, **p);
- (*p)++;
- }
- }
- if(squote) {
- err_msg("require to close '", sname, *sline);
- return FALSE;
- }
- if(dquote) {
- err_msg("require to close \"", sname, *sline);
- return FALSE;
- }
- return TRUE;
- }
- /// if?????
- 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)
- {
- skip_spaces(p, not_evaled);
- if(**p != '(') {
- err_msg("expected (", sname, *sline);
- return FALSE;
- }
- /// ??????? ///
- string_obj* str = STRING_NEW("");
- int read_end_of_statment2 = -1;
- if(!read_until_next_close_character('(', ')', p, str, &read_end_of_statment2, FALSE, sname, sline)) {
- string_delete(str);
- return FALSE;
- }
- string_push_back(not_evaled, string_c_str(str));
- string_erase(str, 0, 1);
- string_trunc(str, string_length(str)-1);
- sStatments* condition = STATMENTS_NEW();
- if(!parse(string_c_str(str), sname, sline, condition))
- {
- string_delete(str);
- sStatments_delete(condition);
- return FALSE;
- }
- string_delete(str);
- skip_spaces(p, not_evaled);
- /// ??? ///
- sStatments* loop = STATMENTS_NEW();
- if(**p == '(') {
- string_obj* str = STRING_NEW("");
- if(!read_block(p, str, NULL, not_evaled, FALSE, sname, sline)) {
- string_delete(str);
- sStatments_delete(condition);
- sStatments_delete(loop);
- return FALSE;
- }
- if(!parse(string_c_str(str), sname, sline, loop))
- {
- sStatments_delete(condition);
- sStatments_delete(loop);
- string_delete(str);
- return FALSE;
- }
- string_delete(str);
- }
- else {
- err_msg("expected block.", sname, *sline);
- sStatments_delete(condition);
- sStatments_delete(loop);
- return FALSE;
- }
- skip_spaces(p, not_evaled);
- vector_obj* conditions = VECTOR_NEW(30);
- vector_obj* loops = VECTOR_NEW(30);
-
- vector_add(conditions, condition);
- vector_add(loops, loop);
- /// elif ?? ///
- if(**p == 'e' && *(*p+1) == 'l'
- && *(*p+2) == 'i' && *(*p+3) == 'f'
- && (*(*p+4) == ' ' || *(*p+4) == '\t' || *(*p+4) == '('))
- {
- while(**p == 'e' && *(*p+1) == 'l' && *(*p+2) == 'i'
- && *(*p+3) == 'f'
- && (*(*p+4) == ' ' || *(*p+4) == '\t' || *(*p+4) == '('))
- {
- string_push_back2(not_evaled, **p);
- (*p)++;
- string_push_back2(not_evaled, **p);
- (*p)++;
- string_push_back2(not_evaled, **p);
- (*p)++;
- string_push_back2(not_evaled, **p);
- (*p)++;
- skip_spaces(p, not_evaled);
- if(**p != '(') {
- err_msg("expected (", sname, *sline);
- int i;
- for(i=0; i<vector_size(conditions); i++) {
- sStatments_delete(vector_item(conditions, i));
- }
- vector_delete(conditions);
- for(i=0; i<vector_size(loops); i++) {
- sStatments_delete(vector_item(loops, i));
- }
- vector_delete(loops);
-
- return FALSE;
- }
- /// ??? ///
- string_obj* str = STRING_NEW("");
- int read_end_of_statment = -1;
- if(!read_until_next_close_character('(', ')', p, str, &read_end_of_statment, FALSE, sname, sline)) {
- string_delete(str);
- int i;
- for(i=0; i<vector_size(conditions); i++) {
- sStatments_delete(vector_item(conditions, i));
- }
- vector_delete(conditions);
- for(i=0; i<vector_size(loops); i++) {
- sStatments_delete(vector_item(loops, i));
- }
- vector_delete(loops);
- return FALSE;
- }
- string_push_back(not_evaled, string_c_str(str));
- sStatments* condition = STATMENTS_NEW();
- if(!parse(string_c_str(str), sname, sline, condition))
- {
- sStatments_delete(condition);
- int i;
- for(i=0; i<vector_size(conditions); i++) {
- sStatments_delete(vector_item(conditions, i));
- }
- vector_delete(conditions);
- for(i=0; i<vector_size(loops); i++) {
- sStatments_delete(vector_item(loops, i));
- }
- vector_delete(loops);
- string_delete(str);
- return FALSE;
- }
- string_delete(str);
- vector_add(conditions, condition);
- skip_spaces(p, not_evaled);
- /// ??? ///
- sStatments* loop = STATMENTS_NEW();
- if(**p == '(') {
- string_obj* str = STRING_NEW("");
- if(!read_block(p, str, NULL, not_evaled, FALSE, sname, sline)) {
- string_delete(str);
- sStatments_delete(loop);
- int i;
- for(i=0; i<vector_size(conditions); i++) {
- sStatments_delete(vector_item(conditions, i));
- }
- vector_delete(conditions);
- for(i=0; i<vector_size(loops); i++) {
- sStatments_delete(vector_item(loops, i));
- }
- vector_delete(loops);
- return FALSE;
- }
- if(!parse(string_c_str(str), sname, sline, loop))
- {
- sStatments_delete(loop);
- string_delete(str);
- int i;
- for(i=0; i<vector_size(conditions); i++) {
- sStatments_delete(vector_item(conditions, i));
- }
- vector_delete(conditions);
- for(i=0; i<vector_size(loops); i++) {
- sStatments_delete(vector_item(loops, i));
- }
- vector_delete(loops);
- return FALSE;
- }
- string_delete(str);
- }
- else {
- err_msg("expected block.", sname, *sline);
- sStatments_delete(loop);
- int i;
- for(i=0; i<vector_size(conditions); i++) {
- sStatments_delete(vector_item(conditions, i));
- }
- vector_delete(conditions);
- for(i=0; i<vector_size(loops); i++) {
- sStatments_delete(vector_item(loops, i));
- }
- vector_delete(loops);
- return FALSE;
- }
- skip_spaces(p, not_evaled);
- vector_add(loops, loop);
- }
- }
- /// else ?? ///
- if(**p == 'e' && *(*p+1) == 'l' && *(*p+2) == 's' && *(*p+3) == 'e' && (*(*p+4) == ' ' || *(*p+4) == '\t' || *(*p+4) == '('))
- {
- string_push_back2(not_evaled, **p);
- (*p)++;
- string_push_back2(not_evaled, **p);
- (*p)++;
- string_push_back2(not_evaled, **p);
- (*p)++;
- string_push_back2(not_evaled, **p);
- (*p)++;
- skip_spaces(p, not_evaled);
-
- /// ??? ///
- sStatments* loop = STATMENTS_NEW();
- if(**p == '(') {
- string_obj* str = STRING_NEW("");
- if(!read_block(p, str, NULL, not_evaled, FALSE, sname, sline)) {
- string_delete(str);
- sStatments_delete(loop);
- int i;
- for(i=0; i<vector_size(conditions); i++) {
- sStatments_delete(vector_item(conditions, i));
- }
- vector_delete(conditions);
- for(i=0; i<vector_size(loops); i++) {
- sStatments_delete(vector_item(loops, i));
- }
- vector_delete(loops);
- return FALSE;
- }
- if(!parse(string_c_str(str), sname, sline, loop))
- {
- string_delete(str);
- sStatments_delete(loop);
- int i;
- for(i=0; i<vector_size(conditions); i++) {
- sStatments_delete(vector_item(conditions, i));
- }
- vector_delete(conditions);
- for(i=0; i<vector_size(loops); i++) {
- sStatments_delete(vector_item(loops, i));
- }
- return FALSE;
- }
- string_delete(str);
- }
- else {
- err_msg("expected block.", sname, *sline);
- int i;
- for(i=0; i<vector_size(conditions); i++) {
- sStatments_delete(vector_item(conditions, i));
- }
- vector_delete(conditions);
- for(i=0; i<vector_size(loops); i++) {
- sStatments_delete(vector_item(loops, i));
- }
- sStatments_delete(loop);
- return FALSE;
- }
- skip_spaces(p, not_evaled);
- vector_add(loops, loop);
- }
-
- command->mKind = kIf;
- command->mExtra = sIf_new(MANAGED conditions, MANAGED loops);
- return TRUE;
- }
- /// while?????
- 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)
- {
- skip_spaces(p, not_evaled);
- if(**p != '(') {
- err_msg("expected (", sname, *sline);
- return FALSE;
- }
- /// ??????? ///
- string_obj* str = STRING_NEW("");
- int read_end_of_statment2 = -1;
- if(!read_until_next_close_character('(', ')', p, str, &read_end_of_statment2, FALSE, sname, sline)) {
- string_delete(str);
- return FALSE;
- }
- string_push_back(not_evaled, string_c_str(str));
- string_erase(str, 0, 1);
- string_trunc(str, string_length(str)-1);
- sStatments* conditions = STATMENTS_NEW();
- if(!parse(string_c_str(str), sname, sline, conditions))
- {
- sStatments_delete(conditions);
- string_delete(str);
- return FALSE;
- }
- string_delete(str);
- while(**p) {
- if(**p == '\n') {
- (*sline)++;
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- else if(**p == ' ' || **p == '\t') {
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- else {
- break;
- }
- }
- /// ???????? ///
- sStatments* loops = STATMENTS_NEW();
- if(**p == '(') {
- string_obj* str = STRING_NEW("");
- if(!read_block(p, str, NULL, not_evaled, FALSE, sname, sline)) {
- sStatments_delete(conditions);
- sStatments_delete(loops);
- string_delete(str);
- return FALSE;
- }
- if(!parse(string_c_str(str), sname, sline, loops))
- {
- string_delete(str);
- sStatments_delete(conditions);
- sStatments_delete(loops);
- return FALSE;
- }
- string_delete(str);
- }
- else {
- err_msg("expected block.", sname, *sline);
- sStatments_delete(conditions);
- sStatments_delete(loops);
- return FALSE;
- }
- command->mKind = kWhile;
- // ??????mNotEvaled????????????
- // ???command??????
- command->mExtra = sWhile_new(MANAGED conditions, MANAGED loops);
- return TRUE;
- }
- /// ?????????
- static BOOL read_command(char** p, sCommand* command, sStatment* statment, string_obj* not_evaled, int* read_end_of_statment, char* sname, int* sline)
- {
- while(**p) {
- string_obj* buf = STRING_NEW("");
- if(!read_one_argument(p, buf, not_evaled, read_end_of_statment, command, sname, sline, TRUE))
- {
- string_delete(buf);
- return FALSE;
- }
- /// ??????? ///
- if(strcmp(string_c_str(buf), "") != 0) {
- if(vector_size(command->mArgs) == 0) {
- if(strcmp(string_c_str(buf), "if") == 0) {
- if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
- {
- return FALSE;
- }
- string_push_back(statment->mTitle, string_c_str(buf));
- string_push_back(statment->mTitle, " ");
- if(!read_command_parse_if_statment(p, command, statment, not_evaled, read_end_of_statment, sname, sline))
- {
- return FALSE;
- }
- }
- else if(strcmp(string_c_str(buf), "while") == 0) {
- if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
- {
- return FALSE;
- }
- string_push_back(statment->mTitle, string_c_str(buf));
- string_push_back(statment->mTitle, " ");
- if(!read_command_parse_while_statment(p, command, statment, not_evaled, read_end_of_statment, sname, sline))
- {
- return FALSE;
- }
- }
- else {
- if(vector_size(statment->mCommands) == 0 && strcmp(string_c_str(buf), "!") == 0)
- {
- statment->mRCodeReverse = TRUE;
- }
- if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
- {
- return FALSE;
- }
- string_push_back(statment->mTitle, string_c_str(buf));
- string_push_back(statment->mTitle, " ");
- }
- }
- else {
- if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
- {
- return FALSE;
- }
- string_push_back(statment->mTitle, string_c_str(buf));
- string_push_back(statment->mTitle, " ");
- }
- }
- else {
- /// ?????
- if(**p == '\'') {
- string_push_back(not_evaled, "''");
- (*p)+=2;
- if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
- {
- return FALSE;
- }
- string_push_back(statment->mTitle, "'");
- string_push_back(statment->mTitle, " ");
- continue;
- }
- else if(**p == '"') {
- string_push_back(not_evaled, "\"\"");
- (*p)+=2;
- /// ???????????????? ///
- if(!add_arg_to_command(command, ARG_NEW(0, MANAGED buf), sname, sline))
- {
- return FALSE;
- }
- string_push_back(statment->mTitle, "\"\"");
- string_push_back(statment->mTitle, " ");
- continue;
- }
- else {
- string_delete(buf);
- }
- }
- /// ?????????? ///
- if((**p == '@' && *(*p+1) == '(') || (**p == '@' && *(*p+1) == '@' && *(*p+2) == '(') || (**p == '@' && *(*p+1) == '@' && *(*p+2) >= 'a' && *(*p+2) <= 'z' && *(*p+3) == '('))
- {
- string_push_back2(not_evaled, **p);
- (*p)++;
- BOOL double_;
- enum eLineField lf;
- if(**p == '@') {
- string_push_back2(not_evaled, **p);
- (*p)++;
- double_ = TRUE;
- if(**p == '(') {
- lf = kLF;
- }
- else if(*(*p+1) == 'a') {
- lf = kBel;
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- else if(*(*p+1) == 'm') {
- lf = kCR;
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- else if(*(*p+1) == 'w') {
- lf = kCRLF;
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- else {
- lf = kLF;
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- }
- else if(**p == '(') {
- double_ = FALSE;
- lf = kLF;
- }
- string_obj* str = STRING_NEW("");
- int read_end_of_statment = -1;
- if(!read_until_next_close_character('(', ')', p, str, &read_end_of_statment, FALSE, sname, sline)) {
- string_delete(str);
- return FALSE;
- }
- string_push_back(not_evaled, string_c_str(str));
- string_push_back(statment->mTitle, string_c_str(str));
- string_erase(str, 0, 1);
- string_trunc(str, string_length(str)-1);
- sStatments* statments = STATMENTS_NEW();
- if(!parse(string_c_str(str), sname, sline, statments))
- {
- string_delete(str);
- sStatments_delete(statments);
- return FALSE;
- }
- string_delete(str);
- if(double_) {
- if(!add_arg_to_command(command, ARG_NEW(4, MANAGED sAtCommand_new(MANAGED statments, lf)), sname, sline))
- {
- return FALSE;
- }
- }
- else {
- if(!add_arg_to_command(command, ARG_NEW(2, MANAGED statments), sname, sline))
- {
- return FALSE;
- }
- }
- }
- else if(**p == '>') {
- /// ?????? ///
- if(*(*p+1) == '(') {
- string_push_back2(not_evaled, **p);
- (*p)++;
- string_obj* cmd = STRING_NEW("");
- if(!read_until_next_close_character('(', ')', p, cmd, read_end_of_statment, FALSE, sname, sline)) {
- string_delete(cmd);
- return FALSE;
- }
- string_push_back(not_evaled, string_c_str(cmd));
- string_erase(cmd, 0, 1); // (???
- string_trunc(cmd, string_length(cmd)-1); // )???
- sStatments* statments = STATMENTS_NEW();
- if(!parse(string_c_str(cmd), sname, sline, statments)) {
- sStatments_delete(statments);
- string_delete(cmd);
- return FALSE;
- }
- string_delete(cmd);
- if(vector_size(command->mArgs) == 0) {
- err_msg("command name must be determined staticaly", sname, *sline);
- sStatments_delete(statments);
- return FALSE;
- }
- if(!add_arg_to_command(command, ARG_NEW(8, MANAGED statments), sname, sline))
- {
- return FALSE;
- }
- }
- /// ??????
- else if(*(*p+1) == '>') {
- string_push_back(not_evaled, ">>");
- (*p)+=2;
- int fd = 1;
- enum eRedirect type = kRedirectAppend;
- skip_spaces(p, not_evaled);
- if(!add_arg_to_command(command, ARG_NEW(9, MANAGED sRedirect_new(type, fd)), sname, sline))
- {
- return FALSE;
- }
- }
- /// ??????
- else {
- string_push_back(not_evaled, ">");
- (*p)++;
- int fd = 1;
- enum eRedirect type = kRedirectOverwrite;
- skip_spaces(p, not_evaled);
- if(!add_arg_to_command(command, ARG_NEW(9, MANAGED sRedirect_new(type, fd)), sname, sline))
- {
- return FALSE;
- }
- }
- }
- else if(**p == '<') {
- /// ????????
- if(*(*p+1) == '<') {
- string_push_back2(not_evaled, **p);
- (*p)++;
- string_push_back2(not_evaled, **p);
- (*p)++;
- skip_spaces(p, not_evaled);
- BOOL expand_env = TRUE;
- BOOL squote = FALSE;
- BOOL dquote = FALSE;
- if(**p == '\'') {
- squote = TRUE;
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- else if(**p == '"') {
- dquote = TRUE;
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- string_obj* name = STRING_NEW("");
- while(**p) {
- if(**p == '\n') {
- string_push_back2(not_evaled, **p);
- (*p)++;
- break;
- }
- else if(**p == ' ' || **p == '\t') {
- skip_spaces(p, not_evaled);
- if(**p != '\n') {
- err_msg("invalid here document name1", sname, *sline);
- string_delete(name);
- return FALSE;
- }
- string_push_back2(not_evaled, **p);
- (*p)++;
- break;
- }
- else if(**p >='A' && ** p <= 'Z' || **p >='a' && **p <='z')
- {
- string_push_back2(name, **p);
- string_push_back2(not_evaled, **p);
- (*p)++;
- }
- else if(dquote && **p == '"') {
- expand_env = TRUE;
- dquote = FALSE;
- string_push_back2(not_evaled, **p);
- (*p)++;
- skip_spaces(p, not_evaled);
- if(**p != '\n') {
- err_msg("invalid here document name2", sname, *sline);
- string_delete(name);
- return FALSE;
- }
- string_push_back2(not_evaled, **p);
- (*p)++;
- break;
- }
- else if(squote && **p == '\'') {
- expand_env = FALSE;
- squote = FALSE;
- string_push_back2(not_evaled, **p);
- (*p)++;
- skip_spaces(p, not_evaled);
- if(**p != '\n') {
- err_msg("invalid here document name3", sname, *sline);
- string_delete(name);
- return FALSE;
- }
- string_push_back2(not_evaled, **p);
- (*p)++;
- break;
- }
- else {…