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; }