Example #1
0
        int here_document(int term, int indent)
        {
            int c;
            string line = String.Empty;
            RNode list = null;
            int linesave = thread.line;

            newtok();
            switch (term) {
            case '\'':
                goto case '`';
            case '"':
                goto case '`';
            case '`':
                while ((c = nextc()) != term) {
                    tokadd(c);
                }
                if (term == '\'') term = '\0';
                break;

            default:
                c = term;
                term = '"';
                if (!is_identchar(c)) {
                    ruby.warn("use of bare << to mean <<\"\" is deprecated");
                    break;
                }
                while (is_identchar(c)) {
                    tokadd(c);
                    c = nextc();
                }
                pushback(c);
                break;
            }
            string lastline_save = lastline;
            int offset_save = pcur - pbeg;
            string eos = string.Copy(tok());
            int len = eos.Length;

            string str = String.Empty;
            for (;;) {
                lastline = line = getline();
                if (line == null) {
                    thread.line = linesave;
                    thread.CompileError("can't find string \"" + eos + "\" anywhere before EOF");
                    return 0;
                }
                thread.line++;
                string p = line;
                if (indent > 0) {
                    while (p.Length > 0 && (p[0] == ' ' || p[0] == '\t')) {
                        p = p.Substring(1);
                    }
                }
                if (String.Compare(eos, 0, p, 0, len) == 0) {
                    if (p[len] == '\n' || p[len] == '\r')
                        break;
                    if (len == line.Length)
                        break;
                }
                pbeg = pcur = 0;
                pend = pcur + line.Length;
            retry:
                switch (parse_string(term, '\n', '\n')) {
                case Token.tSTRING:
                    // fall down to the next case
                case Token.tXSTRING:
                    {
                    yylval = (string)yylval + "\n";
                    }
                    if (list == null) {
                        str += (string)yylval;
                    }
                    else {
                        RNode.list_append(thread, list, new RNStr(thread, ruby, (string)yylval));
                    }
                    break;
                case Token.tDSTRING:
                    if (list == null) list = new RNDStr(thread, ruby, str);
                    goto case Token.tDXSTRING;
                case Token.tDXSTRING:
                    if (list == null) list = new RNDXStr(thread, ruby, str);

                    RNode.list_append(thread, (RNode)yylval, new RNStr(thread, ruby, "\n"));
                    RNStr val = new RNStr((RNStr)yylval);
                    yylval = new RNArray(thread, val);
                    ((RNode)yylval).next = ((RNode)yylval).head.next;
                    RNode.list_concat(list, (RNode)yylval);
                    break;

                case 0:
                    thread.line = linesave;
                    thread.CompileError("can't find string \"" + eos + "\" anywhere before EOF");
                    return 0;
                }
                if (pcur != pend) {
                    goto retry;
                }
            }
            lastline = lastline_save;
            pbeg = 0;
            pend = lastline.Length;
            pcur = offset_save;

            lex_state = EXPR.END;
            heredoc_end = thread.line;
            thread.line = linesave;
            if (list != null) {
                list.SetLine(linesave+1);
                yylval = list;
            }
            switch (term) {
            case '\0':
                goto case '"';
            case '\'':
                goto case '"';
            case '"':
                if (list != null) return Token.tDSTRING;
                yylval = str;
                return Token.tSTRING;
            case '`':
                if (list != null) return Token.tDXSTRING;
                yylval = str;
                return Token.tXSTRING;
            }
            return 0;
        }
Example #2
0
        int parse_quotedwords(int term, int paren)
        {
            RNode qwords = null;
            int strstart = thread.line;
            int c;
            int nest = 0;

            newtok();

            for (c = nextc(); Char.IsWhiteSpace((char)c); c = nextc())
                ;                /* skip preceding spaces */
            pushback(c);
            while ((c = nextc()) != term || nest > 0) {
                if (c == -1) {
                    thread.line = strstart;
                    thread.CompileError("unterminated string meets end of file");
                    return 0;
                }
                /*
                if (ismbchar(c)) {
                    int i, len = mbclen(c)-1;

                    for (i = 0; i < len; i++) {
                        tokadd(c);
                        c = nextc();
                    }
                }
                */
                else if (c == '\\') {
                    c = nextc();
                    switch (c) {
                    case '\n':
                        continue;
                    case '\\':
                        c = '\\';
                        break;
                    default:
                        if (c == term) {
                            tokadd(c);
                            continue;
                        }
                        if (!Char.IsWhiteSpace((char)c))
                            tokadd('\\');
                        break;
                    }
                }
                else if (Char.IsWhiteSpace((char)c)) {

                    RNode str = new RNStr(thread, ruby, tok());
                    newtok();
                    if (qwords == null) qwords = new RNArray(thread, str);
                    else RNode.list_append(thread, qwords, str);
                    for (c = nextc(); Char.IsWhiteSpace((char)c); c = nextc())
                        ;                /* skip continuous spaces */
                    pushback(c);
                    continue;
                }

                if (paren != 0) {
                    if (c == paren) nest++;
                    if (c == term && nest-- == 0) break;
                }
                tokadd(c);
            }

            if (toklen() > 0) {
                RNode str = new RNStr(thread, ruby, tok());
                if (qwords == null) qwords = new RNArray(thread, str);
                else RNode.list_append(thread, qwords, str);
            }
            if (qwords == null) qwords = new RNZArray(thread);
            yylval = qwords;
            lex_state = EXPR.END;
            return Token.tDSTRING;
        }