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