ported remaining commands

master
Daniel Kolesa 2015-08-08 15:34:05 +01:00
parent 421bdb69ec
commit f9817a9b4a
1 changed files with 66 additions and 46 deletions

View File

@ -3745,6 +3745,8 @@ int cs_list_includes(const char *list, ostd::ConstCharRange needle) {
return -1; return -1;
} }
static void cs_init_lib_list_sort(CsState &cs);
void init_lib_list(CsState &cs) { void init_lib_list(CsState &cs) {
cs.add_command("listlen", "s", [](CsState &cs, char *s) { cs.add_command("listlen", "s", [](CsState &cs, char *s) {
cs.result->set_int(listlen(cs, s)); cs.result->set_int(listlen(cs, s));
@ -4093,45 +4095,53 @@ found:
p.push('\0'); p.push('\0');
cs.result->set_str(p.disown()); cs.result->set_str(p.disown());
}); });
cs_init_lib_list_sort(cs);
} }
/* struct ListSortItem {
struct sortitem { const char *str;
const char *str, *quotestart, *quoteend; ostd::ConstCharRange quote;
int quotelength() const {
return int(quoteend - quotestart);
}
}; };
struct sortfun { struct ListSortFun {
CsState &cs; CsState &cs;
Ident *x, *y; Ident *x, *y;
ostd::Uint32 *body; ostd::Uint32 *body;
bool operator()(const sortitem &xval, const sortitem &yval) { bool operator()(const ListSortItem &xval, const ListSortItem &yval) {
if (x->valtype != VAL_CSTR) x->valtype = VAL_CSTR; if (x->valtype != VAL_CSTR)
x->valtype = VAL_CSTR;
x->clean_code(); x->clean_code();
x->val.code = (const ostd::Uint32 *)xval.str; x->val.code = (const ostd::Uint32 *)xval.str;
if (y->valtype != VAL_CSTR) y->valtype = VAL_CSTR; if (y->valtype != VAL_CSTR)
y->valtype = VAL_CSTR;
y->clean_code(); y->clean_code();
y->val.code = (const ostd::Uint32 *)yval.str; y->val.code = (const ostd::Uint32 *)yval.str;
return cs.run_bool(body); return cs.run_bool(body);
} }
}; };
void sortlist(CsState &cs, char *list, Ident *x, Ident *y, ostd::Uint32 *body, ostd::Uint32 *unique) { void cs_list_sort(CsState &cs, char *list, Ident *x, Ident *y,
if (x == y || x->type != ID_ALIAS || y->type != ID_ALIAS) return; ostd::Uint32 *body, ostd::Uint32 *unique) {
if (x == y || x->type != ID_ALIAS || y->type != ID_ALIAS)
return;
ostd::Vector<ListSortItem> items;
ostd::Size clen = strlen(list);
ostd::Size total = 0;
ostd::Vector<sortitem> items;
int clen = strlen(list), total = 0;
char *cstr = dup_ostr(ostd::ConstCharRange(list, clen)); char *cstr = dup_ostr(ostd::ConstCharRange(list, clen));
const char *curlist = list, *start, *end, *quotestart, *quoteend; const char *curlist = list, *start, *end, *quotestart, *quoteend;
while (parselist(curlist, start, end, quotestart, quoteend)) { while (parselist(curlist, start, end, quotestart, quoteend)) {
cstr[end - list] = '\0'; cstr[end - list] = '\0';
sortitem item = { &cstr[start - list], quotestart, quoteend }; ListSortItem item = {
&cstr[start - list],
ostd::ConstCharRange(quotestart, quoteend)
};
items.push(item); items.push(item);
total += item.quotelength(); total += item.quote.size();
} }
if (items.empty()) { if (items.empty()) {
@ -4145,39 +4155,41 @@ void sortlist(CsState &cs, char *list, Ident *x, Ident *y, ostd::Uint32 *body, o
y->push_arg(null_value, ystack); y->push_arg(null_value, ystack);
y->flags &= ~IDF_UNKNOWN; y->flags &= ~IDF_UNKNOWN;
int totalunique = total, numunique = items.size(); ostd::Size totaluniq = total;
ostd::Size nuniq = items.size();
if (body) { if (body) {
sortfun f = { cs, x, y, body }; ListSortFun f = { cs, x, y, body };
ostd::sort(items.iter(), f); ostd::sort(items.iter(), f);
if ((*unique & CODE_OP_MASK) != CODE_EXIT) { if ((*unique & CODE_OP_MASK) != CODE_EXIT) {
f.body = unique; f.body = unique;
totalunique = items[0].quotelength(); totaluniq = items[0].quote.size();
numunique = 1; nuniq = 1;
for (ostd::Size i = 1; i < items.size(); i++) { for (ostd::Size i = 1; i < items.size(); i++) {
sortitem &item = items[i]; ListSortItem &item = items[i];
if (f(items[i - 1], item)) item.quotestart = nullptr; if (f(items[i - 1], item))
item.quote = nullptr;
else { else {
totalunique += item.quotelength(); totaluniq += item.quote.size();
numunique++; ++nuniq;
} }
} }
} }
} else { } else {
sortfun f = { cs, x, y, unique }; ListSortFun f = { cs, x, y, unique };
totalunique = items[0].quotelength(); totaluniq = items[0].quote.size();
numunique = 1; nuniq = 1;
for (ostd::Size i = 1; i < items.size(); i++) { for (ostd::Size i = 1; i < items.size(); i++) {
sortitem &item = items[i]; ListSortItem &item = items[i];
for (ostd::Size j = 0; j < i; ++j) { for (ostd::Size j = 0; j < i; ++j) {
sortitem &prev = items[j]; ListSortItem &prev = items[j];
if (prev.quotestart && f(item, prev)) { if (!prev.quote.empty() && f(item, prev)) {
item.quotestart = nullptr; item.quote = nullptr;
break; break;
} }
} }
if (item.quotestart) { if (!item.quote.empty()) {
totalunique += item.quotelength(); totaluniq += item.quote.size();
numunique++; ++nuniq;
} }
} }
} }
@ -4186,28 +4198,36 @@ void sortlist(CsState &cs, char *list, Ident *x, Ident *y, ostd::Uint32 *body, o
y->pop_arg(); y->pop_arg();
char *sorted = cstr; char *sorted = cstr;
int sortedlen = totalunique + ostd::max(numunique - 1, 0); ostd::Size sortedlen = totaluniq + ostd::max(nuniq - 1, ostd::Size(0));
if (clen < sortedlen) { if (clen < sortedlen) {
delete[] cstr; delete[] cstr;
sorted = new char[sortedlen + 1]; sorted = new char[sortedlen + 1];
} }
int offset = 0; ostd::Size offset = 0;
for (ostd::Size i = 0; i < items.size(); ++i) { for (ostd::Size i = 0; i < items.size(); ++i) {
sortitem &item = items[i]; ListSortItem &item = items[i];
if (!item.quotestart) continue; if (item.quote.empty())
int len = item.quotelength(); continue;
if (i) sorted[offset++] = ' '; if (i)
memcpy(&sorted[offset], item.quotestart, len); sorted[offset++] = ' ';
offset += len; memcpy(&sorted[offset], item.quote.data(), item.quote.size());
offset += item.quote.size();
} }
sorted[offset] = '\0'; sorted[offset] = '\0';
cs.result->set_str(sorted); cs.result->set_str(sorted);
} }
COMMAND(sortlist, "srree");
ICOMMAND(uniquelist, "srre", (CsState &cs, char *list, Ident *x, Ident *y, ostd::Uint32 *body), sortlist(cs, list, x, y, nullptr, body)); static void cs_init_lib_list_sort(CsState &cs) {
*/ cs.add_command("sortlist", "srree", cs_list_sort);
cs.add_command("uniquelist", "srre", [](CsState &cs, char *list,
Ident *x, Ident *y,
ostd::Uint32 *body) {
cs_list_sort(cs, list, x, y, nullptr, body);
});
}
static constexpr float PI = 3.14159265358979f; static constexpr float PI = 3.14159265358979f;
static constexpr float RAD = PI / 180.0f; static constexpr float RAD = PI / 180.0f;