Annotation of parser3/src/classes/table.C, revision 1.17
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.17 ! paf 6: $Id: table.C,v 1.16 2001/03/19 16:06:13 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.17 ! paf 29: // ^load[this body type]
! 30: // ^set{this body type}
! 31: r.fail_if_junction_(is_load, *vdata,
! 32: method_name, is_load?"body must not be junction":"body must be junction");
1.1 paf 33:
1.2 paf 34: // data or file_name
1.17 ! paf 35: char *data_or_filename;
! 36: {
! 37: Temp_lang temp_lang(r, String::Untaint_lang::TABLE);
! 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
78: r.self->as_vtable().set_table(table);
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();
92: Value& value=*new(pool) VInt(pool, r.self->as_vtable().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();
98: Value& value=*new(pool) VInt(pool, 1+r.self->as_vtable().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();
104: Table& table=r.self->as_vtable().table();
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:
125: Table& table=r.self->as_vtable().table();
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) {
142: Table& table=r.self->as_vtable().table();
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: