예제 #1
0
파일: json_parser.hpp 프로젝트: jvsg/orcus
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();
}
예제 #2
0
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));
}
예제 #3
0
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);
    }
}
예제 #4
0
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);
}
예제 #5
0
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);
}
예제 #6
0
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, '|');
}
예제 #7
0
void parser_base::skip_blanks()
{
    for (; has_char(); next())
    {
        if (!is_blank(*mp_char))
            break;
    }
}
예제 #8
0
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.");
    }
}
예제 #9
0
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;
    }
}
예제 #10
0
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;
    }
}
예제 #11
0
void parser_base::blank()
{
    char c = cur_char();
    while (is_blank(c))
    {
        next();
        if (!has_char())
            return;

        c = cur_char();
    }
}
예제 #12
0
파일: json_parser.hpp 프로젝트: jvsg/orcus
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();
}
예제 #13
0
파일: json_parser.hpp 프로젝트: jvsg/orcus
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 ;
}
예제 #15
0
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();
}
예제 #16
0
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");
    }
}
예제 #17
0
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();
    }
}
예제 #18
0
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;
    }
}
예제 #19
0
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.
}
예제 #20
0
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.");
}
예제 #21
0
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));
}
예제 #22
0
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();
}
예제 #23
0
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;
        }
    }
}
예제 #24
0
파일: json_parser.hpp 프로젝트: jvsg/orcus
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());
}
예제 #25
0
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;

}