Annotation of parser3/src/classes/table.C, revision 1.19
1.1 paf 1: /*
2: Parser
3: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
4: Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
5:
1.19 ! paf 6: $Id: table.C,v 1.18 2001/03/19 20:07:35 paf Exp $
1.1 paf 7: */
8:
1.16 paf 9: #include "pa_common.h"
1.1 paf 10: #include "pa_request.h"
11: #include "_table.h"
12: #include "pa_vtable.h"
1.6 paf 13: #include "pa_vint.h"
1.1 paf 14:
15: // global var
16:
1.14 paf 17: VStateless_class *table_class;
1.1 paf 18:
19: // methods
20:
1.2 paf 21: static void set_or_load(
22: Request& r,
23: const String& method_name, Array *params,
24: bool is_load) {
1.1 paf 25: Pool& pool=r.pool();
26: // data is last parameter
27: Value *vdata=static_cast<Value *>(params->get(params->size()-1));
1.4 paf 28: // forcing
1.19 ! paf 29: // ^load{this body type}
1.17 paf 30: // ^set{this body type}
1.19 ! paf 31: r.fail_if_junction_(false, *vdata, method_name, "body must be junction");
1.1 paf 32:
1.2 paf 33: // data or file_name
1.17 paf 34: char *data_or_filename;
35: {
1.19 ! paf 36: Temp_lang temp_lang(r,
! 37: is_load ? String::Untaint_lang::FILE : String::Untaint_lang::TABLE);
1.17 paf 38: data_or_filename=r.process(*vdata).as_string().cstr();
39: }
1.2 paf 40: // data
41: char *data=is_load?file_read(pool, r.absolute(data_or_filename)):data_or_filename;
1.1 paf 42:
43: // parse columns
44: Array *columns;
45: #ifndef NO_STRING_ORIGIN
46: const Origin& origin=method_name.origin();
1.2 paf 47: const char *file=origin.file;
1.1 paf 48: uint line=origin.line;
49: #endif
50: if(params->size()==2) {
51: columns=0;
52: } else {
53: columns=new(pool) Array(pool);
54:
55: if(char *row_chars=getrow(&data))
56: do {
57: String *name=new(pool) String(pool);
58: name->APPEND(lsplit(&row_chars, '\t'), 0, file, line++);
59: *columns+=name;
60: } while(row_chars);
61: }
62:
63: // parse cells
64: Table& table=*new(pool) Table(pool, method_name, columns);
65: char *row_chars;
66: while(row_chars=getrow(&data)) {
67: Array *row=new(pool) Array(pool);
68: while(char *cell_chars=lsplit(&row_chars, '\t')) {
69: String *cell=new(pool) String(pool);
70: cell->APPEND(cell_chars, 0, file, line);
71: *row+=cell;
72: }
73: line++;
74: table+=row;
75: };
76:
77: // replace any previous table value
1.18 paf 78: static_cast<VTable *>(r.self)->set_table(table);
1.1 paf 79: }
80:
1.2 paf 81:
82: static void _set(Request& r, const String& method_name, Array *params) {
83: set_or_load(r, method_name, params, false);
84: }
85:
86: static void _load(Request& r, const String& method_name, Array *params) {
87: set_or_load(r, method_name, params, true);
88: }
89:
1.6 paf 90: static void _count(Request& r, const String&, Array *) {
91: Pool& pool=r.pool();
1.18 paf 92: Value& value=*new(pool) VInt(pool, static_cast<VTable *>(r.self)->table().size());
1.15 paf 93: r.write_no_lang(value);
1.6 paf 94: }
95:
96: static void _line(Request& r, const String&, Array *) {
97: Pool& pool=r.pool();
1.18 paf 98: Value& value=*new(pool) VInt(pool, 1+static_cast<VTable *>(r.self)->table().get_current());
1.15 paf 99: r.write_no_lang(value);
1.6 paf 100: }
101:
102: static void _offset(Request& r, const String&, Array *params) {
103: Pool& pool=r.pool();
1.18 paf 104: Table& table=static_cast<VTable *>(r.self)->table();
1.6 paf 105: if(params->size()) {
106: if(int size=table.size()) {
1.9 paf 107: int offset=
108: (int)r.process(*static_cast<Value *>(params->get(0))).get_double();
1.6 paf 109: table.set_current((table.get_current()+offset+size)%size);
110: }
111: } else {
112: Value& value=*new(pool) VInt(pool, table.get_current());
1.15 paf 113: r.write_no_lang(value);
1.6 paf 114: }
115: }
116:
1.7 paf 117: static void _menu(Request& r, const String& method_name, Array *params) {
118: Value& body_code=*static_cast<Value *>(params->get(0));
119: // forcing ^menu{this param type}
120: r.fail_if_junction_(false, body_code,
121: method_name, "body must be junction");
122:
123: Value *delim_code=params->size()==2?static_cast<Value *>(params->get(1)):0;
124:
1.18 paf 125: Table& table=static_cast<VTable *>(r.self)->table();
1.7 paf 126: bool need_delim=false;
127: for(int i=0; i<table.size(); i++) {
128: table.set_current(i);
129:
1.12 paf 130: Value& processed_body=r.process(body_code);
1.7 paf 131: if(delim_code) { // delimiter set?
132: const String *string=processed_body.get_string();
133: if(need_delim && string && string->size()) // need delim & iteration produced string?
134: r.write_pass_lang(r.process(*delim_code));
135: need_delim=true;
136: }
137: r.write_pass_lang(processed_body);
138: }
139: }
140:
1.8 paf 141: static void _empty(Request& r, const String&, Array *params) {
1.18 paf 142: Table& table=static_cast<VTable *>(r.self)->table();
1.8 paf 143: if(table.size()==0) {
144: Value& value=r.process(*static_cast<Value *>(params->get(0)));
145: r.write_pass_lang(value);
146: } else if(params->size()==2) {
147: Value& value=r.process(*static_cast<Value *>(params->get(1)));
148: r.write_pass_lang(value);
149: }
150: }
1.15 paf 151:
152: // initialize
1.8 paf 153:
1.14 paf 154: void initialize_table_class(Pool& pool, VStateless_class& vclass) {
1.10 paf 155: // ^table.set[data]
156: // ^table.set[nameless;data]
1.1 paf 157: vclass.add_native_method("set", _set, 1, 2);
1.2 paf 158:
1.10 paf 159: // ^table.load[file]
160: // ^table.load[nameless;file]
1.2 paf 161: vclass.add_native_method("load", _load, 1, 2);
1.6 paf 162:
163: // ^table.count[]
164: vclass.add_native_method("count", _count, 0, 0);
165:
166: // ^table.line[]
167: vclass.add_native_method("line", _line, 0, 0);
168:
1.10 paf 169: // ^table.offset[]
170: // ^table.offset[offset]
1.6 paf 171: vclass.add_native_method("offset", _offset, 0, 1);
1.7 paf 172:
1.10 paf 173: // ^table.menu{code}
174: // ^table.menu{code}[delim]
1.7 paf 175: vclass.add_native_method("menu", _menu, 1, 2);
1.8 paf 176:
1.10 paf 177: // ^table.empty{code-when-empty}
178: // ^table.empty{code-when-empty}{code-when-not}
1.8 paf 179: vclass.add_native_method("empty", _empty, 1, 2);
180:
1.1 paf 181: }
E-mail: