void json_parser<_Handler>::parse() { m_handler.begin_parse(); skip_blanks(); if (has_char()) root_value(); if (has_char()) throw json::parse_error("parse: unexpected trailing string segment.", offset()); m_handler.end_parse(); }
void tokenizer::numeral() { const char* p = mp_char; push_pos(); size_t len = 1; size_t sep_count = 0; for (next(); has_char(); next(), ++len) { if (*mp_char == ':') { // Treat this as a name. This may be a part of a row-only range (e.g. 3:3). pop_pos(); name(); return; } if (is_digit(*mp_char)) continue; if (is_decimal_sep(*mp_char) && ++sep_count <= 1) continue; break; } if (sep_count > 1) { ostringstream os; os << "error parsing numeral: " << std::string(p, len); throw formula_lexer::tokenize_error(os.str()); } double val = global::to_double(p, len); m_tokens.push_back(new lexer_value_token(val)); }
void sax_parser<_Handler,_Config>::characters() { size_t first = m_pos; const char* p0 = m_char; for (; has_char(); next()) { if (cur_char() == '<') break; if (cur_char() == '&') { // Text span with one or more encoded characters. Parse using cell buffer. cell_buffer& buf = get_cell_buffer(); buf.reset(); buf.append(p0, m_pos-first); characters_with_encoded_char(buf); if (buf.empty()) m_handler.characters(pstring(), false); else m_handler.characters(pstring(buf.get(), buf.size()), true); return; } } if (m_pos > first) { size_t size = m_pos - first; pstring val(m_content + first, size); m_handler.characters(val, false); } }
uint8_t parser_base::parse_uint8() { // 0 - 255 int val = 0; size_t len = 0; for (; has_char() && len <= 3; next()) { char c = cur_char(); if (!is_numeric(c)) break; ++len; val *= 10; val += c - '0'; } if (!len) throw css::parse_error("parse_uint8: no digit encountered."); int maxval = std::numeric_limits<uint8_t>::max(); if (val > maxval) val = maxval; return static_cast<uint8_t>(val); }
void parser_base::characters_with_encoded_char(cell_buffer& buf) { assert(cur_char() == '&'); parse_encoded_char(buf); size_t first = m_pos; while (has_char()) { if (cur_char() == '&') { if (m_pos > first) buf.append(m_content+first, m_pos-first); parse_encoded_char(buf); first = m_pos; } if (cur_char() == '<') break; if (cur_char() != '&') next(); } if (m_pos > first) buf.append(m_content+first, m_pos-first); }
int has_pipe(char ** cmd, int args_count) { /* * funkcja zwraca index operatora potoku * jesli go nie znajdzie, zwraca 0 */ return has_char(cmd, args_count, '|'); }
void parser_base::skip_blanks() { for (; has_char(); next()) { if (!is_blank(*mp_char)) break; } }
void sax_parser<_Handler,_Config>::special_tag() { assert(cur_char() == '!'); // This can be either <![CDATA, <!--, or <!DOCTYPE. size_t len = remains(); if (len < 2) throw sax::malformed_xml_error("special tag too short."); switch (next_char()) { case '-': { // Possibly comment. if (next_char() != '-') throw sax::malformed_xml_error("comment expected."); len -= 2; if (len < 3) throw sax::malformed_xml_error("malformed comment."); next(); comment(); } break; case '[': { // Possibly a CDATA. expects_next("CDATA[", 6); if (has_char()) cdata(); } break; case 'D': { // check if this is a DOCTYPE. expects_next("OCTYPE", 6); blank(); if (has_char()) doctype(); } break; default: throw sax::malformed_xml_error("failed to parse special tag."); } }
void parser_base::skip_to(const char*&p, size_t& len, char c) { p = mp_char; len = 0; for (; has_char(); next(), ++len) { if (cur_char() == c) return; } }
void parser_base::skip_to_or_blank(const char*&p, size_t& len, const char* chars) { p = mp_char; len = 0; for (; has_char(); next(), ++len) { if (is_blank(*mp_char) || is_in(*mp_char, chars)) return; } }
void parser_base::blank() { char c = cur_char(); while (is_blank(c)) { next(); if (!has_char()) return; c = cur_char(); } }
void json_parser<_Handler>::number_with_exp(double base) { assert(cur_char() == 'e' || cur_char() == 'E'); next(); if (!has_char()) throw json::parse_error("number_with_exp: illegal exponent value.", offset()); long exp = parse_long_or_throw(); base *= std::pow(10.0, exp); m_handler.number(base); skip_blanks(); }
void json_parser<_Handler>::array() { assert(cur_char() == '['); m_handler.begin_array(); for (next(); has_char(); next()) { if (cur_char() == ']') { m_handler.end_array(); next(); skip_blanks(); return; } skip_blanks(); value(); skip_blanks(); if (has_char()) { switch (cur_char()) { case ']': m_handler.end_array(); next(); skip_blanks(); return; case ',': continue; default: json::parse_error::throw_with( "array: either ']' or ',' expected, but '", cur_char(), "' found.", offset()); } } } throw json::parse_error("array: failed to parse array.", offset()); }
char* squeeze( char* cstr, const char* filter ) { if( cstr != NULL && filter != NULL ) { size_t pos = 0 ; while( cstr[pos] != 0 ) { if( has_char( filter, cstr[pos] ) ) remove_char_at( cstr, pos ) ; else ++pos ; } } return cstr ; }
void tokenizer::string() { next(); const char* p = mp_char; size_t len = 0; for (; *mp_char != '"' && has_char(); ++len) next(); if (len) m_tokens.push_back(new lexer_string_token(p, len)); if (*mp_char == '"') next(); }
void sax_parser<_Handler,_Config>::header() { // we don't handle multi byte encodings so we can just skip bom entry if exists. skip_bom(); blank(); if (!has_char() || cur_char() != '<') throw sax::malformed_xml_error("xml file must begin with '<'."); if (config_type::strict_xml_declaration) { if (next_char_checked() != '?') throw sax::malformed_xml_error("xml file must begin with '<?'."); declaration("xml"); } }
void sax_parser<_Handler,_Config>::body() { while (has_char()) { if (cur_char() == '<') { element(); if (!m_root_elem_open) // Root element closed. Stop parsing. return; } else if (m_nest_level) // Call characters only when in xml hierarchy. characters(); else next(); } }
void parser_base::identifier(const char*& p, size_t& len, const char* extra) { p = mp_char; len = 1; for (next(); has_char(); next(), ++len) { char c = cur_char(); if (is_alpha(c) || is_name_char(c) || is_numeric(c)) continue; if (extra) { // See if the character is one of the extra allowed characters. if (is_in(c, extra)) continue; } return; } }
void parser_base::comment() { assert(cur_char() == '*'); // Parse until we reach either EOF or '*/'. bool has_star = false; for (next(); has_char(); next()) { char c = cur_char(); if (has_star && c == '/') { next(); return; } has_star = (c == '*'); } // EOF reached. }
void parser_base::parse_encoded_char(cell_buffer& buf) { assert(cur_char() == '&'); next(); const char* p0 = m_char; for (; has_char(); next()) { if (cur_char() != ';') continue; size_t n = m_char - p0; if (!n) throw malformed_xml_error("empty encoded character."); #if ORCUS_DEBUG_SAX_PARSER cout << "sax_parser::parse_encoded_char: raw='" << std::string(p0, n) << "'" << endl; #endif char c = decode_xml_encoded_char(p0, n); if (c) buf.append(&c, 1); // Move to the character past ';' before returning to the parent call. next(); if (!c) { #if ORCUS_DEBUG_SAX_PARSER cout << "sax_parser::parse_encoded_char: not a known encoding name. Use the original." << endl; #endif // Unexpected encoding name. Use the original text. buf.append(p0, m_char-p0); } return; } throw malformed_xml_error("error parsing encoded character: terminating character is not found."); }
void tokenizer::name() { assert(m_scope == 0); const char* p = mp_char; char c = *mp_char; if (c == '[') ++m_scope; else if (c == ']') { m_tokens.push_back(new lexer_name_token(p, 1)); next(); return; } size_t len = 1; for (next(); has_char(); next(), ++len) { c = *mp_char; if (c == '[') { ++m_scope; } else if (c == ']') { if (!m_scope) break; --m_scope; } else if (is_op(c)) break; } m_tokens.push_back(new lexer_name_token(p, len)); }
void parser_base::value_with_encoded_char(cell_buffer& buf, pstring& str) { assert(cur_char() == '&'); parse_encoded_char(buf); assert(cur_char() != ';'); size_t first = m_pos; while (has_char()) { if (cur_char() == '&') { if (m_pos > first) buf.append(m_content+first, m_pos-first); parse_encoded_char(buf); first = m_pos; } if (cur_char() == '"') break; if (cur_char() != '&') next(); } if (m_pos > first) buf.append(m_content+first, m_pos-first); if (!buf.empty()) str = pstring(buf.get(), buf.size()); // Skip the closing quote. assert(cur_char() == '"'); next(); }
void tokenizer::run() { if (!m_size) // Nothing to do. return; init(); while (has_char()) { if (is_digit(*mp_char)) { numeral(); continue; } if (!is_op(*mp_char)) { name(); continue; } if (is_arg_sep(*mp_char)) { op(op_sep); continue; } switch (*mp_char) { case ' ': space(); break; case '+': op(op_plus); break; case '-': op(op_minus); break; case '/': op(op_divide); break; case '*': op(op_multiply); break; case '=': op(op_equal); break; case '<': op(op_less); break; case '>': op(op_greater); break; case '(': op(op_open); break; case ')': op(op_close); break; case '"': string(); break; } } }
void json_parser<_Handler>::object() { assert(cur_char() == '{'); m_handler.begin_object(); for (next(); has_char(); next()) { skip_blanks(); if (!has_char()) throw json::parse_error("object: stream ended prematurely before reaching a key.", offset()); switch (cur_char()) { case '}': m_handler.end_object(); next(); skip_blanks(); return; case '"': break; default: json::parse_error::throw_with( "object: '\"' was expected, but '", cur_char(), "' found.", offset()); } parse_quoted_string_state res = parse_string(); if (!res.str) { // Parsing was unsuccessful. if (res.length == parse_quoted_string_state::error_no_closing_quote) throw json::parse_error("object: stream ended prematurely before reaching the closing quote of a key.", offset()); else if (res.length == parse_quoted_string_state::error_illegal_escape_char) json::parse_error::throw_with( "object: illegal escape character '", cur_char(), "' in key value.", offset()); else throw json::parse_error("object: unknown error while parsing a key value.", offset()); } m_handler.object_key(res.str, res.length, res.transient); skip_blanks(); if (cur_char() != ':') json::parse_error::throw_with( "object: ':' was expected, but '", cur_char(), "' found.", offset()); next(); skip_blanks(); if (!has_char()) throw json::parse_error("object: stream ended prematurely before reaching a value.", offset()); value(); skip_blanks(); if (!has_char()) throw json::parse_error("object: stream ended prematurely before reaching either ']' or ','.", offset()); switch (cur_char()) { case '}': m_handler.end_object(); next(); skip_blanks(); return; case ',': continue; default: json::parse_error::throw_with( "object: either ']' or ',' expected, but '", cur_char(), "' found.", offset()); } } throw json::parse_error("object: closing '}' was never reached.", offset()); }
int exec_cmd(char **args, int args_count, int run_background, int logical, int _stdin, int _stdout, int is_child) { /* * Funkcja tworzy potomka który wykonuje przekazana komende. * * Parametry: * is_child - informuje funkcję czy została ona wywołana przez potomka procesu głównego */ pid_t pid; int status; if (run_background && logical) { fprintf(stderr, "Polecenia warunkowe nie mogą występować dla poleceń uruchamianych w tle!\n"); return 0; } pid = fork(); switch (pid) { // error case -1: { perror("SOPshell fork"); status = EXIT_FAILURE; break; } // child case 0: { int pipe_idx = has_pipe(args, args_count); pid_t child_pid = -1; if(pipe_idx) { int _pipe[2]; if (pipe(_pipe) == -1) { perror("SOPshell pipe"); exit(EXIT_FAILURE); } child_pid = fork(); switch (child_pid) { case -1: { perror("SOPshell fork"); status = EXIT_FAILURE; break; } case 0: { if(args_count - pipe_idx - 1 > 0) { close(_pipe[1]); return exec_cmd(&args[pipe_idx + 1], args_count - pipe_idx - 1, run_background, logical, _pipe[0], _stdout, 1); } else { exit(EXIT_SUCCESS); } } default: { char ** new_args = malloc((pipe_idx) * sizeof(args[0])); memcpy(new_args, args, pipe_idx * sizeof(args[0])); new_args[pipe_idx] = NULL; args = new_args; args_count = pipe_idx; close(_pipe[0]); _stdout = _pipe[1]; } } }; dup2(_stdin, 0); dup2(_stdout, 1); int redirect_stdout = has_char(args, args_count, '>'); if (redirect_stdout && args[redirect_stdout+1]) { int fd = open(args[redirect_stdout+1], O_RDWR | O_CREAT, S_IRWXU | S_IRWXG); if(fd == -1) { perror("SOPshell open"); } else { args[redirect_stdout] = NULL; args_count = redirect_stdout; dup2(fd, _stdout); close(fd); } } int redirect_stdin = has_char(args, args_count, '<'); if (redirect_stdin && args[redirect_stdin+1]) { int fd = open(args[redirect_stdin+1], O_RDONLY); if(fd == -1) { perror("SOPshell open"); } args[redirect_stdin] = NULL; dup2(fd, _stdin); close(fd); } int result = execvp(args[0], args); if (result == -1) { fprintf(stderr, "SOPshell: komenda nie znaleziona: %s\n", args[0]); result = EXIT_FAILURE; } // ładnie zamykamy co otwieraliśmy close(_stdin); close(_stdout); exit(result); } // owner default: { if(run_background) { add_bg_process(args[0], pid); fprintf(stdout, "[%d] %s pid: %d\n", bg_proc_count, args[0], pid); } else { do { RUNNING = 1; waitpid(pid, &status, WUNTRACED); if(!RUNNING) { kill(pid, SIGINT); printf("\n"); } } while (!WIFEXITED(status) && !WIFSIGNALED(status)); if (WIFEXITED(status)) status = WEXITSTATUS(status); if (WIFSIGNALED(status)) status = EXIT_FAILURE; //printf("pid: %d, status:%d, WIFEXITED: %d, WEXITSTATUS: %d, WIFSIGNALED: %d, WTERMSIG: %d\n", pid, status, WIFEXITED(status), WEXITSTATUS(status), WIFSIGNALED(status), WTERMSIG(status)); } if (is_child) { exit(EXIT_SUCCESS); } } } //printf("status: %d", status); return status == EXIT_SUCCESS; }