diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index 8abeb8e..4f6b644 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -74,8 +74,8 @@ struct OSTD_EXPORT cs_strref { friend inline cs_strref cs_make_strref(char const *p, cs_shared_state &cs); cs_strref() = delete; - cs_strref(cs_shared_state &cs, ostd::string_range str); - cs_strref(cs_state &cs, ostd::string_range str); + cs_strref(cs_shared_state &cs, std::string_view str); + cs_strref(cs_state &cs, std::string_view str); cs_strref(cs_strref const &ref); @@ -83,17 +83,17 @@ struct OSTD_EXPORT cs_strref { cs_strref &operator=(cs_strref const &ref); - operator ostd::string_range() const; + operator std::string_view() const; std::size_t size() const { - return ostd::string_range{*this}.size(); + return std::string_view{*this}.size(); } std::size_t length() const { - return ostd::string_range{*this}.length(); + return std::string_view{*this}.length(); } char const *data() const { - return ostd::string_range{*this}.data(); + return std::string_view{*this}.data(); } bool operator==(cs_strref const &s) const; @@ -125,7 +125,7 @@ struct OSTD_EXPORT cs_value { void set_int(cs_int val); void set_float(cs_float val); - void set_str(ostd::string_range val); + void set_str(std::string_view val); void set_str(cs_strref const &val); void set_none(); void set_code(cs_bcode *val); @@ -143,7 +143,7 @@ struct OSTD_EXPORT cs_value { void force_none(); cs_float force_float(); cs_int force_int(); - ostd::string_range force_str(); + std::string_view force_str(); bool code_is_empty() const; @@ -203,7 +203,7 @@ struct OSTD_EXPORT cs_ident { cs_ident &operator=(cs_ident &&) = delete; cs_ident_type get_type() const; - ostd::string_range get_name() const; + std::string_view get_name() const; int get_flags() const; int get_index() const; @@ -329,7 +329,7 @@ struct OSTD_EXPORT cs_alias: cs_ident { void get_cval(cs_value &v) const; private: cs_alias(cs_state &cs, cs_strref n, cs_strref a, int flags); - cs_alias(cs_state &cs, cs_strref n, ostd::string_range a, int flags); + cs_alias(cs_state &cs, cs_strref n, std::string_view a, int flags); cs_alias(cs_state &cs, cs_strref n, cs_int a, int flags); cs_alias(cs_state &cs, cs_strref n, cs_float a, int flags); cs_alias(cs_state &cs, cs_strref n, int flags); @@ -345,7 +345,7 @@ struct cs_command: cs_ident { friend struct cs_shared_state; friend struct cs_cmd_internal; - ostd::string_range get_args() const; + std::string_view get_args() const; int get_num_args() const; private: @@ -431,58 +431,58 @@ struct OSTD_EXPORT cs_state { void clear_override(cs_ident &id); void clear_overrides(); - cs_ident *new_ident(ostd::string_range name, int flags = CS_IDF_UNKNOWN); + cs_ident *new_ident(std::string_view name, int flags = CS_IDF_UNKNOWN); cs_ident *force_ident(cs_value &v); cs_ivar *new_ivar( - ostd::string_range n, cs_int m, cs_int x, cs_int v, + std::string_view n, cs_int m, cs_int x, cs_int v, cs_var_cb f = cs_var_cb(), int flags = 0 ); cs_fvar *new_fvar( - ostd::string_range n, cs_float m, cs_float x, cs_float v, + std::string_view n, cs_float m, cs_float x, cs_float v, cs_var_cb f = cs_var_cb(), int flags = 0 ); cs_svar *new_svar( - ostd::string_range n, ostd::string_range v, + std::string_view n, std::string_view v, cs_var_cb f = cs_var_cb(), int flags = 0 ); cs_command *new_command( - ostd::string_range name, ostd::string_range args, cs_command_cb func + std::string_view name, std::string_view args, cs_command_cb func ); - cs_ident *get_ident(ostd::string_range name); - cs_alias *get_alias(ostd::string_range name); - bool have_ident(ostd::string_range name); + cs_ident *get_ident(std::string_view name); + cs_alias *get_alias(std::string_view name); + bool have_ident(std::string_view name); cs_ident_r get_idents(); cs_const_ident_r get_idents() const; - void reset_var(ostd::string_range name); - void touch_var(ostd::string_range name); + void reset_var(std::string_view name); + void touch_var(std::string_view name); cs_strref run_str(cs_bcode *code); - cs_strref run_str(ostd::string_range code); + cs_strref run_str(std::string_view code); cs_strref run_str(cs_ident *id, cs_value_r args); cs_int run_int(cs_bcode *code); - cs_int run_int(ostd::string_range code); + cs_int run_int(std::string_view code); cs_int run_int(cs_ident *id, cs_value_r args); cs_float run_float(cs_bcode *code); - cs_float run_float(ostd::string_range code); + cs_float run_float(std::string_view code); cs_float run_float(cs_ident *id, cs_value_r args); bool run_bool(cs_bcode *code); - bool run_bool(ostd::string_range code); + bool run_bool(std::string_view code); bool run_bool(cs_ident *id, cs_value_r args); void run(cs_bcode *code, cs_value &ret); - void run(ostd::string_range code, cs_value &ret); + void run(std::string_view code, cs_value &ret); void run(cs_ident *id, cs_value_r args, cs_value &ret); void run(cs_bcode *code); - void run(ostd::string_range code); + void run(std::string_view code); void run(cs_ident *id, cs_value_r args); cs_loop_state run_loop(cs_bcode *code, cs_value &ret); @@ -492,43 +492,43 @@ struct OSTD_EXPORT cs_state { return p_inloop; } - std::optional run_file_str(ostd::string_range fname); - std::optional run_file_int(ostd::string_range fname); - std::optional run_file_float(ostd::string_range fname); - std::optional run_file_bool(ostd::string_range fname); - bool run_file(ostd::string_range fname, cs_value &ret); - bool run_file(ostd::string_range fname); + std::optional run_file_str(std::string_view fname); + std::optional run_file_int(std::string_view fname); + std::optional run_file_float(std::string_view fname); + std::optional run_file_bool(std::string_view fname); + bool run_file(std::string_view fname, cs_value &ret); + bool run_file(std::string_view fname); - void set_alias(ostd::string_range name, cs_value v); + void set_alias(std::string_view name, cs_value v); void set_var_int( - ostd::string_range name, cs_int v, + std::string_view name, cs_int v, bool dofunc = true, bool doclamp = true ); void set_var_float( - ostd::string_range name, cs_float v, + std::string_view name, cs_float v, bool dofunc = true, bool doclamp = true ); void set_var_str( - ostd::string_range name, ostd::string_range v, bool dofunc = true + std::string_view name, std::string_view v, bool dofunc = true ); void set_var_int_checked(cs_ivar *iv, cs_int v); void set_var_int_checked(cs_ivar *iv, cs_value_r args); void set_var_float_checked(cs_fvar *fv, cs_float v); - void set_var_str_checked(cs_svar *fv, ostd::string_range v); + void set_var_str_checked(cs_svar *fv, std::string_view v); - std::optional get_var_int(ostd::string_range name); - std::optional get_var_float(ostd::string_range name); - std::optional get_var_str(ostd::string_range name); + std::optional get_var_int(std::string_view name); + std::optional get_var_float(std::string_view name); + std::optional get_var_str(std::string_view name); - std::optional get_var_min_int(ostd::string_range name); - std::optional get_var_max_int(ostd::string_range name); + std::optional get_var_min_int(std::string_view name); + std::optional get_var_max_int(std::string_view name); - std::optional get_var_min_float(ostd::string_range name); - std::optional get_var_max_float(ostd::string_range name); + std::optional get_var_min_float(std::string_view name); + std::optional get_var_max_float(std::string_view name); - std::optional get_alias_val(ostd::string_range name); + std::optional get_alias_val(std::string_view name); void print_var(cs_var const &v) const; @@ -582,7 +582,7 @@ struct cs_error { p_errmsg(v.p_errmsg), p_stack(std::move(v.p_stack)) {} - ostd::string_range what() const { + std::string_view what() const { return p_errmsg; } @@ -594,7 +594,7 @@ struct cs_error { return p_stack; } - cs_error(cs_state &cs, ostd::string_range msg): + cs_error(cs_state &cs, std::string_view msg): p_errmsg(), p_stack(cs) { p_errmsg = save_msg(cs, msg); @@ -602,7 +602,7 @@ struct cs_error { } template - cs_error(cs_state &cs, ostd::string_range msg, A &&...args): + cs_error(cs_state &cs, std::string_view msg, A &&...args): p_errmsg(), p_stack(cs) { try { @@ -620,9 +620,9 @@ struct cs_error { private: cs_stack_state save_stack(cs_state &cs); - ostd::string_range save_msg(cs_state &cs, ostd::string_range v); + std::string_view save_msg(cs_state &cs, std::string_view v); - ostd::string_range p_errmsg; + std::string_view p_errmsg; cs_stack_state p_stack; }; @@ -652,12 +652,23 @@ private: bool p_pushed; }; -struct cs_list_parse_state { - cs_list_parse_state(ostd::string_range s = ostd::string_range{}): input{s} {} +struct OSTD_EXPORT cs_list_parse_state { + cs_list_parse_state(std::string_view s = std::string_view{}): + input_beg{s.data()}, input_end{s.data() + s.size()} + {} - ostd::string_range input{}; - ostd::string_range item{}; - ostd::string_range quoted_item{}; + void set_input(std::string_view s) { + input_beg = s.data(); + input_end = s.data() + s.size(); + } + + std::string_view get_input() const { + return std::string_view{input_beg, std::size_t(input_end - input_beg)}; + } + + char const *input_beg, *input_end; + std::string_view item{}; + std::string_view quoted_item{}; }; OSTD_EXPORT bool list_parse(cs_list_parse_state &ps, cs_state &cs); @@ -666,16 +677,16 @@ OSTD_EXPORT cs_strref list_get_item(cs_list_parse_state &ps, cs_state &cs); OSTD_EXPORT void list_find_item(cs_list_parse_state &ps); OSTD_EXPORT cs_strref value_list_concat( - cs_state &cs, cs_value_r vals, ostd::string_range sep = ostd::string_range{} + cs_state &cs, cs_value_r vals, std::string_view sep = std::string_view{} ); namespace util { template - inline R &&escape_string(R &&writer, ostd::string_range str) { + inline R &&escape_string(R &&writer, std::string_view str) { using namespace ostd::string_literals; writer.put('"'); - for (; !str.empty(); str.pop_front()) { - switch (str.front()) { + for (auto c: str) { + switch (c) { case '\n': ostd::range_put_all(writer, "^n"_sr); break; @@ -692,7 +703,7 @@ namespace util { ostd::range_put_all(writer, "^^"_sr); break; default: - writer.put(str.front()); + writer.put(c); break; } } @@ -701,14 +712,14 @@ namespace util { } template - inline R &&unescape_string(R &&writer, ostd::string_range str) { - for (; !str.empty(); str.pop_front()) { - if (str.front() == '^') { - str.pop_front(); - if (str.empty()) { + inline R &&unescape_string(R &&writer, std::string_view str) { + for (auto it = str.begin(); it != str.end(); ++it) { + if (*it == '^') { + ++it; + if (it == str.end()) { break; } - switch (str.front()) { + switch (*it) { case 'n': writer.put('\n'); break; @@ -725,18 +736,20 @@ namespace util { writer.put('^'); break; default: - writer.put(str.front()); + writer.put(*it); break; } - } else if (str.front() == '\\') { - str.pop_front(); - if (str.empty()) { + } else if (*it == '\\') { + ++it; + if (it == str.end()) { break; } - char c = str.front(); + char c = *it; if ((c == '\r') || (c == '\n')) { - if (!str.empty() && (c == '\r') && (str.front() == '\n')) { - str.pop_front(); + if ((c == '\r') && ((it + 1) != str.end())) { + if (it[1] == '\n') { + ++it; + } } continue; } @@ -748,20 +761,18 @@ namespace util { return std::forward(writer); } - OSTD_EXPORT ostd::string_range parse_string( - cs_state &cs, ostd::string_range str, size_t &nlines + OSTD_EXPORT char const *parse_string( + cs_state &cs, std::string_view str, size_t &nlines ); - inline ostd::string_range parse_string( - cs_state &cs, ostd::string_range str + inline char const *parse_string( + cs_state &cs, std::string_view str ) { size_t nlines; return parse_string(cs, str, nlines); } - OSTD_EXPORT ostd::string_range parse_word( - cs_state &cs, ostd::string_range str - ); + OSTD_EXPORT char const *parse_word(cs_state &cs, std::string_view str); template inline void print_stack(R &&writer, cs_stack_state const &st) { diff --git a/src/cs_gen.cc b/src/cs_gen.cc index 6f549ed..df51c01 100644 --- a/src/cs_gen.cc +++ b/src/cs_gen.cc @@ -8,13 +8,15 @@ namespace cscript { -ostd::string_range cs_gen_state::get_str() { +std::string_view cs_gen_state::get_str() { size_t nl; - ostd::string_range beg = source; - source = util::parse_string(cs, source, nl); + char const *beg = source; + source = util::parse_string( + cs, std::string_view{source, std::size_t(send - source)}, nl + ); current_line += nl - 1; - ostd::string_range ret = beg.slice(0, &source[0] - &beg[0]); - return ret.slice(1, ret.size() - 1); + auto ret = std::string_view{beg, std::size_t(source - beg)}; + return ret.substr(1, ret.size() - 2); } cs_charbuf cs_gen_state::get_str_dup() { @@ -24,21 +26,21 @@ cs_charbuf cs_gen_state::get_str_dup() { return std::move(app.get()); } -ostd::string_range cs_gen_state::read_macro_name() { - auto op = source; +std::string_view cs_gen_state::read_macro_name() { + char const *op = source; char c = current(); if (!isalpha(c) && (c != '_')) { - return nullptr; + return std::string_view{}; } for (; isalnum(c) || (c == '_'); c = current()) { next_char(); } - return op.slice(0, &source[0] - &op[0]); + return std::string_view{op, std::size_t(source - op)}; } -char cs_gen_state::skip_until(ostd::string_range chars) { +char cs_gen_state::skip_until(std::string_view chars) { char c = current(); - while (c && ostd::find(chars, c).empty()) { + while (c && (chars.find(c) == std::string_view::npos)) { next_char(); c = current(); } @@ -88,10 +90,12 @@ void cs_gen_state::skip_comments() { } } -ostd::string_range cs_gen_state::get_word() { - auto beg = source; - source = util::parse_word(cs, source); - return beg.slice(0, &source[0] - &beg[0]); +std::string_view cs_gen_state::get_word() { + char const *beg = source; + source = util::parse_word( + cs, std::string_view{source, std::size_t(send - source)} + ); + return std::string_view{beg, std::size_t(source - beg)}; } static inline int cs_ret_code(int type, int def = 0) { @@ -104,20 +108,20 @@ static inline int cs_ret_code(int type, int def = 0) { static void compilestatements( cs_gen_state &gs, int rettype, int brak = '\0', int prevargs = 0 ); -static inline std::pair compileblock( - cs_gen_state &gs, ostd::string_range p, size_t line, +static inline std::pair compileblock( + cs_gen_state &gs, std::string_view p, size_t line, int rettype = CS_RET_NULL, int brak = '\0' ); -void cs_gen_state::gen_int(ostd::string_range word) { +void cs_gen_state::gen_int(std::string_view word) { gen_int(cs_parse_int(word)); } -void cs_gen_state::gen_float(ostd::string_range word) { +void cs_gen_state::gen_float(std::string_view word) { gen_float(cs_parse_float(word)); } -void cs_gen_state::gen_value(int wordtype, ostd::string_range word, int line) { +void cs_gen_state::gen_value(int wordtype, std::string_view word, int line) { switch (wordtype) { case CS_VAL_ANY: if (!word.empty()) { @@ -157,22 +161,24 @@ static inline void compileblock(cs_gen_state &gs) { gs.code.push_back(CS_CODE_EMPTY); } -static inline std::pair compileblock( - cs_gen_state &gs, ostd::string_range p, size_t line, int rettype, int brak +static inline std::pair compileblock( + cs_gen_state &gs, std::string_view p, size_t line, int rettype, int brak ) { size_t start = gs.code.size(); gs.code.push_back(CS_CODE_BLOCK); gs.code.push_back(CS_CODE_OFFSET | ((start + 2) << 8)); size_t retline = line; - if (p) { - ostd::string_range op = gs.source; + if (!p.empty()) { + char const *op = gs.source, *oe = gs.send; size_t oldline = gs.current_line; - gs.source = p; + gs.source = p.data(); + gs.send = p.data() + p.size(); gs.current_line = line; compilestatements(gs, CS_VAL_ANY, brak); - p = gs.source; + p = std::string_view{gs.source, std::size_t(gs.send - gs.source)}; retline = gs.current_line; gs.source = op; + gs.send = oe; gs.current_line = oldline; } if (gs.code.size() > start + 2) { @@ -323,7 +329,7 @@ lookupid: numargs++; break; case 's': - gs.gen_str(ostd::string_range()); + gs.gen_str(std::string_view{}); numargs++; break; case 'i': @@ -452,44 +458,44 @@ invalid: } } -static bool compileblockstr(cs_gen_state &gs, ostd::string_range str) { +static bool compileblockstr(cs_gen_state &gs, char const *str, char const *send) { int startc = gs.code.size(); gs.code.push_back(CS_CODE_VAL | CS_RET_STRING); - gs.code.reserve(gs.code.size() + str.size() / sizeof(uint32_t) + 1); - char *buf = new char[(str.size() / sizeof(uint32_t) + 1) * sizeof(uint32_t)]; + gs.code.reserve(gs.code.size() + (send - str) / sizeof(uint32_t) + 1); + char *buf = new char[((send - str) / sizeof(uint32_t) + 1) * sizeof(uint32_t)]; int len = 0; - while (!str.empty()) { - char const *p = str.data(); - str = ostd::find_one_of(str, ostd::string_range("\r/\"@]")); - memcpy(&buf[len], p, str.data() - p); - len += str.data() - p; - if (str.empty()) { + for (auto it = str; it != send; ++it) { + char const *p = it; + std::string_view chrs{"\r/\"@]"}; + it = std::find_first_of(it, send, chrs.begin(), chrs.end()); + memcpy(&buf[len], p, std::size_t(it - p)); + len += (it - p); + if (it == send) { goto done; } - switch (str.front()) { + switch (*it) { case '\r': - str.pop_front(); + ++it; break; case '\"': { - auto start = str; - str = util::parse_string(gs.cs, str); - auto strr = start.slice(0, &str[0] - &start[0]); - memcpy(&buf[len], strr.data(), strr.size()); - len += strr.size(); + char const *start = it; + it = util::parse_string( + gs.cs, std::string_view{it, std::size_t(send - it)} + ); + memcpy(&buf[len], start, std::size_t(it - start)); + len += (it - start); break; } case '/': - if (str[1] == '/') { - str = ostd::find(str, '\n'); + if (((it + 1) != send) && it[1] == '/') { + it = std::find(it, send, '\n'); } else { - buf[len++] = str.front(); - str.pop_front(); + buf[len++] = *it++; } break; case '@': case ']': - buf[len++] = str.front(); - str.pop_front(); + buf[len++] = *it++; break; } } @@ -561,7 +567,7 @@ done: } static void compileblockmain(cs_gen_state &gs, int wordtype, int prevargs) { - char const *start = gs.source.data(); + char const *start = gs.source; size_t curline = gs.current_line; int concs = 0; for (int brak = 1; brak;) { @@ -587,7 +593,7 @@ static void compileblockmain(cs_gen_state &gs, int wordtype, int prevargs) { brak--; break; case '@': { - char const *esc = gs.source.data(); + char const *esc = gs.source; int level = 0; while (gs.current() == '@') { ++level; @@ -606,14 +612,14 @@ static void compileblockmain(cs_gen_state &gs, int wordtype, int prevargs) { gs.code.push_back(CS_CODE_CONC_W | CS_RET_STRING | (concs << 8)); concs = 1; } - if (compileblockstr(gs, ostd::string_range(start, esc))) { + if (compileblockstr(gs, start, esc)) { concs++; } if (compileblocksub(gs, prevargs + concs)) { concs++; } if (concs) { - start = gs.source.data(); + start = gs.source; curline = gs.current_line; } else if (prevargs >= MaxResults) { gs.code.pop_back(); @@ -625,26 +631,29 @@ static void compileblockmain(cs_gen_state &gs, int wordtype, int prevargs) { break; } } - if (gs.source.data() - 1 > start) { + if (gs.source - 1 > start) { if (!concs) { switch (wordtype) { case CS_VAL_POP: return; case CS_VAL_CODE: case CS_VAL_COND: { - auto ret = compileblock(gs, ostd::string_range( - start, gs.source.data() + gs.source.size() - ), curline, CS_RET_NULL, ']'); - gs.source = ret.first; + auto ret = compileblock(gs, std::string_view{ + start, std::size_t(gs.send - start) + }, curline, CS_RET_NULL, ']'); + gs.source = ret.first.data(); + gs.send = ret.first.data() + ret.first.size(); gs.current_line = ret.second; return; } case CS_VAL_IDENT: - gs.gen_ident(ostd::string_range(start, gs.source.data() - 1)); + gs.gen_ident(std::string_view{ + start, std::size_t((gs.source - 1) - start) + }); return; } } - compileblockstr(gs, ostd::string_range(start, gs.source.data() - 1)); + compileblockstr(gs, start, gs.source - 1); if (concs > 1) { concs++; } @@ -659,26 +668,26 @@ static void compileblockmain(cs_gen_state &gs, int wordtype, int prevargs) { } switch (wordtype) { case CS_VAL_POP: - if (concs || gs.source.data() - 1 > start) { + if (concs || gs.source - 1 > start) { gs.code.push_back(CS_CODE_POP); } break; case CS_VAL_COND: - if (!concs && gs.source.data() - 1 <= start) { + if (!concs && gs.source - 1 <= start) { gs.gen_null(); } else { gs.code.push_back(CS_CODE_COND); } break; case CS_VAL_CODE: - if (!concs && gs.source.data() - 1 <= start) { + if (!concs && gs.source - 1 <= start) { compileblock(gs); } else { gs.code.push_back(CS_CODE_COMPILE); } break; case CS_VAL_IDENT: - if (!concs && gs.source.data() - 1 <= start) { + if (!concs && gs.source - 1 <= start) { gs.gen_ident(); } else { gs.code.push_back(CS_CODE_IDENT_U); @@ -688,13 +697,13 @@ static void compileblockmain(cs_gen_state &gs, int wordtype, int prevargs) { case CS_VAL_NULL: case CS_VAL_ANY: case CS_VAL_WORD: - if (!concs && gs.source.data() - 1 <= start) { + if (!concs && gs.source - 1 <= start) { gs.gen_str(); } break; default: if (!concs) { - if (gs.source.data() - 1 <= start) { + if (gs.source - 1 <= start) { gs.gen_value(wordtype); } else { gs.code.push_back(CS_CODE_FORCE | (wordtype << CS_CODE_RET)); @@ -837,8 +846,8 @@ static void compile_cmd( int comtype = CS_CODE_COM, numargs = 0, fakeargs = 0; bool rep = false; auto fmt = id->get_args(); - for (; !fmt.empty(); ++fmt) { - switch (*fmt) { + for (auto it = fmt.begin(); it != fmt.end(); ++it) { + switch (*it) { case 's': /* string */ if (more) { more = compilearg(gs, CS_VAL_STRING, prevargs + numargs); @@ -847,9 +856,9 @@ static void compile_cmd( if (rep) { break; } - gs.gen_str(ostd::string_range()); + gs.gen_str(std::string_view{}); fakeargs++; - } else if (fmt.size() == 1) { + } else if ((it + 1) == fmt.end()) { int numconc = 1; while ((numargs + numconc) < MaxArguments) { more = compilearg( @@ -1010,8 +1019,8 @@ static void compile_cmd( case '3': case '4': if (more && (numargs < MaxArguments)) { - int numrep = -int(*fmt) + '0' - 1; - fmt = ostd::string_range{&fmt[numrep], &fmt[fmt.size()]}; + int numrep = *it - '0' + 1; + it -= numrep; rep = true; } else { while (numargs > MaxArguments) { @@ -1298,7 +1307,7 @@ noid: } switch (rettype) { case CS_VAL_ANY: { - ostd::string_range end = idname.str_term(); + std::string_view end = idname.str_term(); cs_int val = cs_parse_int(end, &end); if (!end.empty()) { gs.gen_str(idname.str_term()); @@ -1441,8 +1450,9 @@ endstatement: } } -void cs_gen_state::gen_main(ostd::string_range s, int ret_type) { - source = s; +void cs_gen_state::gen_main(std::string_view s, int ret_type) { + source = s.data(); + send = s.data() + s.size(); code.push_back(CS_CODE_START); compilestatements(*this, CS_VAL_ANY); code.push_back(CS_CODE_EXIT | ((ret_type < CS_VAL_ANY) ? (ret_type << CS_CODE_RET) : 0)); diff --git a/src/cs_util.cc b/src/cs_util.cc index 637d1dc..f879916 100644 --- a/src/cs_util.cc +++ b/src/cs_util.cc @@ -7,19 +7,20 @@ namespace cscript { -static inline void p_skip_white(ostd::string_range &v) { - while (!v.empty() && isspace(*v)) { - ++v; +static inline char const *p_skip_white(char const *beg, char const *end) { + while ((beg != end) && isspace(*beg)) { + ++beg; } + return beg; } static inline void p_set_end( - const ostd::string_range &v, ostd::string_range *end + char const *nbeg, char const *nend, std::string_view *end ) { if (!end) { return; } - *end = v; + *end = std::string_view{nbeg, std::size_t(nend - nbeg)}; } /* this function assumes the input is definitely a hex digit */ @@ -33,7 +34,7 @@ static inline cs_int p_hexd_to_int(char c) { return c - '0'; } -static inline bool p_check_neg(ostd::string_range &input) { +static inline bool p_check_neg(char const *&input) { bool neg = (*input == '-'); if (neg || (*input == '+')) { ++input; @@ -41,46 +42,41 @@ static inline bool p_check_neg(ostd::string_range &input) { return neg; } -cs_int cs_parse_int(ostd::string_range input, ostd::string_range *end) { - ostd::string_range orig = input; - p_skip_white(input); - if (input.empty()) { - p_set_end(orig, end); +cs_int cs_parse_int(std::string_view input, std::string_view *endstr) { + char const *beg = input.begin(); + char const *end = input.end(); + char const *orig = beg; + beg = p_skip_white(beg, end); + if (beg == end) { + p_set_end(orig, end, endstr); return cs_int(0); } - bool neg = p_check_neg(input); + bool neg = p_check_neg(beg); cs_int ret = 0; - ostd::string_range past = input; - if (input.size() >= 2) { - ostd::string_range pfx = input.slice(0, 2); + char const *past = beg; + if ((end - beg) >= 2) { + std::string_view pfx = std::string_view{beg, 2}; if ((pfx == "0x") || (pfx == "0X")) { - input = input.slice(2, input.size()); - past = input; - while (!past.empty() && isxdigit(*past)) { - ret = ret * 16 + p_hexd_to_int(*past); - ++past; + beg += 2; + past = beg; + while ((past != end) && isxdigit(*past)) { + ret = ret * 16 + p_hexd_to_int(*past++); } goto done; } else if ((pfx == "0b") || (pfx == "0B")) { - input = input.slice(2, input.size()); - past = input; - while (!past.empty() && ((*past == '0') || (*past == '1'))) { - ret = ret * 2 + (*past - '0'); - ++past; + beg += 2; + past = beg; + while ((past != end) && ((*past == '0') || (*past == '1'))) { + ret = ret * 2 + (*past++ - '0'); } goto done; } } - while (!past.empty() && isdigit(*past)) { - ret = ret * 10 + (*past - '0'); - ++past; + while ((past != end) && isdigit(*past)) { + ret = ret * 10 + (*past++ - '0'); } done: - if (&past[0] == &input[0]) { - p_set_end(orig, end); - } else { - p_set_end(past, end); - } + p_set_end((past == beg) ? orig : past, end, endstr); if (neg) { return -ret; } @@ -88,25 +84,23 @@ done: } template -static inline bool p_read_exp(ostd::string_range &input, cs_int &fn) { - if (input.empty()) { +static inline bool p_read_exp(char const *&beg, char const *end, cs_int &fn) { + if (beg == end) { return true; } - if ((*input != e1) && (*input != e2)) { + if ((*beg != e1) && (*beg != e2)) { return true; } - ++input; - if (input.empty()) { + if (++beg == end) { return false; } - bool neg = p_check_neg(input); - if (input.empty() || !isdigit(*input)) { + bool neg = p_check_neg(beg); + if ((beg == end) || !isdigit(*beg)) { return false; } cs_int exp = 0; - while (!input.empty() && isdigit(*input)) { - exp = exp * 10 + (*input - '0'); - ++input; + while ((beg != end) && isdigit(*beg)) { + exp = exp * 10 + (*beg++ - '0'); } if (neg) { exp = -exp; @@ -117,33 +111,33 @@ static inline bool p_read_exp(ostd::string_range &input, cs_int &fn) { template static inline bool parse_gen_float( - ostd::string_range input, ostd::string_range *end, cs_float &ret + char const *&beg, char const *end, std::string_view *endstr, cs_float &ret ) { - auto read_digits = [&input](double r, cs_int &n) { - while (!input.empty() && (Hex ? isxdigit(*input) : isdigit(*input))) { + auto read_digits = [&beg, end](double r, cs_int &n) { + while ((beg != end) && (Hex ? isxdigit(*beg) : isdigit(*beg))) { if (Hex) { - r = r * 16.0 + double(p_hexd_to_int(*input)); + r = r * 16.0 + double(p_hexd_to_int(*beg)); } else { - r = r * 10.0 + double(*input - '0'); + r = r * 10.0 + double(*beg - '0'); } ++n; - ++input; + ++beg; } return r; }; cs_int wn = 0, fn = 0; double r = read_digits(0.0, wn); - if (!input.empty() && (*input == '.')) { - ++input; + if ((beg != end) && (*beg == '.')) { + ++beg; r = read_digits(r, fn); } if (!wn && !fn) { return false; } fn = -fn; - p_set_end(input, end); /* we have a valid number until here */ - if (p_read_exp(input, fn)) { - p_set_end(input, end); + p_set_end(beg, end, endstr); /* we have a valid number until here */ + if (p_read_exp(beg, end, fn)) { + p_set_end(beg, end, endstr); } if (Hex) { ret = cs_float(ldexp(r, fn * 4)); @@ -153,28 +147,30 @@ static inline bool parse_gen_float( return true; } -cs_float cs_parse_float(ostd::string_range input, ostd::string_range *end) { - ostd::string_range orig = input; - p_skip_white(input); - if (input.empty()) { - p_set_end(orig, end); +cs_float cs_parse_float(std::string_view input, std::string_view *endstr) { + char const *beg = input.begin(); + char const *end = input.end(); + char const *orig = beg; + beg = p_skip_white(beg, end); + if (beg == end) { + p_set_end(orig, end, endstr); return cs_float(0); } - bool neg = p_check_neg(input); + bool neg = p_check_neg(beg); cs_float ret = cs_float(0); - if (input.size() >= 2) { - ostd::string_range pfx = input.slice(0, 2); + if ((end - beg) >= 2) { + std::string_view pfx = std::string_view{beg, 2}; if ((pfx == "0x") || (pfx == "0X")) { - input = input.slice(2, input.size()); - if (!parse_gen_float(input, end, ret)) { - p_set_end(orig, end); + beg += 2; + if (!parse_gen_float(beg, end, endstr, ret)) { + p_set_end(orig, end, endstr); return ret; } goto done; } } - if (!parse_gen_float(input, end, ret)) { - p_set_end(orig, end); + if (!parse_gen_float(beg, end, endstr, ret)) { + p_set_end(orig, end, endstr); return ret; } done: @@ -192,7 +188,7 @@ inline cs_strref_state *get_ref_state(char const *ptr) { ) - 1; } -char const *cs_strman::add(ostd::string_range str) { +char const *cs_strman::add(std::string_view str) { auto it = counts.find(str); /* already present: just increment ref */ if (it != counts.end()) { @@ -209,7 +205,7 @@ char const *cs_strman::add(ostd::string_range str) { /* write string data, it's already pre-terminated */ memcpy(strp, str.data(), ss); /* store it */ - counts.emplace(ostd::string_range{strp, strp + ss}, get_ref_state(strp)); + counts.emplace(std::string_view{strp, ss}, get_ref_state(strp)); return strp; } @@ -221,7 +217,7 @@ char const *cs_strman::ref(char const *ptr) { char const *cs_strman::steal(char *ptr) { auto *ss = get_ref_state(ptr); - auto sr = ostd::string_range{ptr, ptr + ss->length}; + auto sr = std::string_view{ptr, ss->length}; /* much like add(), but we already have memory */ auto it = counts.find(sr); if (it != counts.end()) { @@ -244,7 +240,7 @@ void cs_strman::unref(char const *ptr) { /* refcount zero, so ditch it * this path is a little slow... */ - auto sr = ostd::string_range{ptr, ptr + ss->length}; + auto sr = std::string_view{ptr, ss->length}; auto it = counts.find(sr); if (it == counts.end()) { /* internal error: this should *never* happen */ @@ -257,7 +253,7 @@ void cs_strman::unref(char const *ptr) { } } -char const *cs_strman::find(ostd::string_range str) const { +char const *cs_strman::find(std::string_view str) const { auto it = counts.find(str); if (it == counts.end()) { return nullptr; @@ -265,9 +261,9 @@ char const *cs_strman::find(ostd::string_range str) const { return reinterpret_cast(it->second + 1); } -ostd::string_range cs_strman::get(char const *ptr) const { +std::string_view cs_strman::get(char const *ptr) const { auto *ss = get_ref_state(ptr); - return ostd::string_range{ptr, ptr + ss->length}; + return std::string_view{ptr, ss->length}; } char *cs_strman::alloc_buf(std::size_t len) const { @@ -288,13 +284,13 @@ char *cs_strman::alloc_buf(std::size_t len) const { /* strref */ -cs_strref::cs_strref(cs_shared_state &cs, ostd::string_range str): +cs_strref::cs_strref(cs_shared_state &cs, std::string_view str): p_state{&cs} { p_str = cs.strman->add(str); } -cs_strref::cs_strref(cs_state &cs, ostd::string_range str): +cs_strref::cs_strref(cs_state &cs, std::string_view str): p_state{cs.p_state} { p_str = p_state->strman->add(str); @@ -323,7 +319,7 @@ cs_strref &cs_strref::operator=(cs_strref const &ref) { return *this; } -cs_strref::operator ostd::string_range() const { +cs_strref::operator std::string_view() const { return p_state->strman->get(p_str); } @@ -332,140 +328,151 @@ bool cs_strref::operator==(cs_strref const &s) const { } namespace util { - OSTD_EXPORT ostd::string_range parse_string( - cs_state &cs, ostd::string_range str, size_t &nlines + OSTD_EXPORT char const *parse_string( + cs_state &cs, std::string_view str, size_t &nlines ) { size_t nl = 0; nlines = nl; - if (str.empty() || (*str != '\"')) { - return str; + if (str.empty() || (str.front() != '\"')) { + return str.data(); } - ostd::string_range orig = str; - ++str; + char const *beg = str.begin(); + char const *end = str.end(); + char const *orig = beg++; ++nl; - while (!str.empty()) { - switch (*str) { + while (beg != end) { + switch (*beg) { case '\r': case '\n': case '\"': goto end; case '^': case '\\': { - bool needn = (*str == '\\'); - ++str; - if (str.empty()) { + bool needn = (*beg == '\\'); + if (++beg == end) { goto end; } - if ((*str == '\r') || (*str == '\n')) { - char c = *str; - ++str; + if ((*beg == '\r') || (*beg == '\n')) { + char c = *beg++; ++nl; - if (!str.empty() && (c == '\r') && (*str == '\n')) { - ++str; + if ((beg != end) && (c == '\r') && (*beg == '\n')) { + ++beg; } } else if (needn) { goto end; } else { - ++str; + ++beg; } continue; } + default: + break; } - ++str; + ++beg; } end: nlines = nl; - if (str.empty() || (*str != '\"')) { + if ((beg == end) || (*beg != '\"')) { throw cs_error( - cs, "unfinished string '%s'", orig.slice(0, &str[0] - &orig[0]) + cs, "unfinished string '%s'", + std::string_view{orig, std::size_t(beg - orig)} ); } - str.pop_front(); - return str; + return ++beg; } - OSTD_EXPORT ostd::string_range parse_word( - cs_state &cs, ostd::string_range str - ) { - for (;;) { - str = ostd::find_one_of(str, ostd::string_range("\"/;()[] \t\r\n")); - if (str.empty()) { - return str; + OSTD_EXPORT char const *parse_word(cs_state &cs, std::string_view str) { + char const *it = str.begin(); + char const *end = str.end(); + for (; it != end; ++it) { + std::string_view chrs{"\"/;()[] \t\r\n"}; + it = std::find_first_of(it, end, chrs.begin(), chrs.end()); + if (it == end) { + return it; } - switch (*str) { + switch (*it) { case '"': case ';': case ' ': case '\t': case '\r': case '\n': - return str; + return it; case '/': - if ((str.size() > 1) && (str[1] == '/')) { - return str; + if (((end - it) > 1) && (it[1] == '/')) { + return it; } break; case '[': - str.pop_front(); - str = parse_word(cs, str); - if (str.empty() || (*str != ']')) { + ++it; + it = parse_word(cs, std::string_view{ + it, std::size_t(end - it) + }); + if ((it == end) || (*it != ']')) { throw cs_error(cs, "missing \"]\""); } break; case '(': - str.pop_front(); - str = parse_word(cs, str); - if (str.empty() || (*str != ')')) { + ++it; + it = parse_word(cs, std::string_view{ + it, std::size_t(end - it) + }); + if ((it == end) || (*it != ')')) { throw cs_error(cs, "missing \")\""); } break; case ']': case ')': - return str; + return it; } - ++str; } - return str; + return it; } } /* namespace util */ OSTD_EXPORT bool list_parse(cs_list_parse_state &ps, cs_state &cs) { list_find_item(ps); - if (ps.input.empty()) { + if (ps.input_beg == ps.input_end) { return false; } - switch (*ps.input) { - case '"': - ps.quoted_item = ps.input; - ps.input = util::parse_string(cs, ps.input); - ps.quoted_item = ps.quoted_item.slice( - 0, &ps.input[0] - &ps.quoted_item[0] - ); - ps.item = ps.quoted_item.slice(1, ps.quoted_item.size() - 1); + switch (*ps.input_beg) { + case '"': { + char const *qi = ps.input_beg; + ps.input_beg = util::parse_string(cs, ps.get_input()); + ps.quoted_item = std::string_view{ + qi, std::size_t(ps.input_beg - qi) + }; + ps.item = ps.quoted_item.substr(1, ps.quoted_item.size() - 2); break; + } case '(': case '[': { - ps.quoted_item = ps.input; - ++ps.input; - ps.item = ps.input; - char btype = *ps.quoted_item; + char btype = *ps.input_beg; int brak = 1; + char const *ibeg = ps.input_beg++; for (;;) { - ps.input = ostd::find_one_of( - ps.input, ostd::string_range("\"/;()[]") + std::string_view chrs{"\"/;()[]"}; + ps.input_beg = std::find_first_of( + ps.input_beg, ps.input_end, chrs.begin(), chrs.end() ); - if (ps.input.empty()) { + if (ps.input_beg == ps.input_end) { return true; } - char c = *ps.input; - ++ps.input; + char c = *ps.input_beg++; switch (c) { case '"': - ps.input = util::parse_string(cs, ps.input); + /* the quote is needed in str parsing */ + --ps.input_beg; + ps.input_beg = util::parse_string(cs, ps.get_input()); break; case '/': - if (!ps.input.empty() && (*ps.input == '/')) { - ps.input = ostd::find(ps.input, '\n'); + if ( + (ps.input_beg != ps.input_end) && + (*ps.input_beg == '/') + ) { + ps.input_beg = std::find( + ps.input_beg, ps.input_end, '\n' + ); } break; case '(': @@ -485,26 +492,29 @@ OSTD_EXPORT bool list_parse(cs_list_parse_state &ps, cs_state &cs) { } } endblock: - ps.item = ps.item.slice(0, &ps.input[0] - &ps.item[0]); - ps.item.pop_back(); - ps.quoted_item = ps.quoted_item.slice( - 0, &ps.input[0] - &ps.quoted_item[0] - ); + ps.item = std::string_view{ + ibeg + 1, std::size_t(ps.input_beg - ibeg - 2) + }; + ps.quoted_item = std::string_view{ + ibeg, std::size_t(ps.input_beg - ibeg) + }; break; } case ')': case ']': return false; default: { - ostd::string_range e = util::parse_word(cs, ps.input); - ps.quoted_item = ps.item = ps.input.slice(0, &e[0] - &ps.input[0]); - ps.input = e; + char const *e = util::parse_word(cs, ps.get_input()); + ps.quoted_item = ps.item = std::string_view{ + ps.input_beg, std::size_t(e - ps.input_beg) + }; + ps.input_beg = e; break; } } list_find_item(ps); - if (!ps.input.empty() && (*ps.input == ';')) { - ++ps.input; + if ((ps.input_beg != ps.input_end) && (*ps.input_beg == ';')) { + ++ps.input_beg; } return true; } @@ -518,7 +528,7 @@ OSTD_EXPORT std::size_t list_count(cs_list_parse_state &ps, cs_state &cs) { } OSTD_EXPORT cs_strref list_get_item(cs_list_parse_state &ps, cs_state &cs) { - if (!ps.quoted_item.empty() && (*ps.quoted_item == '"')) { + if (!ps.quoted_item.empty() && (ps.quoted_item.front() == '"')) { auto app = ostd::appender(cs); util::unescape_string(app, ps.item); return cs_strref{cs, app.get().str()}; @@ -528,23 +538,26 @@ OSTD_EXPORT cs_strref list_get_item(cs_list_parse_state &ps, cs_state &cs) { OSTD_EXPORT void list_find_item(cs_list_parse_state &ps) { for (;;) { - while (!ps.input.empty()) { - char c = *ps.input; + while (ps.input_beg != ps.input_end) { + char c = *ps.input_beg; if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')) { - ++ps.input; + ++ps.input_beg; } else { break; } } - if ((ps.input.size() < 2) || (ps.input[0] != '/') || (ps.input[1] != '/')) { + if ((ps.input_end - ps.input_beg) < 2) { break; } - ps.input = ostd::find(ps.input, '\n'); + if ((ps.input_beg[0] != '/') || (ps.input_beg[1]) != '/') { + break; + } + ps.input_beg = std::find(ps.input_beg, ps.input_end, '\n'); } } OSTD_EXPORT cs_strref value_list_concat( - cs_state &cs, cs_value_r vals, ostd::string_range sep + cs_state &cs, cs_value_r vals, std::string_view sep ) { auto app = ostd::appender(cs); for (std::size_t i = 0; i < vals.size(); ++i) { @@ -553,7 +566,9 @@ OSTD_EXPORT cs_strref value_list_concat( case cs_value_type::FLOAT: case cs_value_type::STRING: { cs_value v{vals[i]}; - ostd::range_put_all(app, cs_value{vals[i]}.force_str()); + for (auto c: v.force_str()) { + app.put(c); + } break; } default: @@ -562,7 +577,9 @@ OSTD_EXPORT cs_strref value_list_concat( if (i == (vals.size() - 1)) { break; } - ostd::range_put_all(app, sep); + for (auto c: sep) { + app.put(c); + } } return cs_strref{cs, app.get().str()}; } diff --git a/src/cs_util.hh b/src/cs_util.hh index a21b2aa..ae54ed5 100644 --- a/src/cs_util.hh +++ b/src/cs_util.hh @@ -10,11 +10,11 @@ namespace cscript { cs_int cs_parse_int( - ostd::string_range input, ostd::string_range *end = nullptr + std::string_view input, std::string_view *end = nullptr ); cs_float cs_parse_float( - ostd::string_range input, ostd::string_range *end = nullptr + std::string_view input, std::string_view *end = nullptr ); template @@ -111,30 +111,30 @@ struct cs_charbuf: cs_valbuf { cs_valbuf::append(beg, end); } - void append(ostd::string_range v) { + void append(std::string_view v) { append(&v[0], &v[v.size()]); } - ostd::string_range str() { - return ostd::string_range{buf.data(), buf.data() + buf.size()}; + std::string_view str() { + return std::string_view{buf.data(), buf.size()}; } - ostd::string_range str_term() { - return ostd::string_range{buf.data(), buf.data() + buf.size() - 1}; + std::string_view str_term() { + return std::string_view{buf.data(), buf.size() - 1}; } }; struct cs_shared_state { using allocator_type = cs_allocator< - std::pair + std::pair >; cs_alloc_cb allocf; void *aptr; std::unordered_map< - ostd::string_range, cs_ident *, - std::hash, - std::equal_to, + std::string_view, cs_ident *, + std::hash, + std::equal_to, allocator_type > idents; std::vector> identmap; @@ -226,7 +226,7 @@ struct cs_strref_state { struct cs_strman { using allocator_type = cs_allocator< - std::pair + std::pair >; cs_strman() = delete; cs_strman(cs_shared_state *cs): cstate{cs}, counts{allocator_type{cs}} {} @@ -242,7 +242,7 @@ struct cs_strman { * version; this is "slow" as it has to hash the string and potentially * allocate fresh memory for it, but is perfectly safe at any time */ - char const *add(ostd::string_range str); + char const *add(std::string_view str); /* this simply increments the reference count of an existing managed * string, this is only safe when you know the pointer you are passing @@ -263,10 +263,10 @@ struct cs_strman { /* just finds a managed pointer with the same contents * as the input, if not found then a null pointer is returned */ - char const *find(ostd::string_range str) const; + char const *find(std::string_view str) const; /* a quick helper to make a proper ostd string range out of a ptr */ - ostd::string_range get(char const *ptr) const; + std::string_view get(char const *ptr) const; /* this will allocate a buffer of the given length (plus one for * terminating zero) so you can fill it; use steal() to write it @@ -275,9 +275,9 @@ struct cs_strman { cs_shared_state *cstate; std::unordered_map< - ostd::string_range, cs_strref_state *, - std::hash, - std::equal_to, + std::string_view, cs_strref_state *, + std::hash, + std::equal_to, allocator_type > counts; }; diff --git a/src/cs_val.cc b/src/cs_val.cc index 71912ab..b4d3884 100644 --- a/src/cs_val.cc +++ b/src/cs_val.cc @@ -113,7 +113,7 @@ void cs_value::set_float(cs_float val) { csv_get(p_stor) = val; } -void cs_value::set_str(ostd::string_range val) { +void cs_value::set_str(std::string_view val) { csv_cleanup(p_type, p_stor); new (&p_stor) cs_strref{*state(), val}; p_type = cs_value_type::STRING; @@ -156,9 +156,9 @@ cs_float cs_value::force_float() { rf = csv_get(p_stor); break; case cs_value_type::STRING: - rf = cs_parse_float(ostd::string_range( + rf = cs_parse_float( *reinterpret_cast(&p_stor) - )); + ); break; case cs_value_type::FLOAT: return csv_get(p_stor); @@ -176,9 +176,9 @@ cs_int cs_value::force_int() { ri = csv_get(p_stor); break; case cs_value_type::STRING: - ri = cs_parse_int(ostd::string_range( + ri = cs_parse_int( *reinterpret_cast(&p_stor) - )); + ); break; case cs_value_type::INT: return csv_get(p_stor); @@ -189,7 +189,7 @@ cs_int cs_value::force_int() { return ri; } -ostd::string_range cs_value::force_str() { +std::string_view cs_value::force_str() { cs_charbuf rs{*state()}; switch (get_type()) { case cs_value_type::FLOAT: @@ -199,14 +199,12 @@ ostd::string_range cs_value::force_str() { rs = std::move(intstr(csv_get(p_stor), *state())); break; case cs_value_type::STRING: - return ostd::string_range( - *reinterpret_cast(&p_stor) - ); + return *reinterpret_cast(&p_stor); default: break; } set_str(rs.str()); - return ostd::string_range(*reinterpret_cast(&p_stor)); + return std::string_view(*reinterpret_cast(&p_stor)); } cs_int cs_value::get_int() const { @@ -216,9 +214,9 @@ cs_int cs_value::get_int() const { case cs_value_type::INT: return csv_get(p_stor); case cs_value_type::STRING: - return cs_parse_int(ostd::string_range( + return cs_parse_int( *reinterpret_cast(&p_stor) - )); + ); default: break; } @@ -232,9 +230,9 @@ cs_float cs_value::get_float() const { case cs_value_type::INT: return cs_float(csv_get(p_stor)); case cs_value_type::STRING: - return cs_parse_float(ostd::string_range( + return cs_parse_float( *reinterpret_cast(&p_stor) - )); + ); default: break; } @@ -306,11 +304,11 @@ bool cs_value::code_is_empty() const { return cscript::cs_code_is_empty(csv_get(p_stor)); } -static inline bool cs_get_bool(ostd::string_range s) { +static inline bool cs_get_bool(std::string_view s) { if (s.empty()) { return false; } - ostd::string_range end = s; + std::string_view end = s; cs_int ival = cs_parse_int(end, &end); if (end.empty()) { return !!ival; @@ -330,9 +328,9 @@ bool cs_value::get_bool() const { case cs_value_type::INT: return csv_get(p_stor) != 0; case cs_value_type::STRING: - return cs_get_bool(ostd::string_range( + return cs_get_bool( *reinterpret_cast(&p_stor) - )); + ); default: return false; } diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 493baa2..a72ba27 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -107,11 +107,11 @@ cs_stack_state cs_error::save_stack(cs_state &cs) { return cs_stack_state(cs, ret, total > dalias->get_value()); } -ostd::string_range cs_error::save_msg( - cs_state &cs, ostd::string_range msg +std::string_view cs_error::save_msg( + cs_state &cs, std::string_view msg ) { if (msg.size() > sizeof(cs.p_errbuf)) { - msg = msg.slice(0, sizeof(cs.p_errbuf)); + msg = msg.substr(0, sizeof(cs.p_errbuf)); } cs_gen_state *gs = cs.p_pstate; if (gs) { @@ -133,10 +133,10 @@ ostd::string_range cs_error::save_msg( memcpy(cs.p_errbuf, msg.data(), msg.size()); sz = msg.size(); } - return ostd::string_range(cs.p_errbuf, cs.p_errbuf + sz); + return std::string_view{cs.p_errbuf, sz}; } memcpy(cs.p_errbuf, msg.data(), msg.size()); - return ostd::string_range(cs.p_errbuf, cs.p_errbuf + msg.size()); + return std::string_view{cs.p_errbuf, msg.size()}; } static void bcode_ref(uint32_t *code) { @@ -220,7 +220,7 @@ static inline uint32_t *forcecode(cs_state &cs, cs_value &v) { static inline void forcecond(cs_state &cs, cs_value &v) { switch (v.get_type()) { case cs_value_type::STRING: - if (!ostd::string_range{v.get_str()}.empty()) { + if (!std::string_view{v.get_str()}.empty()) { forcecode(cs, v); } else { v.set_int(0); @@ -310,8 +310,9 @@ static inline void callcommand( ) { int i = -1, fakeargs = 0; bool rep = false; - for (auto fmt = id->get_args(); !fmt.empty(); ++fmt) { - switch (*fmt) { + auto fmt = id->get_args(); + for (auto it = fmt.begin(); it != fmt.end(); ++it) { + switch (*it) { case 'i': if (++i >= numargs) { if (rep) { @@ -436,9 +437,7 @@ static inline void callcommand( case '3': case '4': if (i + 1 < numargs) { - fmt = ostd::string_range{ - &fmt[-int(*fmt) + '0' - 1], &fmt[fmt.size()] - }; + it -= *it - '0' + 1; rep = true; } break; @@ -758,9 +757,8 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) { case CS_CODE_VAL | CS_RET_STRING: { uint32_t len = op >> 8; - args[numargs++].set_str(ostd::string_range{ - reinterpret_cast(code), - reinterpret_cast(code) + len + args[numargs++].set_str(std::string_view{ + reinterpret_cast(code), len }); code += len / sizeof(uint32_t) + 1; continue; @@ -906,7 +904,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) { cs_value &arg = args[numargs - 1]; switch (arg.get_type()) { case cs_value_type::STRING: { - ostd::string_range s = arg.get_str(); + std::string_view s = arg.get_str(); if (!s.empty()) { cs_gen_state gs(cs); gs.code.reserve(64); @@ -1461,7 +1459,7 @@ noid: result.force_none(); force_arg(result, op & CS_CODE_RET_MASK); throw cs_error( - cs, "unknown command: %s", ostd::string_range{idn} + cs, "unknown command: %s", std::string_view{idn} ); } result.force_none(); @@ -1564,7 +1562,7 @@ void cs_state::run(cs_bcode *code, cs_value &ret) { } static void cs_run( - cs_state &cs, ostd::string_range file, ostd::string_range code, + cs_state &cs, std::string_view file, std::string_view code, cs_value &ret ) { cs_gen_state gs(cs); @@ -1580,8 +1578,8 @@ static void cs_run( } } -void cs_state::run(ostd::string_range code, cs_value &ret) { - cs_run(*this, ostd::string_range(), code, ret); +void cs_state::run(std::string_view code, cs_value &ret) { + cs_run(*this, std::string_view{}, code, ret); } void cs_state::run(cs_ident *id, cs_value_r args, cs_value &ret) { @@ -1663,7 +1661,7 @@ cs_strref cs_state::run_str(cs_bcode *code) { return ret.get_str(); } -cs_strref cs_state::run_str(ostd::string_range code) { +cs_strref cs_state::run_str(std::string_view code) { cs_value ret{*this}; run(code, ret); return ret.get_str(); @@ -1681,7 +1679,7 @@ cs_int cs_state::run_int(cs_bcode *code) { return ret.get_int(); } -cs_int cs_state::run_int(ostd::string_range code) { +cs_int cs_state::run_int(std::string_view code) { cs_value ret{*this}; run(code, ret); return ret.get_int(); @@ -1699,7 +1697,7 @@ cs_float cs_state::run_float(cs_bcode *code) { return ret.get_float(); } -cs_float cs_state::run_float(ostd::string_range code) { +cs_float cs_state::run_float(std::string_view code) { cs_value ret{*this}; run(code, ret); return ret.get_float(); @@ -1717,7 +1715,7 @@ bool cs_state::run_bool(cs_bcode *code) { return ret.get_bool(); } -bool cs_state::run_bool(ostd::string_range code) { +bool cs_state::run_bool(std::string_view code) { cs_value ret{*this}; run(code, ret); return ret.get_bool(); @@ -1734,7 +1732,7 @@ void cs_state::run(cs_bcode *code) { run(code, ret); } -void cs_state::run(ostd::string_range code) { +void cs_state::run(std::string_view code) { cs_value ret{*this}; run(code, ret); } @@ -1767,7 +1765,7 @@ cs_loop_state cs_state::run_loop(cs_bcode *code) { } static bool cs_run_file( - cs_state &cs, ostd::string_range fname, cs_value &ret + cs_state &cs, std::string_view fname, cs_value &ret ) { std::unique_ptr buf; size_t len; @@ -1789,11 +1787,11 @@ static bool cs_run_file( } buf[len] = '\0'; - cs_run(cs, fname, ostd::string_range(buf.get(), buf.get() + len), ret); + cs_run(cs, fname, std::string_view{buf.get(), len}, ret); return true; } -std::optional cs_state::run_file_str(ostd::string_range fname) { +std::optional cs_state::run_file_str(std::string_view fname) { cs_value ret{*this}; if (!cs_run_file(*this, fname, ret)) { return std::nullopt; @@ -1801,7 +1799,7 @@ std::optional cs_state::run_file_str(ostd::string_range fname) { return ret.get_str(); } -std::optional cs_state::run_file_int(ostd::string_range fname) { +std::optional cs_state::run_file_int(std::string_view fname) { cs_value ret{*this}; if (!cs_run_file(*this, fname, ret)) { return std::nullopt; @@ -1809,7 +1807,7 @@ std::optional cs_state::run_file_int(ostd::string_range fname) { return ret.get_int(); } -std::optional cs_state::run_file_float(ostd::string_range fname) { +std::optional cs_state::run_file_float(std::string_view fname) { cs_value ret{*this}; if (!cs_run_file(*this, fname, ret)) { return std::nullopt; @@ -1817,7 +1815,7 @@ std::optional cs_state::run_file_float(ostd::string_range fname) { return ret.get_float(); } -std::optional cs_state::run_file_bool(ostd::string_range fname) { +std::optional cs_state::run_file_bool(std::string_view fname) { cs_value ret{*this}; if (!cs_run_file(*this, fname, ret)) { return std::nullopt; @@ -1825,11 +1823,11 @@ std::optional cs_state::run_file_bool(ostd::string_range fname) { return ret.get_bool(); } -bool cs_state::run_file(ostd::string_range fname, cs_value &ret) { +bool cs_state::run_file(std::string_view fname, cs_value &ret) { return cs_run_file(*this, fname, ret); } -bool cs_state::run_file(ostd::string_range fname) { +bool cs_state::run_file(std::string_view fname) { cs_value ret{*this}; if (!cs_run_file(*this, fname, ret)) { return false; diff --git a/src/cs_vm.hh b/src/cs_vm.hh index 1722b49..8b966c7 100644 --- a/src/cs_vm.hh +++ b/src/cs_vm.hh @@ -129,14 +129,14 @@ struct cs_gen_state { cs_gen_state *prevps; bool parsing = true; cs_valbuf code; - ostd::string_range source; + char const *source, *send; size_t current_line; - ostd::string_range src_name; + std::string_view src_name; cs_gen_state() = delete; cs_gen_state(cs_state &csr): - cs(csr), prevps(csr.p_pstate), code{cs}, - source(nullptr), current_line(1), src_name() + cs{csr}, prevps{csr.p_pstate}, code{cs}, + source{}, send{}, current_line{1}, src_name{} { csr.p_pstate = this; } @@ -153,12 +153,12 @@ struct cs_gen_state { parsing = false; } - ostd::string_range get_str(); + std::string_view get_str(); cs_charbuf get_str_dup(); - ostd::string_range get_word(); + std::string_view get_word(); - void gen_str(ostd::string_range word) { + void gen_str(std::string_view word) { if (word.size() <= 3) { uint32_t op = CS_CODE_VAL_INT | CS_RET_STRING; for (size_t i = 0; i < word.size(); ++i) { @@ -204,7 +204,7 @@ struct cs_gen_state { } } - void gen_int(ostd::string_range word); + void gen_int(std::string_view word); void gen_float(cs_float f = 0.0f) { if (cs_int(f) == f && f >= -0x800000 && f <= 0x7FFFFF) { @@ -220,7 +220,7 @@ struct cs_gen_state { } } - void gen_float(ostd::string_range word); + void gen_float(std::string_view word); void gen_ident(cs_ident *id) { code.push_back( @@ -235,43 +235,43 @@ struct cs_gen_state { gen_ident(cs.p_state->identmap[DummyIdx]); } - void gen_ident(ostd::string_range word) { + void gen_ident(std::string_view word) { gen_ident(cs.new_ident(word)); } void gen_value( - int wordtype, ostd::string_range word = ostd::string_range(), + int wordtype, std::string_view word = std::string_view(), int line = 0 ); - void gen_main(ostd::string_range s, int ret_type = CS_VAL_ANY); + void gen_main(std::string_view s, int ret_type = CS_VAL_ANY); void next_char() { - if (source.empty()) { + if (source == send) { return; } if (*source == '\n') { ++current_line; } - source.pop_front(); + ++source; } char current(size_t ahead = 0) { - if (source.size() <= ahead) { + if (std::size_t(send - source) <= ahead) { return '\0'; } return source[ahead]; } - ostd::string_range read_macro_name(); + std::string_view read_macro_name(); - char skip_until(ostd::string_range chars); + char skip_until(std::string_view chars); char skip_until(char cf); void skip_comments(); }; -bool cs_check_num(ostd::string_range s); +bool cs_check_num(std::string_view s); static inline void bcode_incr(uint32_t *bc) { *bc += 0x100; diff --git a/src/cubescript.cc b/src/cubescript.cc index 431845d..47a8113 100644 --- a/src/cubescript.cc +++ b/src/cubescript.cc @@ -3,7 +3,7 @@ namespace cscript { -bool cs_check_num(ostd::string_range s) { +bool cs_check_num(std::string_view s) { if (isdigit(s[0])) { return true; } @@ -51,7 +51,7 @@ cs_alias::cs_alias(cs_state &cs, cs_strref name, cs_strref a, int fl): { p_val.set_str(a); } -cs_alias::cs_alias(cs_state &cs, cs_strref name, ostd::string_range a, int fl): +cs_alias::cs_alias(cs_state &cs, cs_strref name, std::string_view a, int fl): cs_ident(cs_ident_type::ALIAS, name, fl), p_acode(nullptr), p_astack(nullptr), p_val{cs} { @@ -236,7 +236,7 @@ void cs_svar::set_value(cs_strref val) { p_storage = val; } -ostd::string_range cs_command::get_args() const { +std::string_view cs_command::get_args() const { return p_cargs; } @@ -338,7 +338,7 @@ cs_state::cs_state(cs_alloc_cb func, void *data): } })->p_type = CsIdOr; - new_command("local", nullptr, nullptr)->p_type = CsIdLocal; + new_command("local", "", nullptr)->p_type = CsIdLocal; new_command("break", "", [](auto &cs, auto, auto &) { if (cs.is_in_loop()) { @@ -467,7 +467,7 @@ OSTD_EXPORT cs_ident *cs_state::add_ident(cs_ident *id) { return p_state->identmap.back(); } -OSTD_EXPORT cs_ident *cs_state::new_ident(ostd::string_range name, int flags) { +OSTD_EXPORT cs_ident *cs_state::new_ident(std::string_view name, int flags) { cs_ident *id = get_ident(name); if (!id) { if (cs_check_num(name)) { @@ -498,7 +498,7 @@ OSTD_EXPORT cs_ident *cs_state::force_ident(cs_value &v) { return p_state->identmap[DummyIdx]; } -OSTD_EXPORT cs_ident *cs_state::get_ident(ostd::string_range name) { +OSTD_EXPORT cs_ident *cs_state::get_ident(std::string_view name) { auto id = p_state->idents.find(name); if (id != p_state->idents.end()) { return id->second; @@ -506,7 +506,7 @@ OSTD_EXPORT cs_ident *cs_state::get_ident(ostd::string_range name) { return nullptr; } -OSTD_EXPORT cs_alias *cs_state::get_alias(ostd::string_range name) { +OSTD_EXPORT cs_alias *cs_state::get_alias(std::string_view name) { auto id = get_ident(name); if (!id || !id->is_alias()) { return nullptr; @@ -514,7 +514,7 @@ OSTD_EXPORT cs_alias *cs_state::get_alias(ostd::string_range name) { return static_cast(id); } -OSTD_EXPORT bool cs_state::have_ident(ostd::string_range name) { +OSTD_EXPORT bool cs_state::have_ident(std::string_view name) { return p_state->idents.find(name) != p_state->idents.end(); } @@ -531,7 +531,7 @@ OSTD_EXPORT cs_const_ident_r cs_state::get_idents() const { } OSTD_EXPORT cs_ivar *cs_state::new_ivar( - ostd::string_range n, cs_int m, cs_int x, cs_int v, cs_var_cb f, int flags + std::string_view n, cs_int m, cs_int x, cs_int v, cs_var_cb f, int flags ) { return add_ident(p_state->create( cs_strref{*p_state, n}, m, x, v, std::move(f), flags @@ -539,7 +539,7 @@ OSTD_EXPORT cs_ivar *cs_state::new_ivar( } OSTD_EXPORT cs_fvar *cs_state::new_fvar( - ostd::string_range n, cs_float m, cs_float x, cs_float v, cs_var_cb f, int flags + std::string_view n, cs_float m, cs_float x, cs_float v, cs_var_cb f, int flags ) { return add_ident(p_state->create( cs_strref{*p_state, n}, m, x, v, std::move(f), flags @@ -547,7 +547,7 @@ OSTD_EXPORT cs_fvar *cs_state::new_fvar( } OSTD_EXPORT cs_svar *cs_state::new_svar( - ostd::string_range n, ostd::string_range v, cs_var_cb f, int flags + std::string_view n, std::string_view v, cs_var_cb f, int flags ) { return add_ident(p_state->create( cs_strref{*p_state, n}, cs_strref{*p_state, v}, @@ -555,7 +555,7 @@ OSTD_EXPORT cs_svar *cs_state::new_svar( ))->get_svar(); } -OSTD_EXPORT void cs_state::reset_var(ostd::string_range name) { +OSTD_EXPORT void cs_state::reset_var(std::string_view name) { cs_ident *id = get_ident(name); if (!id) { throw cs_error(*this, "variable %s does not exist", name); @@ -566,14 +566,14 @@ OSTD_EXPORT void cs_state::reset_var(ostd::string_range name) { clear_override(*id); } -OSTD_EXPORT void cs_state::touch_var(ostd::string_range name) { +OSTD_EXPORT void cs_state::touch_var(std::string_view name) { cs_ident *id = get_ident(name); if (id && id->is_var()) { static_cast(id)->changed(*this); } } -OSTD_EXPORT void cs_state::set_alias(ostd::string_range name, cs_value v) { +OSTD_EXPORT void cs_state::set_alias(std::string_view name, cs_value v) { cs_ident *id = get_ident(name); if (id) { switch (id->get_type()) { @@ -638,7 +638,7 @@ cs_ident_type cs_ident::get_type() const { return cs_ident_type(p_type); } -ostd::string_range cs_ident::get_name() const { +std::string_view cs_ident::get_name() const { return p_name; } @@ -670,7 +670,7 @@ static inline void cs_override_var(cs_state &cs, cs_var *v, int &vflags, SF sf) } OSTD_EXPORT void cs_state::set_var_int( - ostd::string_range name, cs_int v, bool dofunc, bool doclamp + std::string_view name, cs_int v, bool dofunc, bool doclamp ) { cs_ident *id = get_ident(name); if (!id || id->is_ivar()) { @@ -692,7 +692,7 @@ OSTD_EXPORT void cs_state::set_var_int( } OSTD_EXPORT void cs_state::set_var_float( - ostd::string_range name, cs_float v, bool dofunc, bool doclamp + std::string_view name, cs_float v, bool dofunc, bool doclamp ) { cs_ident *id = get_ident(name); if (!id || id->is_fvar()) { @@ -714,7 +714,7 @@ OSTD_EXPORT void cs_state::set_var_float( } OSTD_EXPORT void cs_state::set_var_str( - ostd::string_range name, ostd::string_range v, bool dofunc + std::string_view name, std::string_view v, bool dofunc ) { cs_ident *id = get_ident(name); if (!id || id->is_svar()) { @@ -732,7 +732,7 @@ OSTD_EXPORT void cs_state::set_var_str( } OSTD_EXPORT std::optional -cs_state::get_var_int(ostd::string_range name) { +cs_state::get_var_int(std::string_view name) { cs_ident *id = get_ident(name); if (!id || id->is_ivar()) { return std::nullopt; @@ -741,7 +741,7 @@ cs_state::get_var_int(ostd::string_range name) { } OSTD_EXPORT std::optional -cs_state::get_var_float(ostd::string_range name) { +cs_state::get_var_float(std::string_view name) { cs_ident *id = get_ident(name); if (!id || id->is_fvar()) { return std::nullopt; @@ -750,7 +750,7 @@ cs_state::get_var_float(ostd::string_range name) { } OSTD_EXPORT std::optional -cs_state::get_var_str(ostd::string_range name) { +cs_state::get_var_str(std::string_view name) { cs_ident *id = get_ident(name); if (!id || id->is_svar()) { return std::nullopt; @@ -759,7 +759,7 @@ cs_state::get_var_str(ostd::string_range name) { } OSTD_EXPORT std::optional -cs_state::get_var_min_int(ostd::string_range name) { +cs_state::get_var_min_int(std::string_view name) { cs_ident *id = get_ident(name); if (!id || id->is_ivar()) { return std::nullopt; @@ -768,7 +768,7 @@ cs_state::get_var_min_int(ostd::string_range name) { } OSTD_EXPORT std::optional -cs_state::get_var_max_int(ostd::string_range name) { +cs_state::get_var_max_int(std::string_view name) { cs_ident *id = get_ident(name); if (!id || id->is_ivar()) { return std::nullopt; @@ -777,7 +777,7 @@ cs_state::get_var_max_int(ostd::string_range name) { } OSTD_EXPORT std::optional -cs_state::get_var_min_float(ostd::string_range name) { +cs_state::get_var_min_float(std::string_view name) { cs_ident *id = get_ident(name); if (!id || id->is_fvar()) { return std::nullopt; @@ -786,7 +786,7 @@ cs_state::get_var_min_float(ostd::string_range name) { } OSTD_EXPORT std::optional -cs_state::get_var_max_float(ostd::string_range name) { +cs_state::get_var_max_float(std::string_view name) { cs_ident *id = get_ident(name); if (!id || id->is_fvar()) { return std::nullopt; @@ -795,7 +795,7 @@ cs_state::get_var_max_float(ostd::string_range name) { } OSTD_EXPORT std::optional -cs_state::get_alias_val(ostd::string_range name) { +cs_state::get_alias_val(std::string_view name) { cs_alias *a = get_alias(name); if (!a) { return std::nullopt; @@ -891,7 +891,7 @@ OSTD_EXPORT void cs_state::set_var_float_checked(cs_fvar *fv, cs_float v) { } OSTD_EXPORT void cs_state::set_var_str_checked( - cs_svar *sv, ostd::string_range v + cs_svar *sv, std::string_view v ) { if (sv->get_flags() & CS_IDF_READONLY) { throw cs_error( @@ -907,10 +907,10 @@ OSTD_EXPORT void cs_state::set_var_str_checked( } OSTD_EXPORT cs_command *cs_state::new_command( - ostd::string_range name, ostd::string_range args, cs_command_cb func + std::string_view name, std::string_view args, cs_command_cb func ) { int nargs = 0; - for (ostd::string_range fmt(args); !fmt.empty(); ++fmt) { + for (auto fmt = args.begin(); fmt != args.end(); ++fmt) { switch (*fmt) { case 'i': case 'b': @@ -935,16 +935,19 @@ OSTD_EXPORT cs_command *cs_state::new_command( if (nargs < (*fmt - '0')) { return nullptr; } - if ((fmt.size() != 2) || ((fmt[1] != 'C') && (fmt[1] != 'V'))) { + if ((args.end() - fmt) != 2) { + return nullptr; + } + if ((fmt[1] != 'C') && (fmt[1] != 'V')) { return nullptr; } if (nargs < MaxArguments) { - fmt = ostd::string_range{&fmt[-int(*fmt) + '0' - 1], &fmt[fmt.size()]}; + fmt -= *fmt - '0' + 1; } break; case 'C': case 'V': - if (fmt.size() != 1) { + if ((fmt + 1) != args.end()) { return nullptr; } break; diff --git a/src/lib_list.cc b/src/lib_list.cc index 7269531..113d3ca 100644 --- a/src/lib_list.cc +++ b/src/lib_list.cc @@ -23,8 +23,8 @@ struct cs_arg_val { }; template<> -struct cs_arg_val { - static ostd::string_range get(cs_value &tv) { +struct cs_arg_val { + static std::string_view get(cs_value &tv) { return tv.get_str(); } }; @@ -70,7 +70,7 @@ static inline void cs_list_assoc( } static void cs_loop_list_conc( - cs_state &cs, cs_value &res, cs_ident *id, ostd::string_range list, + cs_state &cs, cs_value &res, cs_ident *id, std::string_view list, cs_bcode *body, bool space ) { cs_stacked_value idv{cs, id}; @@ -101,7 +101,7 @@ end: } int cs_list_includes( - cs_state &cs, ostd::string_range list, ostd::string_range needle + cs_state &cs, std::string_view list, std::string_view needle ) { int offset = 0; for (cs_list_parse_state p{list}; list_parse(p, cs);) { @@ -117,8 +117,8 @@ template static inline void cs_list_merge( cs_state &cs, cs_value_r args, cs_value &res, F cmp ) { - ostd::string_range list = args[0].get_str(); - ostd::string_range elems = args[1].get_str(); + std::string_view list = args[0].get_str(); + std::string_view elems = args[1].get_str(); cs_charbuf buf{cs}; if (PushList) { buf.append(list); @@ -153,7 +153,7 @@ void cs_init_lib_list(cs_state &gcs) { cs_list_parse_state p{str}; p.item = str; for (size_t i = 1; i < args.size(); ++i) { - p.input = str; + p.set_input(str); cs_int pos = args[i].get_int(); for (; pos > 0; --pos) { if (!list_parse(p, cs)) { @@ -161,7 +161,7 @@ void cs_init_lib_list(cs_state &gcs) { } } if (pos > 0 || !list_parse(p, cs)) { - p.item = p.quoted_item = ostd::string_range(); + p.item = p.quoted_item = std::string_view{}; } } res.set_str(list_get_item(p, cs)); @@ -183,18 +183,18 @@ void cs_init_lib_list(cs_state &gcs) { if (offset > 0) { list_find_item(p); } - res.set_str(p.input); + res.set_str(p.get_input()); return; } - char const *list = p.input.data(); - p.quoted_item = ostd::string_range(); + char const *list = p.get_input().data(); + p.quoted_item = std::string_view{}; if (len > 0 && list_parse(p, cs)) { while (--len > 0 && list_parse(p, cs)); } - ostd::string_range quote = p.quoted_item; + std::string_view quote = p.quoted_item; char const *qend = !quote.empty() ? "e[quote.size()] : list; - res.set_str(ostd::string_range{list, qend}); + res.set_str(std::string_view{list, std::size_t(qend - list)}); }); gcs.new_command("listfind", "rse", [](auto &cs, auto args, auto &res) { @@ -255,8 +255,8 @@ void cs_init_lib_list(cs_state &gcs) { ); }); gcs.new_command("listfind=s", "s", [](auto &cs, auto args, auto &res) { - cs_list_find( - cs, args, res, [](cs_list_parse_state const &p, ostd::string_range val) { + cs_list_find( + cs, args, res, [](cs_list_parse_state const &p, std::string_view val) { return p.item == val; } ); @@ -277,8 +277,8 @@ void cs_init_lib_list(cs_state &gcs) { ); }); gcs.new_command("listassoc=s", "s", [](auto &cs, auto args, auto &res) { - cs_list_assoc( - cs, args, res, [](cs_list_parse_state const &p, ostd::string_range val) { + cs_list_assoc( + cs, args, res, [](cs_list_parse_state const &p, std::string_view val) { return p.item == val; } ); @@ -424,16 +424,16 @@ end: gcs.new_command("prettylist", "ss", [](auto &cs, auto args, auto &res) { auto buf = ostd::appender(cs); - ostd::string_range s = args[0].get_str(); - ostd::string_range conj = args[1].get_str(); + std::string_view s = args[0].get_str(); + std::string_view conj = args[1].get_str(); cs_list_parse_state p{s}; size_t len = list_count(p, cs); size_t n = 0; - for (p.input = s; list_parse(p, cs); ++n) { + for (p.set_input(s); list_parse(p, cs); ++n) { if (!p.quoted_item.empty() && (p.quoted_item.front() == '"')) { util::unescape_string(buf, p.item); } else { - ostd::range_put_all(buf, p.item); + buf.get().append(p.item); } if ((n + 1) < len) { if ((len > 2) || conj.empty()) { @@ -441,7 +441,7 @@ end: } if ((n + 2 == len) && !conj.empty()) { buf.put(' '); - ostd::range_put_all(buf, conj); + buf.get().append(conj); } buf.put(' '); } @@ -468,8 +468,8 @@ end: gcs.new_command("listsplice", "ssii", [](auto &cs, auto args, auto &res) { cs_int offset = std::max(args[2].get_int(), cs_int(0)); cs_int len = std::max(args[3].get_int(), cs_int(0)); - ostd::string_range s = args[0].get_str(); - ostd::string_range vals = args[1].get_str(); + std::string_view s = args[0].get_str(); + std::string_view vals = args[1].get_str(); char const *list = s.data(); cs_list_parse_state p{s}; for (cs_int i = 0; i < offset; ++i) { @@ -477,7 +477,7 @@ end: break; } } - ostd::string_range quote = p.quoted_item; + std::string_view quote = p.quoted_item; char const *qend = !quote.empty() ? "e[quote.size()] : list; cs_charbuf buf{cs}; if (qend > list) { @@ -495,8 +495,8 @@ end: } } list_find_item(p); - if (!p.input.empty()) { - switch (p.input.front()) { + if (!p.get_input().empty()) { + switch (p.get_input().front()) { case ')': case ']': break; @@ -504,7 +504,7 @@ end: if (!buf.empty()) { buf.push_back(' '); } - buf.append(p.input); + buf.append(p.get_input()); break; } } @@ -515,8 +515,8 @@ end: } struct ListSortItem { - ostd::string_range str; - ostd::string_range quote; + std::string_view str; + std::string_view quote; }; struct ListSortFun { @@ -534,7 +534,7 @@ struct ListSortFun { }; static void cs_list_sort( - cs_state &cs, cs_value &res, ostd::string_range list, + cs_state &cs, cs_value &res, std::string_view list, cs_ident *x, cs_ident *y, cs_bcode *body, cs_bcode *unique ) { if (x == y || !x->is_alias() || !y->is_alias()) { @@ -575,7 +575,7 @@ static void cs_list_sort( for (size_t i = 1; i < items.size(); i++) { ListSortItem &item = items[i]; if (f(items[i - 1], item)) { - item.quote = nullptr; + item.quote = std::string_view{}; } else { totaluniq += item.quote.size(); ++nuniq; @@ -591,7 +591,7 @@ static void cs_list_sort( for (size_t j = 0; j < i; ++j) { ListSortItem &prev = items[j]; if (!prev.quote.empty() && f(item, prev)) { - item.quote = nullptr; + item.quote = std::string_view{}; break; } } diff --git a/src/lib_str.cc b/src/lib_str.cc index 240c162..9e71ded 100644 --- a/src/lib_str.cc +++ b/src/lib_str.cc @@ -16,8 +16,8 @@ static inline void cs_strgcmp(cs_value_r args, cs_value &res, F cfunc) { } } else { val = cfunc( - !args.empty() ? args[0].get_str() : ostd::string_range(), - ostd::string_range() + !args.empty() ? args[0].get_str() : std::string_view(), + std::string_view() ); } res.set_int(cs_int(val)); @@ -25,16 +25,13 @@ static inline void cs_strgcmp(cs_value_r args, cs_value &res, F cfunc) { void cs_init_lib_string(cs_state &cs) { cs.new_command("strstr", "ss", [](auto &, auto args, auto &res) { - ostd::string_range a = args[0].get_str(), b = args[1].get_str(); - ostd::string_range s = a; - for (cs_int i = 0; b.size() <= s.size(); ++i) { - if (b == s.slice(0, b.size())) { - res.set_int(i); - return; - } - ++s; + std::string_view a = args[0].get_str(), b = args[1].get_str(); + auto pos = a.find(b); + if (pos == a.npos) { + res.set_int(-1); + } else { + res.set_int(cs_int(pos)); } - res.set_int(-1); }); cs.new_command("strlen", "s", [](auto &, auto args, auto &res) { @@ -42,7 +39,7 @@ void cs_init_lib_string(cs_state &cs) { }); cs.new_command("strcode", "si", [](auto &, auto args, auto &res) { - ostd::string_range str = args[0].get_str(); + std::string_view str = args[0].get_str(); cs_int i = args[1].get_int(); if (i >= cs_int(str.size())) { res.set_int(0); @@ -53,11 +50,11 @@ void cs_init_lib_string(cs_state &cs) { cs.new_command("codestr", "i", [](auto &, auto args, auto &res) { char const p[2] = { char(args[0].get_int()), '\0' }; - res.set_str(ostd::string_range{static_cast(p)}); + res.set_str(std::string_view{static_cast(p)}); }); cs.new_command("strlower", "s", [](auto &ccs, auto args, auto &res) { - auto inps = ostd::string_range{args[0].get_str()}; + auto inps = std::string_view{args[0].get_str()}; auto *ics = cs_get_sstate(ccs); auto *buf = ics->strman->alloc_buf(inps.size()); for (auto i: ostd::range(inps.size())) { @@ -70,7 +67,7 @@ void cs_init_lib_string(cs_state &cs) { }); cs.new_command("strupper", "s", [](auto &ccs, auto args, auto &res) { - auto inps = ostd::string_range{args[0].get_str()}; + auto inps = std::string_view{args[0].get_str()}; auto *ics = cs_get_sstate(ccs); auto *buf = ics->strman->alloc_buf(inps.size()); for (auto i: ostd::range(inps.size())) { @@ -108,16 +105,16 @@ void cs_init_lib_string(cs_state &cs) { } cs_charbuf s{ccs}; cs_strref fs = args[0].get_str(); - ostd::string_range f{fs}; - while (!f.empty()) { - char c = *f; - ++f; - if ((c == '%') && !f.empty()) { - char ic = *f; - ++f; - if (ic >= '1' && ic <= '9') { + std::string_view f{fs}; + for (auto it = f.begin(); it != f.end(); ++it) { + char c = *it; + ++it; + if ((c == '%') && (it != f.end())) { + char ic = *it; + ++it; + if ((ic >= '1') && (ic <= '9')) { int i = ic - '0'; - if (size_t(i) < args.size()) { + if (std::size_t(i) < args.size()) { s.append(args[i].get_str()); } } else { @@ -144,89 +141,85 @@ void cs_init_lib_string(cs_state &cs) { }); cs.new_command("substr", "siiN", [](auto &, auto args, auto &res) { - ostd::string_range s = args[0].get_str(); + std::string_view s = args[0].get_str(); cs_int start = args[1].get_int(), count = args[2].get_int(); cs_int numargs = args[3].get_int(); cs_int len = cs_int(s.size()), offset = std::clamp(start, cs_int(0), len); - res.set_str(ostd::string_range{ + res.set_str(std::string_view{ &s[offset], - &s[offset] + ((numargs >= 3) + ((numargs >= 3) ? size_t(std::clamp(count, cs_int(0), len - offset)) : size_t(len - offset)) }); }); cs.new_command("strcmp", "s1V", [](auto &, auto args, auto &res) { - cs_strgcmp(args, res, std::equal_to()); + cs_strgcmp(args, res, std::equal_to()); }); cs.new_command("=s", "s1V", [](auto &, auto args, auto &res) { - cs_strgcmp(args, res, std::equal_to()); + cs_strgcmp(args, res, std::equal_to()); }); cs.new_command("!=s", "s1V", [](auto &, auto args, auto &res) { - cs_strgcmp(args, res, std::not_equal_to()); + cs_strgcmp(args, res, std::not_equal_to()); }); cs.new_command("()); + cs_strgcmp(args, res, std::less()); }); cs.new_command(">s", "s1V", [](auto &, auto args, auto &res) { - cs_strgcmp(args, res, std::greater()); + cs_strgcmp(args, res, std::greater()); }); cs.new_command("<=s", "s1V", [](auto &, auto args, auto &res) { - cs_strgcmp(args, res, std::less_equal()); + cs_strgcmp(args, res, std::less_equal()); }); cs.new_command(">=s", "s1V", [](auto &, auto args, auto &res) { - cs_strgcmp(args, res, std::greater_equal()); + cs_strgcmp(args, res, std::greater_equal()); }); cs.new_command("strreplace", "ssss", [](auto &ccs, auto args, auto &res) { - ostd::string_range s = args[0].get_str(); - ostd::string_range oldval = args[1].get_str(), - newval = args[2].get_str(), - newval2 = args[3].get_str(); + std::string_view s = args[0].get_str(); + std::string_view oldval = args[1].get_str(), + newval = args[2].get_str(), + newval2 = args[3].get_str(); if (newval2.empty()) { newval2 = newval; } - if (!oldval.size()) { + if (oldval.empty()) { res.set_str(s); return; } cs_charbuf buf{ccs}; for (size_t i = 0;; ++i) { - ostd::string_range found; - ostd::string_range trys = s; - for (; oldval.size() <= trys.size(); ++trys) { - if (trys.slice(0, oldval.size()) == oldval) { - found = trys; - break; - } - } - if (!found.empty()) { - buf.append(s.slice(0, &found[0] - &s[0])); - buf.append((i & 1) ? newval2 : newval); - s = found.slice(oldval.size(), found.size()); - } else { + std::string_view found; + auto p = s.find(oldval); + if (p == s.npos) { buf.append(s); - res.set_str(buf.str()); + res.set_str(s); return; } + buf.append(s.substr(0, p)); + buf.append((i & 1) ? newval2 : newval); + buf.append(s.substr( + p + oldval.size(), + s.size() - p - oldval.size() + )); } }); cs.new_command("strsplice", "ssii", [](auto &ccs, auto args, auto &res) { - ostd::string_range s = args[0].get_str(); - ostd::string_range vals = args[1].get_str(); - cs_int skip = args[2].get_int(), + std::string_view s = args[0].get_str(); + std::string_view vals = args[1].get_str(); + cs_int skip = args[2].get_int(), count = args[3].get_int(); cs_int offset = std::clamp(skip, cs_int(0), cs_int(s.size())), - len = std::clamp(count, cs_int(0), cs_int(s.size()) - offset); + len = std::clamp(count, cs_int(0), cs_int(s.size()) - offset); cs_charbuf p{ccs}; p.reserve(s.size() - len + vals.size()); if (offset) { - p.append(s.slice(0, offset)); + p.append(s.substr(0, offset)); } p.append(vals); if ((offset + len) < cs_int(s.size())) { - p.append(s.slice(offset + len, s.size())); + p.append(s.substr(offset + len, s.size() - offset - len)); } res.set_str(p.str()); }); diff --git a/tools/edit_fallback.hh b/tools/edit_fallback.hh index e1fa084..136012b 100644 --- a/tools/edit_fallback.hh +++ b/tools/edit_fallback.hh @@ -5,7 +5,7 @@ #include -inline void init_lineedit(cs_state &, ostd::string_range) { +inline void init_lineedit(cs_state &, std::string_view) { } inline std::optional read_line(cs_state &, cs_svar *pr) { @@ -13,7 +13,7 @@ inline std::optional read_line(cs_state &, cs_svar *pr) { return ostd::cin.get_line(ostd::appender()).get(); } -inline void add_history(cs_state &, ostd::string_range) { +inline void add_history(cs_state &, std::string_view) { } #endif diff --git a/tools/edit_linenoise.hh b/tools/edit_linenoise.hh index 582f7bd..c6c483e 100644 --- a/tools/edit_linenoise.hh +++ b/tools/edit_linenoise.hh @@ -17,16 +17,16 @@ static cs_state *ln_cs = nullptr; inline void ln_complete(char const *buf, linenoiseCompletions *lc) { - ostd::string_range cmd = get_complete_cmd(buf); + std::string_view cmd = get_complete_cmd(buf); for (auto id: ln_cs->get_idents()) { if (!id->is_command()) { continue; } - ostd::string_range idname = id->get_name(); + std::string_view idname = id->get_name(); if (idname.size() <= cmd.size()) { continue; } - if (idname.slice(0, cmd.size()) == cmd) { + if (idname.substr(0, cmd.size()) == cmd) { linenoiseAddCompletion(lc, idname.data()); } } @@ -51,7 +51,7 @@ inline void ln_hint_free(void *hint) { delete[] static_cast(hint); } -inline void init_lineedit(cs_state &cs, ostd::string_range) { +inline void init_lineedit(cs_state &cs, std::string_view) { /* sensible default history size */ linenoiseHistorySetMaxLen(1000); ln_cs = &cs; @@ -75,7 +75,7 @@ inline std::optional read_line(cs_state &, cs_svar *pr) { return ret; } -inline void add_history(cs_state &, ostd::string_range line) { +inline void add_history(cs_state &, std::string_view line) { /* backed by std::string so it's terminated */ linenoiseHistoryAdd(line.data()); } diff --git a/tools/edit_readline.hh b/tools/edit_readline.hh index 44d39e7..f12026a 100644 --- a/tools/edit_readline.hh +++ b/tools/edit_readline.hh @@ -15,7 +15,7 @@ static cs_state *rd_cs = nullptr; inline char *ln_complete_list(char const *buf, int state) { - static ostd::string_range cmd; + static std::string_view cmd; static ostd::iterator_range itr; if (!state) { @@ -28,11 +28,11 @@ inline char *ln_complete_list(char const *buf, int state) { if (!id->is_command()) { continue; } - ostd::string_range idname = id->get_name(); + std::string_view idname = id->get_name(); if (idname.size() <= cmd.size()) { continue; } - if (idname.slice(0, cmd.size()) == cmd) { + if (idname.substr(0, cmd.size()) == cmd) { itr.pop_front(); return strdup(idname.data()); } @@ -63,7 +63,7 @@ inline void ln_hint() { rl_replace_line(old.data(), 0); } -inline void init_lineedit(cs_state &cs, ostd::string_range) { +inline void init_lineedit(cs_state &cs, std::string_view) { rd_cs = &cs; rl_attempted_completion_function = ln_complete; rl_redisplay_function = ln_hint; @@ -79,7 +79,7 @@ inline std::optional read_line(cs_state &, cs_svar *pr) { return ret; } -inline void add_history(cs_state &, ostd::string_range line) { +inline void add_history(cs_state &, std::string_view line) { /* backed by std::string so it's terminated */ add_history(line.data()); } diff --git a/tools/repl.cc b/tools/repl.cc index 27ca959..30e09ba 100644 --- a/tools/repl.cc +++ b/tools/repl.cc @@ -10,7 +10,7 @@ using namespace cscript; -ostd::string_range version = "CubeScript 0.0.1"; +std::string_view version = "CubeScript 0.0.1"; /* util */ @@ -28,18 +28,17 @@ static bool stdin_is_tty() { /* line editing support */ -inline ostd::string_range get_complete_cmd(ostd::string_range buf) { - ostd::string_range not_allowed = "\"/;()[] \t\r\n\0"; - ostd::string_range found = ostd::find_one_of(buf, not_allowed); - while (!found.empty()) { - ++found; - buf = found; - found = ostd::find_one_of(found, not_allowed); +inline std::string_view get_complete_cmd(std::string_view buf) { + std::string_view not_allowed = "\"/;()[] \t\r\n\0"; + auto found = buf.find_first_of(not_allowed); + while (found != buf.npos) { + buf = buf.substr(found + 1, buf.size() - found - 1); + found = buf.find_first_of(not_allowed); } return buf; } -inline ostd::string_range get_arg_type(char arg) { +inline std::string_view get_arg_type(char arg) { switch (arg) { case 'i': return "int"; @@ -71,15 +70,15 @@ inline ostd::string_range get_arg_type(char arg) { return "illegal"; } -inline void fill_cmd_args(std::string &writer, ostd::string_range args) { +inline void fill_cmd_args(std::string &writer, std::string_view args) { char variadic = '\0'; int nrep = 0; if (!args.empty() && ((args.back() == 'V') || (args.back() == 'C'))) { variadic = args.back(); - args.pop_back(); + args.remove_suffix(1); if (!args.empty() && isdigit(args.back())) { nrep = args.back() - '0'; - args.pop_back(); + args.remove_suffix(1); } } if (args.empty()) { @@ -96,8 +95,8 @@ inline void fill_cmd_args(std::string &writer, ostd::string_range args) { if (i != 0) { writer += ", "; } - writer += get_arg_type(*args); - ++args; + writer += get_arg_type(args.front()); + args.remove_prefix(1); } } if (variadic) { @@ -128,22 +127,27 @@ inline void fill_cmd_args(std::string &writer, ostd::string_range args) { } } -inline cs_command *get_hint_cmd(cs_state &cs, ostd::string_range buf) { - ostd::string_range nextchars = "([;"; - auto lp = ostd::find_one_of(buf, nextchars); - if (!lp.empty()) { - cs_command *cmd = get_hint_cmd(cs, buf.slice(1, buf.size())); +inline cs_command *get_hint_cmd(cs_state &cs, std::string_view buf) { + std::string_view nextchars = "([;"; + auto lp = buf.find_first_of(nextchars); + if (lp != buf.npos) { + cs_command *cmd = get_hint_cmd(cs, buf.substr(1, buf.size() - 1)); if (cmd) { return cmd; } } - while (!buf.empty() && isspace(buf.front())) { - ++buf; + std::size_t nsp = 0; + for (auto c: buf) { + if (!isspace(c)) { + break; + } + ++nsp; } - ostd::string_range spaces = " \t\r\n"; - ostd::string_range s = ostd::find_one_of(buf, spaces); - if (!s.empty()) { - buf = buf.slice(0, &s[0] - &buf[0]); + buf.remove_prefix(nsp); + std::string_view spaces = " \t\r\n"; + auto p = buf.find_first_of(spaces); + if (p != buf.npos) { + buf = buf.substr(0, p); } if (!buf.empty()) { auto cmd = cs.get_ident(buf); @@ -158,7 +162,7 @@ inline cs_command *get_hint_cmd(cs_state &cs, ostd::string_range buf) { /* usage */ -void print_usage(ostd::string_range progname, bool err) { +void print_usage(std::string_view progname, bool err) { auto &s = err ? ostd::cerr : ostd::cout; s.writeln( "Usage: ", progname, " [options] [file]\n" @@ -216,8 +220,8 @@ static void repl_print_var(cs_state const &cs, cs_var const &var) { } case cs_ident_type::SVAR: { auto &sv = static_cast(var); - auto val = ostd::string_range{sv.get_value()}; - if (ostd::find(val, '"').empty()) { + auto val = std::string_view{sv.get_value()}; + if (val.find('"') == val.npos) { ostd::writefln("%s = \"%s\"", sv.get_name(), val); } else { ostd::writefln("%s = [%s]", sv.get_name(), val); @@ -229,7 +233,7 @@ static void repl_print_var(cs_state const &cs, cs_var const &var) { } } -static bool do_call(cs_state &cs, ostd::string_range line, bool file = false) { +static bool do_call(cs_state &cs, std::string_view line, bool file = false) { cs_value ret{cs}; scs = &cs; signal(SIGINT, do_sigint); @@ -244,15 +248,17 @@ static bool do_call(cs_state &cs, ostd::string_range line, bool file = false) { } catch (cscript::cs_error const &e) { signal(SIGINT, SIG_DFL); scs = nullptr; - ostd::string_range terr = e.what(); - auto col = ostd::find(terr, ':'); + std::string_view terr = e.what(); + auto col = terr.find(':'); bool is_lnum = false; - if (!col.empty()) { - is_lnum = ostd::find_if( - terr.slice(0, &col[0] - &terr[0]), + if (col != terr.npos) { + auto pre = terr.substr(0, col); + auto it = std::find_if( + pre.begin(), pre.end(), [](auto c) { return !isdigit(c); } - ).empty(); - terr = col.slice(2, col.size()); + ); + is_lnum = (it == pre.end()); + terr = terr.substr(col + 2, terr.size() - col - 2); } if (!file && ((terr == "missing \"]\"") || (terr == "missing \")\""))) { return true; @@ -267,7 +273,7 @@ static bool do_call(cs_state &cs, ostd::string_range line, bool file = false) { signal(SIGINT, SIG_DFL); scs = nullptr; if (ret.get_type() != cs_value_type::NONE) { - ostd::writeln(ret.get_str()); + ostd::writeln(std::string_view{ret.get_str()}); } return false; } @@ -328,7 +334,7 @@ int main(int argc, char **argv) { }); gcs.new_command("echo", "C", [](auto &, auto args, auto &) { - ostd::writeln(ostd::string_range{args[0].get_str()}); + ostd::writeln(std::string_view{args[0].get_str()}); }); int firstarg = 0;