1 /* Copyright (C) 2000-2015 Lavtech.com corp. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18
19 #include "udm_config.h"
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/types.h>
25 #include <errno.h>
26
27 #include "udm_common.h"
28 #include "udm_utils.h"
29 #include "udm_vars.h"
30 #include "udm_result.h"
31 #include "udm_db.h"
32 #include "udm_env.h"
33 #include "udm_prog.h"
34
35
36 typedef struct
37 {
38 UDM_VALUE generic;
39 UDM_RESULT Result;
40 } UDM_VALUE_RESULT;
41
42
43 typedef struct
44 {
45 UDM_VAR_HEADER Header;
46 UDM_VALUE_RESULT Value;
47 } UDM_VAR_RESULT;
48
49
50 static udm_rc_t
UdmValueResultDump(const char * Data,const char * name,FILE * f)51 UdmValueResultDump(const char *Data, const char *name, FILE *f)
52 {
53 return UDM_NOTARGET;
54 }
55
56
57 static udm_var_flag_t
UdmValueResultFlags(const char * Data)58 UdmValueResultFlags(const char *Data)
59 {
60 return UDM_VARFLAG_READONLY;
61 }
62
63
64 static udm_secno_t
UdmValueResultSecno(const char * Data)65 UdmValueResultSecno(const char *Data)
66 {
67 return 0;
68 }
69
70
71 static size_t
UdmValueResultMemUsed(const char * Data)72 UdmValueResultMemUsed(const char *Data)
73 {
74 return sizeof(UDM_RESULT);
75 }
76
77
78 static void
UdmValueResultDestructor(char * Data)79 UdmValueResultDestructor(char *Data)
80 {
81 UDM_RESULT *Res= (UDM_RESULT *) Data;
82 UdmResultFree(Res);
83 }
84
85
86 static udm_rc_t
UdmValueResultCopy(char * D,const char * S)87 UdmValueResultCopy(char *D, const char *S)
88 {
89 UDM_ASSERT(0); /* TODO34: Add CloneVar(), with reference */
90 memmove(D, S, sizeof(UDM_RESULT));
91 return UDM_OK;
92 }
93
94
95 static udm_rc_t
UdmValueResultConstructor(char * Data,const UDM_VALUE ** args,size_t nargs)96 UdmValueResultConstructor(char *Data,
97 const UDM_VALUE **args, size_t nargs)
98 {
99 if (args && args[0] && args[0]->handler->datatype == UDM_VALUE_DATA_TYPE_ENV)
100 {
101 UDM_RESULT *Result;
102 if (!(Result= (UDM_RESULT *) UdmMalloc(sizeof(UDM_RESULT))))
103 return UDM_ERROR;
104 UdmResultInit(Result);
105 ((UDM_RESULT *) Data)[0]= Result[0];
106 }
107 else
108 {
109 UDM_BZERO(Data, sizeof(UDM_RESULT));
110 }
111 return UDM_OK;
112 }
113
114
115 static size_t
UdmValueResultVarSize(void)116 UdmValueResultVarSize(void)
117 {
118 return sizeof(UDM_VAR_RESULT);
119 }
120
121
122 static size_t
UdmValueResultValueSize(void)123 UdmValueResultValueSize(void)
124 {
125 return sizeof(UDM_VALUE_RESULT);
126 }
127
128
129 static size_t
UdmValueResultDataOffset(void)130 UdmValueResultDataOffset(void)
131 {
132 return offsetof(UDM_VALUE_RESULT, Result);
133 }
134
135
136 static size_t
UdmValueResultDataSize(void)137 UdmValueResultDataSize(void)
138 {
139 return sizeof(UDM_RESULT);
140 }
141
142
143 static size_t
UdmValueResultDataAlignment(void)144 UdmValueResultDataAlignment(void)
145 {
146 return sizeof(size_t);
147 }
148
149
150 static void
UdmValueResultGetConstStr(const char * Data,UDM_CONST_STR * Val)151 UdmValueResultGetConstStr(const char *Data, UDM_CONST_STR *Val)
152 {
153 static const UDM_CONST_STR name= {UDM_CSTR_WITH_LEN("#Result#")};
154 *Val= name;
155 }
156
157
158 static void
UdmValueResultGetBool(const char * Data,udm_bool_t * val)159 UdmValueResultGetBool(const char *Data, udm_bool_t *val)
160 {
161 *val= UDM_TRUE;
162 }
163
164
165 static void
UdmValueResultGetInt(const char * Data,int * val)166 UdmValueResultGetInt(const char *Data, int *val)
167 {
168 *val= 0;
169 }
170
171
172 static void
UdmValueResultGetUInt(const char * Data,unsigned int * val)173 UdmValueResultGetUInt(const char *Data, unsigned int *val)
174 {
175 *val= 0;
176 }
177
178
179 static void
UdmValueResultGetDouble(const char * Data,double * val)180 UdmValueResultGetDouble(const char *Data, double *val)
181 {
182 *val= 0.0;
183 }
184
185
186 static udm_rc_t
UdmValueResultSetInt(char * Data,int value)187 UdmValueResultSetInt(char *Data, int value)
188 {
189 return UDM_NOTARGET;
190 }
191
192
193 static udm_rc_t
UdmValueResultSetDouble(char * Data,double value)194 UdmValueResultSetDouble(char *Data, double value)
195 {
196 return UDM_NOTARGET;
197 }
198
199
200 static udm_rc_t
UdmValueResultConvertCharset(char * Data,UDM_CONV * conv,int flags)201 UdmValueResultConvertCharset(char *Data, UDM_CONV *conv, int flags)
202 {
203 return UDM_NOTARGET;
204 }
205
206
207 static udm_rc_t
UdmValueResultAppendStrn(char * Data,const char * str,size_t length)208 UdmValueResultAppendStrn(char *Data, const char *str, size_t length)
209 {
210 return UDM_NOTARGET;
211 }
212
213
214 static udm_rc_t
UdmValueResultSetStrn(char * Data,const char * str,size_t length)215 UdmValueResultSetStrn(char *Data, const char *str, size_t length)
216 {
217 return UDM_NOTARGET;
218 }
219
220
221 static udm_rc_t
UdmValueResultSetConv(char * Data,UDM_CONV * conv,int cnvflags,const char * src,size_t srclen)222 UdmValueResultSetConv(char *Data, UDM_CONV *conv, int cnvflags,
223 const char *src, size_t srclen)
224 {
225 return UDM_NOTARGET;
226 }
227
228
229 static udm_rc_t
UdmValueResultAppendConv(char * Data,size_t maxlen,UDM_CONV * cnv,int cnvflags,const char * src,size_t srclen)230 UdmValueResultAppendConv(char *Data, size_t maxlen,
231 UDM_CONV *cnv, int cnvflags,
232 const char *src, size_t srclen)
233 {
234 return UDM_NOTARGET;
235 }
236
237
238 static udm_rc_t
UdmValueResultPrintToFile(const char * Data,FILE * f)239 UdmValueResultPrintToFile(const char *Data, FILE *f)
240 {
241 return UDM_OK;
242 }
243
244
245 static udm_rc_t
UdmValueResultPrintToDSTR(const char * Data,UDM_DSTR * dstr)246 UdmValueResultPrintToDSTR(const char *Data, UDM_DSTR *dstr)
247 {
248 return UDM_OK;
249 }
250
251
252 static void
UdmResultMethodFind(UDM_PROG_EXECUTOR_STATE * state)253 UdmResultMethodFind(UDM_PROG_EXECUTOR_STATE *state)
254 {
255 UDM_RESULT *Result= (UDM_RESULT*) state->vreg[0].Data;
256 UDM_ENV *Env= ((UDM_ENV **) state->vreg[1].Data)[0];
257 const UDM_SECTION *Section= (const UDM_SECTION*) state->vreg[2].Data;
258 char str[256];
259 Env->errstr[0]= '\0';
260 Env->THDHandler= state->globals.THDHandler;
261 udm_snprintf(str, sizeof(str), "%.*s",
262 (int) UdmDSTRLength(&Section->Value), UdmDSTRPtr(&Section->Value));
263 /*
264 TODO34: if Env is reused for multiple queries, this UdmEnvPrepate()
265 will load ispell multiple times. Fix this to avoid multiple loading.
266 */
267 if (UDM_FUNC_RETURN_INT(state, UdmEnvPrepare(Env)))
268 return; /* Error, e.g. could not load ispell files */
269 UDM_FUNC_RETURN_INT(state, UdmEnvFind(Env, Result, str));
270 }
271
272 static UDM_VALUE_PROTOTYPE UdmResultMethodPrototypeFind[]=
273 {{&UdmValueHandlerResult},{&UdmValueHandlerEnv},{&UdmValueHandlerSimple}};
274
275
276 static void
UdmResultMethodTotalFound(UDM_PROG_EXECUTOR_STATE * state)277 UdmResultMethodTotalFound(UDM_PROG_EXECUTOR_STATE *state)
278 {
279 UDM_RESULT *Result= (UDM_RESULT*) state->vreg[0].Data;
280 UDM_FUNC_RETURN_INT(state, (int) UdmResultTotalFound(Result));
281 }
282
283 static void
UdmResultMethodFirst(UDM_PROG_EXECUTOR_STATE * state)284 UdmResultMethodFirst(UDM_PROG_EXECUTOR_STATE *state)
285 {
286 UDM_RESULT *Result= (UDM_RESULT*) state->vreg[0].Data;
287 UDM_FUNC_RETURN_INT(state, (int) UdmResultFirst(Result));
288 }
289
290 static void
UdmResultMethodLast(UDM_PROG_EXECUTOR_STATE * state)291 UdmResultMethodLast(UDM_PROG_EXECUTOR_STATE *state)
292 {
293 UDM_RESULT *Result= (UDM_RESULT*) state->vreg[0].Data;
294 UDM_FUNC_RETURN_INT(state, (int) UdmResultLast(Result));
295 }
296
297 static void
UdmResultMethodNumRows(UDM_PROG_EXECUTOR_STATE * state)298 UdmResultMethodNumRows(UDM_PROG_EXECUTOR_STATE *state)
299 {
300 UDM_RESULT *Result= (UDM_RESULT*) state->vreg[0].Data;
301 UDM_FUNC_RETURN_INT(state, (int) UdmResultNumRows(Result));
302 }
303
304
305 static void
UdmResultMethodNumWords(UDM_PROG_EXECUTOR_STATE * state)306 UdmResultMethodNumWords(UDM_PROG_EXECUTOR_STATE *state)
307 {
308 UDM_RESULT *Result= (UDM_RESULT*) state->vreg[0].Data;
309 UDM_FUNC_RETURN_INT(state, (int) Result->WWList.nwords);
310 }
311
312
313 static void
UdmResultMethodNumUniqWords(UDM_PROG_EXECUTOR_STATE * state)314 UdmResultMethodNumUniqWords(UDM_PROG_EXECUTOR_STATE *state)
315 {
316 UDM_RESULT *Result= (UDM_RESULT*) state->vreg[0].Data;
317 UDM_FUNC_RETURN_INT(state, (int) Result->WWList.nuniq);
318 }
319
320
321 static udm_rc_t
UdmResultPropertyAppendHilight(UDM_DSTR * dst,UDM_CHARSET * cs,const UDM_CONST_STR * str,const char * hlbeg,size_t hlbeglen,const char * hlend,size_t hlendlen)322 UdmResultPropertyAppendHilight(UDM_DSTR *dst,
323 UDM_CHARSET *cs,
324 const UDM_CONST_STR *str,
325 const char *hlbeg, size_t hlbeglen,
326 const char *hlend, size_t hlendlen)
327 {
328 UDM_DSTR tmp;
329 UDM_CONV cnv;
330 UdmConvInit(&cnv, cs, cs);
331 UdmDSTRInit(&tmp, 128);
332 UdmDSTRAppendConv(&tmp, &cnv, str->str, str->length, UDM_RECODE_HTML);
333 UdmDSTRAppendHighlight(dst, UdmDSTRPtr(&tmp), UdmDSTRLength(&tmp),
334 hlbeg, hlbeglen, hlend, hlendlen);
335 UdmDSTRFree(&tmp);
336 return UDM_OK;
337 }
338
339
340 static UDM_VALUE *
UdmVarListFindValueByDSTR(UDM_VARLIST * Vars,const UDM_DSTR * str)341 UdmVarListFindValueByDSTR(UDM_VARLIST *Vars, const UDM_DSTR *str)
342 {
343 char name[128];
344 udm_snprintf(name, sizeof(name), "%.*s",
345 (int) UdmDSTRLength(str), UdmDSTRPtr(str));
346 return UdmVarListFindValue(Vars, name);
347 }
348
349
350 static void
UdmResultMethodWord(UDM_PROG_EXECUTOR_STATE * state)351 UdmResultMethodWord(UDM_PROG_EXECUTOR_STATE *state)
352 {
353 UDM_RESULT *Result= (UDM_RESULT *) state->vreg[0].Data;
354 int pos= ((int *) state->vreg[1].Data)[0];
355 void *ret= UdmProgExecutorStateSetupReturnValue(state, &UdmValueHandlerQueryWord);
356 if (pos < 0 || (size_t) pos >= Result->WWList.nwords)
357 return;
358 state->fatal_error= UdmValueHandlerQueryWord.Copy(ret,
359 (char *) &Result->WWList.Word[pos]);
360 }
361
362
363 static void
UdmResultMethodPropertyCommon(UDM_PROG_EXECUTOR_STATE * state,UDM_SECTION * ReturnValue,UDM_VARLIST * Vars,UDM_SECTION * Property,UDM_CHARSET * cs,udm_bool_t html,const char * hlbeg,size_t hlbeglen,const char * hlend,size_t hlendlen)364 UdmResultMethodPropertyCommon(UDM_PROG_EXECUTOR_STATE *state,
365 UDM_SECTION *ReturnValue,
366 UDM_VARLIST *Vars, UDM_SECTION *Property,
367 UDM_CHARSET *cs, udm_bool_t html,
368 const char *hlbeg, size_t hlbeglen,
369 const char *hlend, size_t hlendlen)
370 {
371 UDM_CONST_STR str;
372 UDM_VALUE *Value;
373 if (!(Value= UdmVarListFindValueByDSTR(Vars, &Property->Value)))
374 return;
375 Value->handler->GetConstStr(UdmValueDataPtr(Value), &str);
376 state->fatal_error= html ?
377 UdmResultPropertyAppendHilight(&ReturnValue->Value, cs, &str,
378 hlbeg, hlbeglen,
379 hlend, hlendlen) :
380 UdmDSTRAppendRemoveHiLight(&ReturnValue->Value, str.str, str.length);
381 }
382
383
384 static void
UdmResultMethodDocumentPropertyInternal(UDM_PROG_EXECUTOR_STATE * state,udm_bool_t html,const char * hlbeg,size_t hlbeglen,const char * hlend,size_t hlendlen)385 UdmResultMethodDocumentPropertyInternal(UDM_PROG_EXECUTOR_STATE *state,
386 udm_bool_t html,
387 const char *hlbeg, size_t hlbeglen,
388 const char *hlend, size_t hlendlen)
389 {
390 UDM_RESULT *Result= (UDM_RESULT *) state->vreg[0].Data;
391 int pos= ((int *) state->vreg[1].Data)[0];
392 UDM_SECTION *Property= (UDM_SECTION *) state->vreg[2].Data;
393 UDM_SECTION *ret= UdmProgExecutorStateSetupReturnValue(state, &UdmValueHandlerSimple);
394 if (pos < 0 || (size_t) pos >= Result->num_rows)
395 return;
396 UdmResultMethodPropertyCommon(state, ret, &Result->Doc[pos].Sections,
397 Property,
398 Result->Doc[pos].lcs, html,
399 hlbeg, hlbeglen, hlend, hlendlen);
400 }
401
402
403 static void
UdmResultMethodPropertyInternal(UDM_PROG_EXECUTOR_STATE * state,UDM_CHARSET * cs,udm_bool_t html,const char * hlbeg,size_t hlbeglen,const char * hlend,size_t hlendlen)404 UdmResultMethodPropertyInternal(UDM_PROG_EXECUTOR_STATE *state,
405 UDM_CHARSET *cs,
406 udm_bool_t html,
407 const char *hlbeg, size_t hlbeglen,
408 const char *hlend, size_t hlendlen)
409 {
410 UDM_RESULT *Result= (UDM_RESULT *) state->vreg[0].Data;
411 UDM_SECTION *Property= (UDM_SECTION *) state->vreg[1].Data;
412 UDM_SECTION *ret= UdmProgExecutorStateSetupReturnValue(state, &UdmValueHandlerSimple);
413 UdmResultMethodPropertyCommon(state, ret, &Result->Vars,
414 Property, cs, html,
415 hlbeg, hlbeglen, hlend, hlendlen);
416 }
417
418
419 static void
UdmResultMethodDocumentProperty(UDM_PROG_EXECUTOR_STATE * state)420 UdmResultMethodDocumentProperty(UDM_PROG_EXECUTOR_STATE *state)
421 {
422 UdmResultMethodDocumentPropertyInternal(state, UDM_FALSE, "", 0, "", 0);
423 }
424
425
426 static void
UdmResultMethodDocumentPropertyHtml(UDM_PROG_EXECUTOR_STATE * state)427 UdmResultMethodDocumentPropertyHtml(UDM_PROG_EXECUTOR_STATE *state)
428 {
429 UdmResultMethodDocumentPropertyInternal(state, UDM_TRUE, "", 0, "", 0);
430 }
431
432
433 static void
UdmResultMethodDocumentPropertyHtml5(UDM_PROG_EXECUTOR_STATE * state)434 UdmResultMethodDocumentPropertyHtml5(UDM_PROG_EXECUTOR_STATE *state)
435 {
436 UDM_SECTION *HlBeg= (UDM_SECTION *) state->vreg[3].Data;
437 UDM_SECTION *HlEnd= (UDM_SECTION *) state->vreg[4].Data;
438 UdmResultMethodDocumentPropertyInternal(state, UDM_TRUE,
439 UdmDSTRPtr(&HlBeg->Value),
440 UdmDSTRLength(&HlBeg->Value),
441 UdmDSTRPtr(&HlEnd->Value),
442 UdmDSTRLength(&HlEnd->Value));
443 }
444
445
446 static void
UdmResultMethodProperty(UDM_PROG_EXECUTOR_STATE * state)447 UdmResultMethodProperty(UDM_PROG_EXECUTOR_STATE *state)
448 {
449 UdmResultMethodPropertyInternal(state, &udm_charset_latin1, UDM_FALSE,
450 "", 0, "", 0);
451 }
452
453
454 static UDM_VALUE_PROTOTYPE UdmValuePrototypeThis[]= {{&UdmValueHandlerResult}};
455
456
457 static UDM_VALUE_PROTOTYPE UdmValuePrototypeResultString[]=
458 {{&UdmValueHandlerResult},
459 {&UdmValueHandlerSimple},
460 };
461
462
463 static UDM_VALUE_PROTOTYPE UdmValuePrototypeResultIntString[]=
464 {{&UdmValueHandlerResult},
465 {&UdmValueHandlerInt},
466 {&UdmValueHandlerSimple},
467 {&UdmValueHandlerSimple},
468 {&UdmValueHandlerSimple},
469 };
470
471
472 static const UDM_FUNCTION ResultMethods[]=
473 {
474 {{UDM_CSTR_WITH_LEN("find")},
475 {{&UdmValueHandlerInt}, 3, UdmResultMethodPrototypeFind},
476 UdmResultMethodFind},
477 {{UDM_CSTR_WITH_LEN("total_found")},
478 {{&UdmValueHandlerInt}, 1, UdmValuePrototypeThis},
479 UdmResultMethodTotalFound},
480 {{UDM_CSTR_WITH_LEN("first")},
481 {{&UdmValueHandlerInt}, 1, UdmValuePrototypeThis},
482 UdmResultMethodFirst},
483 {{UDM_CSTR_WITH_LEN("last")},
484 {{&UdmValueHandlerInt}, 1, UdmValuePrototypeThis},
485 UdmResultMethodLast},
486 {{UDM_CSTR_WITH_LEN("num_rows")},
487 {{&UdmValueHandlerInt}, 1, UdmValuePrototypeThis},
488 UdmResultMethodNumRows},
489 {{UDM_CSTR_WITH_LEN("num_words")},
490 {{&UdmValueHandlerInt}, 1, UdmValuePrototypeThis},
491 UdmResultMethodNumWords},
492 {{UDM_CSTR_WITH_LEN("num_uniq_words")},
493 {{&UdmValueHandlerInt}, 1, UdmValuePrototypeThis},
494 UdmResultMethodNumUniqWords},
495 {{UDM_CSTR_WITH_LEN("document_property")},
496 {{&UdmValueHandlerSimple}, 3, UdmValuePrototypeResultIntString},
497 UdmResultMethodDocumentProperty},
498 {{UDM_CSTR_WITH_LEN("document_property_html")},
499 {{&UdmValueHandlerSimple}, 3, UdmValuePrototypeResultIntString},
500 UdmResultMethodDocumentPropertyHtml},
501 {{UDM_CSTR_WITH_LEN("document_property_html")},
502 {{&UdmValueHandlerSimple}, 5, UdmValuePrototypeResultIntString},
503 UdmResultMethodDocumentPropertyHtml5},
504 {{UDM_CSTR_WITH_LEN("property")},
505 {{&UdmValueHandlerSimple}, 2, UdmValuePrototypeResultString},
506 UdmResultMethodProperty},
507 {{UDM_CSTR_WITH_LEN("word")},
508 {{&UdmValueHandlerQueryWord}, 2, UdmValuePrototypeResultIntString},
509 UdmResultMethodWord},
510 {{0,0}, {{NULL}, 0, NULL}, NULL}
511 };
512
513
514 UDM_VALUE_HANDLER UdmValueHandlerResult=
515 {
516 UDM_VALUE_HANDLER_TYPE_RESULT,
517 UDM_VALUE_DATA_TYPE_RESULT,
518 UDM_VALUE_DATA_TYPE_STR,
519 "RESULT",
520 UdmValueResultConstructor,
521 UdmValueResultDestructor,
522 UdmValueResultCopy,
523 UdmValueResultVarSize,
524 UdmValueResultValueSize,
525 UdmValueResultDataOffset,
526 UdmValueResultDataSize,
527 UdmValueResultDataAlignment,
528 UdmValueResultDump,
529 UdmValueResultFlags,
530 UdmValueResultSecno,
531 UdmValueResultMemUsed,
532 UdmValueResultGetConstStr,
533 UdmValueResultGetBool,
534 UdmValueResultGetInt,
535 UdmValueResultGetUInt,
536 UdmValueResultGetDouble,
537 UdmValueResultSetInt,
538 UdmValueResultSetDouble,
539 UdmValueResultSetStrn,
540 UdmValueResultPrintToFile,
541 UdmValueResultPrintToDSTR,
542 UdmValueResultConvertCharset,
543 UdmValueResultSetConv,
544 UdmValueResultAppendStrn,
545 UdmValueResultAppendConv,
546 ResultMethods,
547 };
548