Esempio n. 1
0
void ticksize_command(const char *arg, struct session *ses)
{
    int x;
    char left[BUFFER_SIZE], *err;

    get_arg(arg, left, 1, ses);
    if (!ses)
    {
        tintin_printf(ses, "#NO SESSION ACTIVE => NO TICKER!");
        return;
    }
    if (!*left || !isadigit(*left))
    {
        tintin_eprintf(ses, "#SYNTAX: #ticksize <number>");
        return;
    }
    x=strtol(left, &err, 10);
    if (*err || x<1 || x>=0x7fffffff)
    {
        tintin_eprintf(ses, "#TICKSIZE OUT OF RANGE (1..%d)", 0x7fffffff);
        return;
    }
    ses->tick_size = x;
    ses->time0 = time(NULL);
    tintin_printf(ses, "#OK. NEW TICKSIZE SET");
}
// basic parser function
const char* ScriptHandler::readToken(bool no_kidoku)
{
    current_script = next_script;
    const char* buf = current_script;
    end_status = END_NONE;
    current_variable.type = VAR_NONE;

    text_flag = false;

    SKIP_SPACE(buf);
    if (!no_kidoku) markAsKidoku(buf);
    
readTokenTop:
    string_buffer.trunc(0);
    char ch = *buf;
    if (ch == ';') { // comment
        addStrBuf(ch);
        do {
            ch = *++buf;
            addStrBuf(ch);
        } while (ch != 0x0a && ch != '\0');
    }
    else if (ch & 0x80
             || (ch >= '0' && ch <= '9')
             || ch == '@' || ch == '\\' || ch == '/'
             || ch == '%' || ch == '?' || ch == '$'
             || ch == '[' || ch == '('
             || ch == '!' || ch == '#' || ch == ',' || ch == '"') {
        // text
        if (ch != '!' and !warned_unmarked) {
//            errorWarning("unmarked text found"); //Mion: stop warnings, for compatibility
            // TODO: make this more robust; permit only !-directives
//            warned_unmarked = true;
        }
        bool loop_flag = true;
        bool ignore_click_flag = false;
        do {
            char bytes = file_encoding->NextCharSize(buf);
            if (bytes > 1) {
                if (textgosub_flag && !ignore_click_flag && checkClickstr(buf))
                    loop_flag = false;
                string_buffer.add(buf, bytes);
                buf += bytes;
                SKIP_SPACE(buf);
                ch = *buf;
            }
            else {
                if (ch == '%' || ch == '?') {
                    addIntVariable(&buf);
                }
                else if (ch == '$') {
                    addStrVariable(&buf);
                }
                else {
                    if (textgosub_flag && !ignore_click_flag &&
                        checkClickstr(buf))
                        loop_flag = false;

                    string_buffer += ch;
                    buf++;
                    ignore_click_flag = false;
                    if (ch == '_') ignore_click_flag = true;
                }

                // CHECKME: why do we ignore text markers here?
                if (isadigit(ch) &&
                    (isawspace(*buf) || *buf == file_encoding->TextMarker()) &&
                    (string_buffer.length() % 2)) {
                    string_buffer += ' ';
                }

                ch = *buf;
                if (ch == 0x0a || ch == '\0' || !loop_flag ||
                    ch == file_encoding->TextMarker()) {
                    break;
                }

                SKIP_SPACE(buf);
                ch = *buf;
            }
        }
        while (ch != 0x0a && ch != '\0' && loop_flag &&
               ch != file_encoding->TextMarker()) /*nop*/;
        if (loop_flag && ch == 0x0a && !(textgosub_flag && linepage_flag)) {
            string_buffer += ch;
            if (!no_kidoku) markAsKidoku(buf++);
        }

        text_flag = true;
    }
    else if (ch == file_encoding->TextMarker()) {
        ch = *++buf;
        while (ch != file_encoding->TextMarker() && ch != 0x0a && ch != '\0') {
            if ((ch == '\\' || ch == '@') &&
                (textgosub_flag || buf[1] == 0x0a || buf[1] == 0)) {
                string_buffer += *buf++;
                ch = *buf;
                break;
            }

            // Interpolate expressions.
            if (ch == '{' &&
                (buf[1] == '%' || buf[1] == '$' || buf[1] == '?'))
            {
                const char* start = buf + 1;
                while (*buf && *buf != '\n' && *buf != '}') ++buf;
                if (*buf != '}')
                    errorAndExit("interpolation missing }");
                pstring var_expr(start, buf++ - start);
                const char* var_iter = var_expr;
                if (var_expr[0] == '$') {
                    pstring val = parseStr(&var_iter);
                    if (val[0] == file_encoding->TextMarker()) val.remove(0, 1);
                    string_buffer += val;
                }
                else {
                    string_buffer += stringFromInteger(parseInt(&var_iter),
                                                       -1);
                }   
                ch = *buf;
                continue;
            }
            
            if (file_encoding->UseTags() && ch == '~' && (ch = *++buf) != '~') {
                while (ch != '~') {
                    int l;
                    string_buffer += file_encoding->TranslateTag(buf, l);
                    buf += l;
                    ch = *buf;
                }
                ch = *++buf;
                continue;
            }

            int bytes;
            // NOTE: we don't substitute ligatures at this stage.
            string_buffer += file_encoding->Encode(file_encoding->DecodeChar(buf, bytes));
            buf += bytes;
            ch = *buf;
        }
        if (ch == file_encoding->TextMarker() && !textgosub_flag) ++buf;

        if (ch == 0x0a && !(textgosub_flag && linepage_flag)) {
            string_buffer += ch;
            if (!no_kidoku) markAsKidoku(buf++);
        }

        text_flag   = true;
    }
    else if ((ch >= 'a' && ch <= 'z')
             || (ch >= 'A' && ch <= 'Z')
             || ch == '_') { // command
        do {
            if (ch >= 'A' && ch <= 'Z') ch += 'a' - 'A';

            string_buffer += ch;
            ch = *++buf;
        }
        while ((ch >= 'a' && ch <= 'z')
               || (ch >= 'A' && ch <= 'Z')
               || (ch >= '0' && ch <= '9')
               || ch == '_');
    }
    else if (ch == '*') { // label
        return readLabel();
    }
    else if (ch == '~' || ch == 0x0a || ch == ':') {
        string_buffer += ch;
        if (!no_kidoku) markAsKidoku(buf++);
    }
    else if (ch != '\0') {
        fprintf(stderr, "readToken: skip unknown heading character %c (%x)\n",
		ch, ch);
        buf++;
        goto readTokenTop;
    }

    if (text_flag)
        next_script = buf;
    else
        next_script = checkComma(buf);

    return string_buffer;
}
int ScriptHandler::parseInt(const char** buf)
{
    int ret = 0;

    SKIP_SPACE(*buf);

    if (**buf == '%') {
        (*buf)++;
        current_variable.var_no = parseInt(buf);
        current_variable.type = VAR_INT;
        return getVariableData(current_variable.var_no).get_num();
    }
    else if (**buf == '?') {
	array_ref arr = parseArray(buf);
	current_variable.var_no = arr.first;
	current_variable.array = arr.second;
        current_variable.type  = VAR_ARRAY;
	ArrayVariable::iterator i = arrays.find(arr.first);
	if (i != arrays.end()) {
	    if (arr.second.size() < i->second.dimensions())
		arr.second.push_back(0);
	    return i->second.getValue(arr.second);
	}
	return 0;
    }
    else {
        char ch;
	pstring alias_buf;
        int alias_no = 0;
        bool direct_num_flag = false;
        bool num_alias_flag  = false;
        bool hex_num_flag = (*buf)[0] == '0' && (*buf)[1] == 'x';
        if (hex_num_flag) *buf += 2;

        const char* buf_start = *buf;
        while (1) {
            ch = **buf;

            if (hex_num_flag && isaxdigit(ch)) {
                alias_no *= 16;
                if (isadigit(ch)) alias_no += ch - '0';
                else if (isupper(ch)) alias_no += ch - 'A' + 10;
                else alias_no += ch - 'a' + 10;
            }
            else if (isadigit(ch)) {
                if (!num_alias_flag) direct_num_flag = true;

                if (direct_num_flag)
                    alias_no = alias_no * 10 + ch - '0';
                else
                    alias_buf += ch;
            }
            else if (isalpha(ch) || ch == '_') {
                if (ch >= 'A' && ch <= 'Z') ch += 'a' - 'A';

                if (hex_num_flag || direct_num_flag) break;

                num_alias_flag = true;
                alias_buf += ch;
            }
            else break;

            (*buf)++;
        }

        if (*buf - buf_start == 0) {
            current_variable.type = VAR_NONE;
            return 0;
        }

        /* ---------------------------------------- */
        /* Solve num aliases */
        if (num_alias_flag) {

	    numalias_t::iterator a = num_aliases.find(alias_buf);
	    if (a == num_aliases.end()) {
                printf("can't find num alias for %s... assume 0.\n",
		       (const char*) alias_buf);
                current_variable.type = VAR_NONE;
                *buf = buf_start;
                return 0;
	    }
	    else {
		alias_no = a->second;
	    }
        }

        current_variable.type = VAR_INT | VAR_CONST;
        ret = alias_no;
    }

    SKIP_SPACE(*buf);

    return ret;
}