--- parser3/src/classes/table.C 2016/09/08 19:28:34 1.324
+++ parser3/src/classes/table.C 2017/01/13 13:50:28 1.341
@@ -22,7 +22,7 @@
#define USE_STRINGSTREAM
#endif
-volatile const char * IDENT_TABLE_C="$Id: table.C,v 1.324 2016/09/08 19:28:34 moko Exp $";
+volatile const char * IDENT_TABLE_C="$Id: table.C,v 1.341 2017/01/13 13:50:28 moko Exp $";
// class
@@ -74,15 +74,15 @@ static Table::Action_options get_action_
else
throw Exception(PARSER_RUNTIME, &soffset, "must be 'cur' string or expression");
} else
- result.offset=r.process_to_value(*voffset).as_int();
+ result.offset=r.process(*voffset).as_int();
}
if(Value* vlimit=options->get(sql_limit_name)) {
valid_options++;
- result.limit=r.process_to_value(*vlimit).as_int();
+ result.limit=r.process(*vlimit).as_int();
}
if(Value *vreverse=(Value *)options->get(table_reverse_name)) {
valid_options++;
- result.reverse=r.process_to_value(*vreverse).as_bool();
+ result.reverse=r.process(*vreverse).as_bool();
if(result.reverse && !defined_offset)
result.offset=source.count()-1;
}
@@ -121,9 +121,9 @@ struct TableControlChars {
if(sencloser->is_empty()){
encloser=0;
} else {
- if(sencloser->length()!=1)
- throw Exception(PARSER_RUNTIME, sencloser, "encloser must be one byte character");
- encloser=sencloser->first_char();
+ if(sencloser->length()!=1)
+ throw Exception(PARSER_RUNTIME, sencloser, "encloser must be empty or one byte character");
+ encloser=sencloser->first_char();
}
result++;
}
@@ -160,10 +160,12 @@ public:
String *extract(char *pos){
String *result=new String;
- // first: their langs
- result->langs.append(result->body, langs, pos-base, strlen(pos));
- // next: letters themselves
- result->body=Body(pos);
+ if(size_t len=strlen(pos)){
+ // first: their langs
+ result->langs.append(result->body, langs, pos-base, len);
+ // next: letters themselves
+ result->body=Body(pos);
+ }
return result;
}
};
@@ -171,15 +173,15 @@ public:
inline lsplit_sresult lsplit(char* *string_ref, const char* delims, StringSplitHelper& helper) {
lsplit_sresult result;
if(char *pos=*string_ref) {
- while(char* v=strpbrk(pos, delims)) {
- if(helper.check_lang(v)){
- result.delim=*v;
- *v=0;
+ while(pos=strpbrk(pos, delims)) {
+ if(helper.check_lang(pos)){
+ result.delim=*pos;
+ *pos=0;
result.piece=helper.extract(*string_ref);
- *string_ref=v+1;
+ *string_ref=pos+1;
return result;
}
- pos=v+1;
+ pos++;
}
result.piece=helper.extract(*string_ref);
*string_ref=0;
@@ -196,19 +198,19 @@ static lsplit_sresult lsplit(char** stri
// we are enclosed, searching for second encloser
while(1) {
- if(char* v=strchr(pos, encloser)){
- if(helper.check_lang(v)){
- *(v++)=0;
+ if(pos=strchr(pos, encloser)){
+ if(helper.check_lang(pos)){
+ *(pos++)=0;
result.append(helper.extract(*string_ref));
- if(*v==encloser && helper.check_lang(v)){ // double-encloser stands for encloser
- *string_ref=v+1;
+ if(*pos==encloser && helper.check_lang(pos)){ // double-encloser stands for encloser
+ *string_ref=pos;
} else {
- *string_ref=pos=v;
+ *string_ref=pos;
break;
}
}
- pos=v+1;
- }{
+ pos++;
+ } else {
result.append(helper.extract(*string_ref));
*string_ref=0;
return result;
@@ -216,17 +218,17 @@ static lsplit_sresult lsplit(char** stri
}
// we are no longer enclosed, searching for delimiter
- while(char* v=strpbrk(pos, delims)) {
- if(helper.check_lang(v)){
- result.delim=*v;
- if(v>*string_ref){
- *v=0;
+ while(pos=strpbrk(pos, delims)) {
+ if(helper.check_lang(pos)){
+ result.delim=*pos;
+ if(pos>*string_ref){
+ *pos=0;
result.append(helper.extract(*string_ref));
}
- *string_ref=v+1;
+ *string_ref=pos+1;
return result;
}
- pos=v+1;
+ pos++;
}
result.append(helper.extract(*string_ref));
*string_ref=0;
@@ -276,7 +278,6 @@ static void _create(Request& r, MethodPa
}
// data
- Temp_lang temp_lang(r, String::L_PASS_APPENDED);
StringSplitHelper sdata(r.process_to_string(params.as_junction(data_param_index, "body must be table or code")));
char *data=sdata.base;
@@ -362,12 +363,12 @@ static lsplit_result lsplit(char** strin
*write++=c;
}
- // we are no longer enclosed, searching for delimiter, skipping extra enclosers
+ // we are no longer enclosed, searching for delimiter
while(c=*read++) {
if(c==delims[0] || c==delims[1]) {
result.delim=c;
break;
- } else if(c!=encloser)
+ } else
*write++=c;
}
@@ -710,13 +711,13 @@ static void _csv_string(Request& r, Meth
table_to_csv(ost, table, control_chars, output_column_names);
- r.write_no_lang(*new VString(*new String(pa_strdup(ost.str().c_str()), String::L_CLEAN)));
+ r.write(*new VString(*new String(pa_strdup(ost.str().c_str()), String::L_CLEAN)));
#else
String sdata;
table_to_csv(sdata, table, control_chars, output_column_names);
- r.write_no_lang(*new VString(*new String(sdata.cstr(), String::L_CLEAN)));
+ r.write(*new VString(*new String(sdata.cstr(), String::L_CLEAN)));
#endif
}
@@ -736,12 +737,12 @@ static void _count(Request& r, MethodPar
} else
result = table.count();
- r.write_no_lang(*new VInt(result));
+ r.write(*new VInt(result));
}
static void _line(Request& r, MethodParams&) {
int result=1+GET_SELF(r, VTable).table().current();
- r.write_no_lang(*new VInt(result));
+ r.write(*new VInt(result));
}
static void _offset(Request& r, MethodParams& params) {
@@ -761,7 +762,7 @@ static void _offset(Request& r, MethodPa
int offset=params.as_int(params.count()-1, "offset must be expression", r);
table.offset(absolute, offset);
} else
- r.write_no_lang(*new VInt(table.current()));
+ r.write(*new VInt(table.current()));
}
static void _menu(Request& r, MethodParams& params) {
@@ -779,20 +780,20 @@ static void _menu(Request& r, MethodPara
for(size_t row=0; row
is_empty()) { // we have body
if(need_delim) // need delim & iteration produced string?
- r.write_pass_lang(r.process(*delim_maybe_code));
+ r.write(r.process(*delim_maybe_code));
else
need_delim=true;
}
- r.write_pass_lang(sv_processed);
+ r.write(sv_processed);
- if(lskip==Request::SKIP_BREAK)
+ if(skip.check_break())
break;
}
} else {
@@ -800,9 +801,8 @@ static void _menu(Request& r, MethodPara
table.set_current(row);
r.process_write(body_code);
- Request::Skip lskip=r.get_skip(); r.set_skip(Request::SKIP_NOTHING);
- if(lskip==Request::SKIP_BREAK)
+ if(r.check_skip_break())
break;
}
}
@@ -827,7 +827,7 @@ static void table_row_to_hash(Table::ele
const String* key;
if(info->key_code) {
info->table->set_current(info->row++); // change context row
- StringOrValue sv_processed=info->r->process(*info->key_code);
+ Value& sv_processed=info->r->process(*info->key_code);
key=&sv_processed.as_string();
} else {
key=info->key_fieldcount()?row->get(info->key_field):0;
@@ -882,7 +882,7 @@ static void table_row_to_hash(Table::ele
case C_CODE: {
if(!info->key_code)
info->table->set_current(info->row++); // change context row
- exist=info->hash->put_dont_replace(*key, &info->r->process(*info->value_code).as_value());
+ exist=info->hash->put_dont_replace(*key, &info->r->process(*info->value_code));
break;
}
}
@@ -936,7 +936,7 @@ static void _hash(Request& r, MethodPara
int valid_options=0;
if(Value* vdistinct_code=options->get(sql_distinct_name)) { // $.distinct ?
valid_options++;
- distinct=get_distinct(r.process_to_value(*vdistinct_code), value_type);
+ distinct=get_distinct(r.process(*vdistinct_code), value_type);
}
if(Value* vvalue_type_code=options->get(sql_value_type_name)) { // $.type ?
if(value_type==C_TABLE) // $.distinct[tables] already was specified
@@ -944,7 +944,7 @@ static void _hash(Request& r, MethodPara
if(value_type==C_CODE)
throw Exception(PARSER_RUNTIME, 0, "you can't specify $.type[] if value is code");
valid_options++;
- value_type=get_value_type(r.process_to_value(*vvalue_type_code));
+ value_type=get_value_type(r.process(*vvalue_type_code));
}
if(valid_options!=options->count())
@@ -985,8 +985,8 @@ static void _hash(Request& r, MethodPara
throw Exception(PARSER_RUNTIME, 0, "value field(s) must be string or table or code");
}
- if(value_type==C_STRING && value_fields.count()!=1)
- throw Exception(PARSER_RUNTIME, 0, "you can specify only one value field with option $.type[string]");
+ if(value_type==C_STRING && value_fields.count()>1)
+ throw Exception(PARSER_RUNTIME, 0, "you can't specify more then one value field with option $.type[string]");
{
Value* key_param=¶ms[0];
@@ -1012,7 +1012,7 @@ static void _hash(Request& r, MethodPara
}
}
}
- r.write_no_lang(result);
+ r.write(result);
}
#ifndef DOXYGEN
@@ -1043,9 +1043,7 @@ static int sort_cmp_double(const void *a
static void _sort(Request& r, MethodParams& params) {
Value& key_maker=params.as_junction(0, "key-maker must be code");
- bool reverse=params.count()>1/*..[desc|asc|]*/?
- reverse=params.as_no_junction(1, "order must not be code").as_string()=="desc":
- false; // default=asc
+ bool reverse=params.count()>1 /*..[desc|asc|]*/ && params.as_no_junction(1, "order must not be code").as_string()=="desc"; // default=asc
Table& old_table=GET_SELF(r, VTable).table();
Table& new_table=*new Table(old_table.columns());
@@ -1060,7 +1058,7 @@ static void _sort(Request& r, MethodPara
old_table.set_current(i);
// calculate key value
seq[i].row=old_table[i];
- Value& value=r.process_to_value(key_maker);
+ Value& value=r.process(key_maker);
if(i==0) // determining key values type by first one
key_values_are_strings=value.is_string();
@@ -1074,7 +1072,7 @@ static void _sort(Request& r, MethodPara
if(r.charsets.source().NAME()=="KOI8-R" && key_values_are_strings) {
for(i=0; ir->process_to_value(*info->expression_code).as_bool();
+ return info->r->process(*info->expression_code).as_bool();
}
static bool _locate_expression(Table& table, Request& r, MethodParams& params) {
@@ -1123,7 +1121,7 @@ static void _locate(Request& r, MethodPa
bool result=params[0].get_junction() || (params.count() == 1) ?
_locate_expression(table, r, params) :
_locate_name_value(table, r, params);
- r.write_no_lang(VBool::get(result));
+ r.write(VBool::get(result));
}
@@ -1141,14 +1139,14 @@ static void _flip(Request& r, MethodPara
new_table+=new_row;
}
- r.write_no_lang(*new VTable(&new_table));
+ r.write(*new VTable(&new_table));
}
static void _foreach(Request& r, MethodParams& params) {
InCycle temp(r);
- const String& rownum_name=params.as_string(0, "rownum-var name must be string");
- const String& value_name=params.as_string(1, "value-var name must be string");
+ const String* rownum_var_name=¶ms.as_string(0, "rownum-var name must be string");
+ const String* value_var_name=¶ms.as_string(1, "value-var name must be string");
Value& body_code=params.as_junction(2, "body must be code");
@@ -1157,8 +1155,8 @@ static void _foreach(Request& r, MethodP
Table& table=GET_SELF(r, VTable).table();
size_t saved_current=table.current();
- const String* rownum_var_name=rownum_name.is_empty()? 0 : &rownum_name;
- const String* value_var_name=value_name.is_empty()? 0 : &value_name;
+ rownum_var_name=rownum_var_name->is_empty()? 0 : rownum_var_name;
+ value_var_name=value_var_name->is_empty()? 0 : value_var_name;
Value* var_context=r.get_method_frame()->caller();
@@ -1172,20 +1170,20 @@ static void _foreach(Request& r, MethodP
if(value_var_name)
r.put_element(*var_context, *value_var_name, new VTable(&table));
- StringOrValue sv_processed=r.process(body_code);
- Request::Skip lskip=r.get_skip(); r.set_skip(Request::SKIP_NOTHING);
+ Value& sv_processed=r.process(body_code);
+ TempSkip4Delimiter skip(r);
const String* s_processed=sv_processed.get_string();
if(s_processed && !s_processed->is_empty()) { // we have body
if(need_delim) // need delim & iteration produced string?
- r.write_pass_lang(r.process(*delim_maybe_code));
+ r.write(r.process(*delim_maybe_code));
else
need_delim=true;
}
- r.write_pass_lang(sv_processed);
+ r.write(sv_processed);
- if(lskip==Request::SKIP_BREAK)
+ if(skip.check_break())
break;
}
} else {
@@ -1198,9 +1196,8 @@ static void _foreach(Request& r, MethodP
r.put_element(*var_context, *value_var_name, new VTable(&table));
r.process_write(body_code);
- Request::Skip lskip=r.get_skip(); r.set_skip(Request::SKIP_NOTHING);
- if(lskip==Request::SKIP_BREAK)
+ if(r.check_skip_break())
break;
}
}
@@ -1215,13 +1212,11 @@ inline Table::element_type row_from_stri
if(!param.is_string() && !param.get_junction())
throw Exception(PARSER_RUNTIME, 0, "row must be string, code or hash");
- Temp_lang temp_lang(r, String::L_PASS_APPENDED);
const String& string=r.process_to_string(param);
// parse cells
Table::element_type row=new ArrayString;
- size_t pos_after=0;
- string.split(*row, pos_after, "\t", String::L_AS_IS);
+ string.split(*row, 0, "\t", String::L_AS_IS);
return row;
}
@@ -1391,11 +1386,11 @@ static void _sql(Request& r, MethodParam
}
if(Value* vlimit=options->get(sql_limit_name)) {
valid_options++;
- limit=(ulong)r.process_to_value(*vlimit).as_double();
+ limit=(ulong)r.process(*vlimit).as_double();
}
if(Value* voffset=options->get(sql_offset_name)) {
valid_options++;
- offset=(ulong)r.process_to_value(*voffset).as_double();
+ offset=(ulong)r.process(*voffset).as_double();
}
if(valid_options!=options->count())
throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION);
@@ -1406,9 +1401,8 @@ static void _sql(Request& r, MethodParam
if(bind)
placeholders_count=marshal_binds(*bind, placeholders);
- Temp_lang temp_lang(r, String::L_SQL);
const String& statement_string=r.process_to_string(statement);
- const char* statement_cstr=statement_string.untaint_cstr(r.flang, r.connection());
+ const char* statement_cstr=statement_string.untaint_cstr(String::L_SQL, r.connection());
Table_sql_event_handlers handlers;
@@ -1450,7 +1444,7 @@ static void _columns(Request& r, MethodP
}
}
- r.write_no_lang(*new VTable(&result_table));
+ r.write(*new VTable(&result_table));
}
static void _select(Request& r, MethodParams& params) {
@@ -1467,15 +1461,15 @@ static void _select(Request& r, MethodPa
int valid_options=0;
if(Value* vlimit=options->get(sql_limit_name)) {
valid_options++;
- limit=r.process_to_value(*vlimit).as_int();
+ limit=r.process(*vlimit).as_int();
}
if(Value* voffset=options->get(sql_offset_name)) {
valid_options++;
- offset=r.process_to_value(*voffset).as_int();
+ offset=r.process(*voffset).as_int();
}
if(Value* vreverse=options->get(table_reverse_name)) {
valid_options++;
- reverse=r.process_to_value(*vreverse).as_bool();
+ reverse=r.process(*vreverse).as_bool();
}
if(valid_options!=options->count())
throw Exception(PARSER_RUNTIME, 0, CALLED_WITH_INVALID_OPTION);
@@ -1494,7 +1488,7 @@ static void _select(Request& r, MethodPa
for(size_t row=size-1; result_table.count() < (size_t)limit; row--) {
source_table.set_current(row);
- bool condition=r.process_to_value(vcondition, false/*don't intercept string*/).as_bool();
+ bool condition=r.process(vcondition).as_bool();
if(condition && ++appended > (size_t)offset) // ...condition is true, adding to the result
result_table+=source_table[row];
@@ -1504,7 +1498,7 @@ static void _select(Request& r, MethodPa
for(size_t row=0; row < size && result_table.count() < (size_t)limit; row++) {
source_table.set_current(row);
- bool condition=r.process_to_value(vcondition, false/*don't intercept string*/).as_bool();
+ bool condition=r.process(vcondition).as_bool();
if(condition && ++appended > (size_t)offset) // ...condition is true, adding to the result
result_table+=source_table[row];
@@ -1513,7 +1507,7 @@ static void _select(Request& r, MethodPa
source_table.set_current(saved_current);
}
- r.write_no_lang(*new VTable(&result_table));
+ r.write(*new VTable(&result_table));
}
// constructor