root/tags/5.4.pre05/wxis_src/xis_exec.c

Revision 1, 162.5 kB (checked in by heitor.barbieri, 4 years ago)

Criação do svn para Cisis.

Line 
1/* -------------------------------------------------------------- XIS_EXEC.C */
2
3/* ---------------------------------------------------------- C HEADER FILES */
4#include <stdlib.h>
5#include <stdio.h>
6#include <string.h>
7#include <ctype.h>
8#include <time.h>
9#include <errno.h>
10/* ------------------------------------------------------------ HEADER FILES */
11#include "../cisis.h"
12#include "citpv.h"
13#include "easyfc.h"
14#include "easyci.h"
15#include "cgilist.h"
16#include "xis_comp.h"
17#include "freqlist.h"
18#include "cimsrt.h"
19#include "hlfill.h"
20#include "cixml.h"
21#include "xis_exec.h"
22/* ------------------------------------------------------------------ define */
23#if CIFFI
24//#define EXE_REC_SIZE       2*1100000L /*1048576L*/ /*4194304L*/ /* defult record size */
25//#define EXE_BUFF_SIZE      2*1100000L /*4194304L*/ /*1025000L*/ /* defult buffer size */
26#define EXE_REC_SIZE       (rec_maxmfrl) /*1048576L*/ /*4194304L*/ /* defult record size */
27#define EXE_BUFF_SIZE      (rec_maxmfrl) /*4194304L*/ /*1025000L*/ /* defult buffer size */
28#else
29//#define EXE_REC_SIZE       (32L*KBYTE)    /* defult record size */
30//#define EXE_BUFF_SIZE      (32L*KBYTE)    /* defult buffer size */
31#define EXE_REC_SIZE       (rec_maxmfrl)    /* defult record size */
32#define EXE_BUFF_SIZE      (rec_maxmfrl)    /* defult buffer size */
33#endif
34#define SEARCH_AUX_SIZE    (64L*KBYTE)    /* defult search record size */
35#define SEARCH_PREFIX_SIZE (4L*KBYTE)     /* defult search prefix record size */
36/*#define DEFAULT_MAXLK      1024L          /* default maximum link generation */
37#define DEFAULT_MAXLK      102400L        /* default maximum link generation - Visalegis set/05 */
38#define MINIMUM_MAXLK      100L           /* lower value maximum link generation */
39#define FULLINV_TAG_KEY    1              /* extract key field number */
40#define DEFAULT_KEYLENGTH  512L           /* default master sort key length */
41#define CI_TMPNAM          256            /* cisis temporary file name size */
42#if !CIB71
43#define b7_CIB7             void
44#endif /* CIB71 */
45
46#ifndef MAXNDBX
47#define   MAXNDBX    2048L      /* maximum #entries             */
48#endif
49#ifndef MAXNREC
50#define   MAXNREC     256L      /* maximum #entries             */
51#endif
52#ifndef MAXNTRM
53#define   MAXNTRM     256L      /* maximum #entries             */
54#endif
55
56#define SRC_TMP_FILE 0                   /* create cisis temporary file */
57
58
59OUT_BUFFER *outBuffer;
60
61/* ------------------------------------------------------------- enumeration */
62typedef enum {
63   PARM_0,
64   PARM_ACTAB,
65   PARM_BUFFERSIZE,
66   PARM_CIPAR,
67   PARM_COUNT,
68   PARM_DB,
69   PARM_DECOD,
70   PARM_DELIMITER,
71   PARM_EXPIRE,
72   PARM_EXPRESSION,
73   PARM_FILE,
74   PARM_FREQSUM,
75   PARM_FROM,
76   PARM_FST,
77   PARM_GIZMO,
78   PARM_INDEXLIST,
79   PARM_KEY,
80   PARM_KEYFIELD,
81   PARM_KEYLENGTH,
82   PARM_KEYS,
83   PARM_KEYSDB,
84   PARM_LOCKID,
85   PARM_MAXLK,
86   PARM_MFN,
87   PARM_POSTING,
88   PARM_POSTTAG,
89   PARM_PREFIX,
90   PARM_RESET,
91   PARM_REVERSE,
92   PARM_SORT,
93   PARM_STW,
94   PARM_SUFFIX,
95   PARM_TASK,
96   PARM_TO,
97   PARM_TYPE,
98   PARM_UCTAB,
99   /* 27.Nov.2000 */
100   PARM_PREFIX_HTMLPFT,
101   PARM_SUFFIX_HTMLPFT,
102   /* 28.Nov.2000 */
103   PARM_FIRST_LINE,
104   /* 22.Feb.2001 */
105   PARM_ISISXML_STYLE,
106   PARM_ISISXML_TABLE,
107   /* 05.Apr.2001 */
108   PARM_LOG,
109
110   PARM_LIST_QTT
111} PARM_LIST;               /* parameter option */
112
113typedef enum {
114   PRECISE_BR,
115   PRECISE_CURRENT,
116   PRECISE_ERRORINFO,
117   PRECISE_FROM,
118   PRECISE_GETNEW,
119   PRECISE_HLINE,
120   PRECISE_KEYS,
121   PRECISE_ISO2709,
122   PRECISE_ISO2709_CRLF,
123   PRECISE_ITEM,
124   PRECISE_ITENS,
125   PRECISE_ITEMS,
126   PRECISE_KEY,
127   PRECISE_LOCK,
128   PRECISE_MFN,
129   PRECISE_NEW,
130   PRECISE_NEXT,
131   PRECISE_OFF,
132   PRECISE_ON,
133   PRECISE_POSTING,
134   PRECISE_POSTINGS,
135   PRECISE_QUIT,
136   PRECISE_RECSTAT,
137   PRECISE_RLINE,
138   PRECISE_STATUS,
139   PRECISE_TABLE,
140   PRECISE_TO,
141   PRECISE_TOTAL,
142   PRECISE_MARC21,
143   PRECISE_VALUE,
144   PRECISE_VLINE,
145   PRECISE_WDELETE,
146   PRECISE_WLOCK,
147   PRECISE_WNOUNLOCK,
148   PRECISE_WUNLOCK,
149
150   /* 05.Apr.2001 */
151   PRECISE_SETNUMBER,
152
153   PRECISE_LIST_QTT
154} PRECISE_LIST;               /* precise option */
155
156typedef enum {
157   TRACE_SEPARATOR,
158   TRACE_CMD,
159   TRACE_TEXT,
160   TRACE_LIST_QTT
161} TRACE_PART;                 /* trace part to be shown */
162
163typedef enum {
164   SEARCH_ERROR_OK,
165   SEARCH_ERROR_ALLOC,
166   SEARCH_ERROR_SYNTAX,
167   SEARCH_ERROR_RUN,
168   SEARCH_ERROR_LIST_QTT
169} SEARCH_ERROR;               /* search error */
170
171typedef enum {
172   LOCK_ERROR_OK,             /* lock operation succeed */
173   LOCK_ERROR_DE_DENIED,      /* data entry lock refused */
174   LOCK_ERROR_R_DENIED,       /* record lock refused */
175   LOCK_ERROR_U_DENIED,       /* record identification update refused */
176   LOCK_ERROR_NOT_LOCKED,     /* record not locked */
177   LOCK_ERROR_ID_DENIED,      /* lock identification does not match */
178   LOCK_ERROR_IU_DENIED,      /* record inverted update refused */
179   LOCK_ERROR_NOT_EXPIRED,    /* elapse time was not reached */
180   LOCK_ERROR_EW_DENIED,      /* exclusive write lock refused */
181   LOCK_ERROR_LIST_QTT        /* quantity of lock return codes */
182} LOCK_ERROR;                 /* lock error */
183/* --------------------------------------------------------------- structure */
184typedef struct {
185   FMT_CODE *code;
186   CIXML_STRUCT *ciXml;
187   char *text;
188} EXE_FORMAT;                 /* format */
189
190typedef struct {
191   int tag;
192   BOOLEAN apply;
193   char *text;
194   long value;
195} SCOPE_DEFINE;               /* scope define */
196
197typedef struct {
198   CPL_COMMAND *father;
199   long idxPrev;
200   long idxRetn;
201   long idxCurr;
202   char *parmList[PARM_LIST_QTT];
203   SCOPE_DEFINE defineList[PRECISE_LIST_QTT];
204   PRECISE_LIST skip;
205   CPL_COMMAND *jump;
206   FILE *export;
207   PRECISE_LIST exportType;
208   char *stwTable;
209} SCOPE_VAR;                  /* scope variables */
210
211typedef struct {
212   CPL_STRUCT *program;
213   CGI_PARAM *cgiList;
214   CPL_ATVALUE trace;
215   int scope;
216   FREQLIST_VAR freq;
217   char *buff;
218   FILE *output;
219   long buffSize;
220} EXE_VAR;                    /* execution variables */
221
222typedef struct {
223   long idxHit;
224   long idxPfx;
225   char tempFile[CI_TMPNAM];
226   char *dbLog;
227    b7_CIB7 *cib7p;
228} SEARCH_VAR;                 /* search variables */
229/* ---------------------------------------------------------------- external */
230extern char fmterrxy[];                                     /* cifm3.c */
231#if !CIB71
232int b5_deltmp(int fd, char *tmpnamp);                       /* cib62.c */
233#endif /* CIB71 */
234extern CPL_IDENTIFIER cplElement[ELEMENT_LIST_QTT];         /* xis_comp.c */
235extern CPL_IDENTIFIER cplAttribute[ATTRIBUTE_LIST_QTT];     /* xis_comp.c */
236extern CPL_IDENTIFIER cplAtValue[ATVALUE_LIST_QTT];         /* xis_comp.c */
237/* --------------------------------------------------------------- recursive */
238char *exeText(EXE_VAR *exeVar,SCOPE_VAR *scopeVar,long idxCurr,CPL_COMMAND *cmd);
239void  exeGo  (EXE_VAR *exeVar,SCOPE_VAR *scopeVar,CPL_COMMAND *cmd);
240/* ------------------------------------------------------------------ global */
241char *preciseList[PRECISE_LIST_QTT];   /* precise defines and values list */
242PARM_LIST atValueParm[ATVALUE_LIST_QTT];  /* attribute value relate parm value */
243long b5msg_idx = -1L;                  /* auxiliary search message index */
244int b5msg_tag = 0;                     /* auxiliary search message tag */
245unsigned char exeUctab[256] = {        /* upper case character table (ANSI) */
246     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
247    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
248    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
249    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
250    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
251    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
252    96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
253    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127,
254   128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
255   144, 39, 39,147,148,149,150,151,152,153,154,155,156,157,158,159,
256   160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
257   176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
258    65, 65, 65, 65, 65, 65, 65, 67, 69, 69, 69, 69, 73, 73, 73, 73,
259   208, 78, 79, 79, 79, 79, 79,215, 48, 85, 85, 85, 85, 89,222,223,
260    65, 65, 65, 65, 65, 65,230, 67, 69, 69, 69, 69, 73, 73, 73, 73,
261   240, 78, 79, 79, 79, 79, 79,247, 48, 85, 85, 85, 85, 89,254, 89
262};
263unsigned char exeActab[] = {           /* alphabetic character table (ANSI) */
264    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70,
265    71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
266    87, 88, 89, 90, 97, 98, 99,100,101,102,103,104,105,106,107,108,
267   109,110,111,112,113,114,115,116,117,118,119,120,121,122,192,193,
268   194,195,196,197,199,200,201,202,203,204,205,206,207,209,210,211,
269   212,213,214,216,217,218,219,220,221,224,225,226,227,228,229,231,
270   232,233,234,235,236,237,238,239,241,242,243,244,245,246,248,249,
271   250,251,252,253,255,  0
272};
273
274/* ================================================================ exeError */
275EXE_ERROR exeError(CPL_STRUCT *program,      /* program structure */
276                   EXE_ERROR errorCode,      /* error code */
277                   char *text)               /* complement message text */
278{
279
280   /* Set error code and complement text information */
281   program->error.code = errorCode;
282   if (text) sprintf(program->error.info,"%-.*s",EFC_ERROR_INFO_MAX,text);
283
284   /* Return error code */
285   return errorCode;
286
287} /* exeError */
288
289/* ================================================================== exeNew */
290void *exeNew(EXE_VAR *exeVar,       /* execution variables */
291             long memSize)          /* buffer size, in bytes */
292{
293   void *newMem;     /* New memory pointer */
294
295   /* Allocate required memory space, check error */
296   newMem = efc_new(memSize);
297   if (!newMem) exeError(exeVar->program,EXE_ERROR_ALLOC,"exeNew");
298
299   /* Return allocated pointer */
300   return newMem;
301
302} /* exeNew */
303
304/* ============================================================ exeNewRecord */
305long exeNewRecord(EXE_VAR *exeVar,     /* execution variables */
306                  long memSize)        /* buffer size, in bytes */
307{
308   long idx;      /* new record index */
309
310   /* Find and allocate new record index */
311   idx = eci_rec_new(&(exeVar->program->error),memSize);
312
313   if (idx < 0L) exeError(exeVar->program,EXE_ERROR_MAXNREC,NULL);
314
315   /* Return index, negative number indicates an error */
316   return idx;
317
318} /* exeNewRecord */
319
320/* =========================================================== exeWorkRecord */
321long exeWorkRecord(EXE_VAR *var) /* execution variables */
322{
323   long idx;      /* new record index */
324
325   /* Find, allocate and activate new record index */
326   idx = exeNewRecord(var,EXE_REC_SIZE);
327   if (idx >= 0L) eci_rec_active(idx);
328
329   /* Return index, negative number indicates an error */
330   return idx;
331
332} /* exeWorkRecord */
333
334/* =============================================================== exeNumber */
335long exeNumber(EXE_VAR *exeVar,           /* execution variables */
336               SCOPE_VAR *scopeVar,       /* scope variables */
337               PARM_LIST i,               /* identifier index */
338               long min,                  /* minimum possible value */
339               long max,                  /* maximum possible value */
340               long defaultValue)         /* default value */
341{
342   long val;      /* return value */
343
344   /* Set the default value, get parameter (if present) */
345   val = defaultValue;
346   if (scopeVar->parmList[i])
347      if (*(scopeVar->parmList[i]))
348         val = atol(scopeVar->parmList[i]);
349
350   /* Check if value is inside the given range */
351   if (val < min || val > max)
352      exeError(exeVar->program,EXE_ERROR_INVALID,scopeVar->parmList[i]);
353
354   /* Return value */
355   return val;
356
357} /* exeNumber */
358
359/* ============================================================ exeHighLight */
360EXE_ERROR exeHighLight(EXE_VAR *exeVar,         /* execution variables */
361                       SCOPE_VAR *scopeVar,     /* scope variables */
362                       long idx,                /* current record index */
363                       int tag,                 /* field number */
364                       char *change)            /* change text */
365{
366   EFC_SPLIT_LINES table;                 /* split line structure */
367   long line;                             /* line index */
368   char *buff;                            /* auxiliary string buffer pointer */
369   char *p;                               /* auxiliary string buffer pointer */
370   EXE_ERROR errorCode = EXE_ERROR_OK;    /* error code */
371
372   /* Check mandatory parameters */
373   if (!scopeVar->parmList[PARM_PREFIX])
374      return exeError(exeVar->program,EXE_ERROR_MISSING,cplAtValue[ATVALUE_PREFIX].text);
375   if (!scopeVar->parmList[PARM_SUFFIX])
376      return exeError(exeVar->program,EXE_ERROR_MISSING,cplAtValue[ATVALUE_SUFFIX].text);
377
378   /* If no keys, no changed necessary */
379   if (!scopeVar->parmList[PARM_KEYS]) {
380      if (eci_field_AT(&(exeVar->program->error),idx,tag,change))
381         return exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
382      return errorCode;
383   }
384   if (!*scopeVar->parmList[PARM_KEYS]) {
385      if (eci_field_AT(&(exeVar->program->error),idx,tag,change))
386         return exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
387      return errorCode;
388   }
389
390   /* Split keys */
391   p = strdup(scopeVar->parmList[PARM_KEYS]);
392   if (!p) return exeError(exeVar->program,EXE_ERROR_ALLOC,scopeVar->parmList[PARM_KEYS]);
393   if (efc_split_lines(&table,p) < 0L)
394      errorCode = exeError(exeVar->program,EXE_ERROR_ALLOC,p);
395   else {
396
397      /* Copy change buffer */
398      buff = strdup(change);
399      if (!buff) errorCode = exeError(exeVar->program,EXE_ERROR_ALLOC,change);
400      else {
401
402         /* Change all keys */
403         for (line = 0L; line < table.qtt; line++)
404            if (*table.list[line].text) {
405               hl_put(buff,table.list[line].text,scopeVar->parmList[PARM_PREFIX],scopeVar->parmList[PARM_SUFFIX],exeVar->buff);
406               buff = efc_strrepl(buff,exeVar->buff);
407            }
408
409         /* Field update changed text */
410         errorCode = eci_field_AT(&(exeVar->program->error),idx,tag,buff);
411      }
412   }
413
414   /* Garbage collector */
415   efc_free(buff);
416   efc_free(p);
417   efc_split_lines_free(&table);
418
419   /* Return no error */
420   return errorCode;
421
422} /* exeHighLight */
423
424/* ======================================================== exeFieldSplitOcc */
425EXE_ERROR exeFieldSplitOcc(EXE_VAR *exeVar,        /* execution variables */
426                           SCOPE_VAR *scopeVar,    /* scope variables */
427                           long idx,               /* record index */
428                           CPL_ATVALUE atValue,    /* field option value */
429                           char *text,             /* field split buffer */
430                           char charSep,           /* separator character */
431                           int tag)                /* update field */
432{
433   EFC_SPLIT_LINES table;                 /* split line structure */
434   long line;                             /* line index */
435   EXE_ERROR errorCode = EXE_ERROR_OK;    /* error code */
436
437   /* Split lines */
438   if (!*text) return EXE_ERROR_OK;
439   if (efc_split_lines_char(&table,text,charSep) < 0L)
440      return exeError(exeVar->program,EXE_ERROR_ALLOC,text);
441
442   /* Loop all lines */
443   for (line = 0L; line < table.qtt; line++) {
444
445      /* Check error code */
446      if (errorCode) break;
447
448      /* Add field */
449      if (atValue != ATVALUE_HL) {
450         if (eci_field_AT(&(exeVar->program->error),idx,tag,table.list[line].text))
451            errorCode = exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
452      } else
453         errorCode = exeHighLight(exeVar,scopeVar,idx,tag,table.list[line].text);
454
455   } /* for */
456
457   /* Garbage collector */
458   efc_split_lines_free(&table);
459
460   /* Return error code */
461   return errorCode;
462
463} /* exeFieldSplitOcc */
464
465/* ======================================================== exeStatusControl */
466EXE_ERROR exeStatusControl(EXE_VAR *exeVar,        /* execution variables */
467                           char *db)               /* data base name */
468{
469   long idxControl;        /* control record index */
470
471   /* Get control record */
472   idxControl = exeNewRecord(exeVar,sizeof(M0STRU));
473   if (idxControl < 0L) return exeVar->program->error.code;
474
475   /* Read control record */
476   record(idxControl,db,0L);
477
478   /* Set control status string */
479   sprintf(exeVar->buff+strlen(exeVar->buff),"^n%ld^d%ld^e%ld",
480      VMF0nxtmfn(idxControl),VMF0mfcxx2(idxControl),VMF0mfcxx3(idxControl));
481
482   /* Garbage collector */
483   eci_rec_free(idxControl);
484
485   /* Return no error */
486   return EXE_ERROR_OK;
487
488} /* exeStatusControl */
489
490/* ============================================================ exeFileExist */
491BOOLEAN exeFileExist(char *db,            /* data base name */
492                     char *extension)     /* file extension */
493{
494   int handle;       /* auxiliary file handle */
495
496   /* Open file */
497   dbxopt_fatal = 0;
498   handle = dbxopen(NULL,db,extension);
499   if (handle) CLOSE(handle);
500
501   /* Return TRUE if the file exist or FALSE if not */
502   return (BOOLEAN)(handle > 0);
503
504} /* exeFileExist */
505
506/* ============================================================== exeExistDB */
507EXE_ERROR exeExistDB(EXE_VAR *exeVar,     /* execution variables */
508                     long idx,            /* current record index */
509                     int tag,             /* update field number */
510                     char *buff)          /* Return temporary file name buffer */
511{
512   EXE_ERROR errorCode = EXE_ERROR_OK;       /* error code */
513
514   /* Set database exist text */
515   strcpy(exeVar->buff,"^s");
516   if (exeFileExist(buff,".xrf")) strcat(exeVar->buff,"m");
517   if (exeFileExist(buff,".cnt")) strcat(exeVar->buff,"i");
518
519   /* If master exist, check control record */
520   if (strchr(exeVar->buff,'m')) errorCode = exeStatusControl(exeVar,buff);
521
522   /* Field update exist text information */
523   if (!errorCode)
524      if (eci_field_MT(&(exeVar->program->error),idx,tag,exeVar->buff))
525         errorCode = exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
526
527   /* Return error code */
528   return errorCode;
529
530} /* exeExistDB */
531
532/* ========================================================= exeRequiredParm */
533char *exeRequiredParm(EXE_VAR *exeVar,          /* execution variables */
534                      SCOPE_VAR *scopeVar,      /* scope variables */
535                      CPL_ATVALUE i)               /* parameter index */
536{
537   PARM_LIST parmIndex;    /* parmeter list index */
538
539   /* Get parameter related index */
540   parmIndex = atValueParm[i];
541
542   /* If present: return parameter, if absent: set error, return NULL */
543   if (scopeVar->parmList[parmIndex])
544      if (*(scopeVar->parmList[parmIndex]))
545         return scopeVar->parmList[parmIndex];
546   exeError(exeVar->program,EXE_ERROR_MISSING,cplAtValue[i].text);
547   return NULL;
548
549} /* exeRequiredParm */
550
551/* ======================================================= exeRequiredDefine */
552BOOLEAN exeRequiredDefine(EXE_VAR *exeVar,         /* execution variables */
553                          SCOPE_VAR *scopeVar,     /* scope variables */
554                          PRECISE_LIST i)          /* parameter index */
555{
556   /* If present: return define, if absent: set error, return NULL */
557   if (scopeVar->defineList[i].tag) return TRUE;
558   exeError(exeVar->program,EXE_ERROR_MISSING,preciseList[i]);
559   return FALSE;
560
561} /* exeRequiredDefine */
562
563/* ============================================================== exePrecise */
564PRECISE_LIST exePrecise(char *text)       /* find text */
565{
566   PRECISE_LIST i;      /* list index */
567
568   /* Check no text */
569   if (!text) return PRECISE_LIST_QTT;
570
571   /* Find list index */
572   for (i = 0; i < PRECISE_LIST_QTT; i++)
573      if (strcmp(text,preciseList[i]) == 0) break;
574
575   /* Return index found */
576   return i;
577
578} /* exePrecise */
579
580/* ============================================================= exeFindParm */
581CPL_COMMAND *exeFindParm(CPL_COMMAND *cmd,         /* start command */
582                         CPL_ATVALUE atValue)      /* name attribute index */
583{
584
585   /* loop commands backward to find parameter */
586   for ( ; cmd; cmd = cmd->prev) {
587      if (cmd->element != ELEMENT_PARM) continue;
588      if (cmd->attributeList[ATTRIBUTE_NAME].atValue == atValue) return cmd;
589   } /* for */
590
591   /* Return not found: NULL */
592   return NULL;
593
594} /* exeFindParm */
595
596/* ================================================================= exeJump */
597CPL_COMMAND *exeJump(EXE_VAR *exeVar,        /* execution variables */
598                     CPL_COMMAND *cmd,       /* current command */
599                     char *target)           /* target string buffer pointer */
600{
601   CPL_COMMAND *find;         /* auxiliary command pointer */
602
603   /* Find label backward, if found return command label */
604   for (find = cmd->prev; find; find = find->prev) {
605      if (find->element != ELEMENT_LABEL) continue;
606      if (strcmp(target,find->text) == 0) return find;
607   } /* for */
608
609   /* Find label forward, if found return command label */
610   for (find = cmd; find; find = find->next) {
611      if (find->element != ELEMENT_LABEL) continue;
612      if (strcmp(target,find->text) == 0) return find;
613   } /* for */
614
615   /* Return label not found (same scope) */
616   /* [4.0] The caller must test it. Avoid recursive call error set
617   exeError(exeVar->program,EXE_ERROR_TARGET,target);
618   [4.0] */
619   return NULL;
620
621} /* exeJump */
622
623/* ================================================================= exeFlow */
624EXE_ERROR exeFlow(EXE_VAR *exeVar,           /* execution variables */
625                  SCOPE_VAR *scopeVar,       /* scope variables */
626                  CPL_COMMAND *cmd,          /* current command */
627                  char *text)                /* command text */
628{
629
630   /* Evaluate action attribute */
631   switch (cmd->attributeList[ATTRIBUTE_ACTION].atValue) {
632
633   case ATVALUE_EXIT:
634      /* Script exit */
635      exeError(exeVar->program,EXE_ERROR_EXIT,text);
636      break;
637
638   case ATVALUE_JUMP:
639      /* Instruction jump */
640      scopeVar->jump = exeJump(exeVar,cmd,text);
641
642        /* [4.0] Return label not found (same scope) */
643      if (!scopeVar->jump) {
644        exeError(exeVar->program,EXE_ERROR_TARGET,text);
645        }
646
647      break;
648
649   case ATVALUE_SKIP:
650      /* Group skip */
651      scopeVar->skip = exePrecise(text);
652      if (scopeVar->skip != PRECISE_NEXT && scopeVar->skip != PRECISE_QUIT)
653         return exeError(exeVar->program,EXE_ERROR_INVALID,text);
654      break;
655
656   default:
657      /* Invalid action attribute */
658      return exeError(exeVar->program,EXE_ERROR_UNDEFINED,cmd->attributeList[ATTRIBUTE_ACTION].text);
659
660   } /* switch */
661
662   /* Return no error */
663   return EXE_ERROR_OK;
664
665} /* exeFlow */
666
667/* ========================================================= exeCgiDelSubfld */
668EXE_ERROR exeCgiDelSubfld(EXE_VAR *exeVar,   /* execution variables */
669                          long idx,          /* current record index */
670                          char *subfld)      /* subfield buffer */
671{
672   CGI_PARAM *cgip;  /* cgi list item */
673   char *p;          /* auxiliary string buffer pointer */
674   int tag;          /* update field */
675
676   /* Loop all cgi couples */
677   for (cgip = exeVar->cgiList; cgip; cgip = cgip->next) {
678
679      /* Find subfld, get corresponding tag */
680      p = strstr(cgip->name,subfld);
681      if (!p) continue;
682      tag = atoi(p+2);
683
684      /* Field delete tag */
685      if (eci_field_D(&(exeVar->program->error),idx,tag))
686         return exeError(exeVar->program,EXE_ERROR_FIELD,p);
687
688   } /* for */
689
690   /* Return no error */
691   return EXE_ERROR_OK;
692
693} /* exeCgiDelSubfld */
694
695/* ============================================================ exeCgiSubfld */
696EXE_ERROR exeCgiSubfld(EXE_VAR *exeVar,      /* execution variables */
697                       long idx,             /* current record index */
698                       char *subfld)         /* subfield buffer */
699{
700   CGI_PARAM *cgip;  /* cgi list item */
701   char *p;          /* auxiliary string buffer pointer */
702   int tag;          /* update field */
703   char charSep;     /* repeatable field separator character */
704   char *buff;       /* auxiliary buffer */
705   EXE_ERROR errorCode = EXE_ERROR_OK; /* error code */
706
707   /* Loop all cgi couples */
708   for (cgip = exeVar->cgiList; cgip; cgip = cgip->next) {
709
710      /* Find subfld, get corresponding tag */
711      p = strstr(cgip->name,subfld);
712      if (!p) continue;
713      tag = atoi(p+2);
714
715      /* Field update cgi value */
716      p = strstr(cgip->name,"^r");
717      if (p) {
718         charSep = (char)atoi(p+2);
719         buff = strdup(cgip->value);
720         if (!buff)
721            return exeError(exeVar->program,EXE_ERROR_ALLOC,cgip->value);
722         errorCode = exeFieldSplitOcc(exeVar,NULL,idx,ATVALUE_ADD,buff,charSep,tag);
723         efc_free(buff);
724         if (errorCode) break;
725      } else
726         if (*cgip->value)
727            if (eci_field_AT(&(exeVar->program->error),idx,tag,cgip->value))
728               return exeError(exeVar->program,EXE_ERROR_FIELD,cgip->value);
729
730   } /* for */
731
732   /* Return no error */
733   return errorCode;
734
735} /* exeCgiSubfld */
736
737/* ============================================================ exeCgiPrefix */
738EXE_ERROR exeCgiPrefix(EXE_VAR *exeVar,      /* execution variables */
739                       long idx,             /* current record index */
740                       char *prefix)         /* subfield buffer */
741{
742   CGI_PARAM *cgip;     /* cgi list item */
743   int pfxLength;       /* prefix length */
744   int tag;             /* update field */
745
746   /* Set prefix length, loop all copules */
747   pfxLength = strlen(prefix);
748   for (cgip = exeVar->cgiList; cgip; cgip = cgip->next) {
749
750      /* Find prefix, get corresponding tag */
751      if (strncmp(cgip->name,prefix,pfxLength) != 0) continue;
752      tag = atoi(cgip->name+pfxLength);
753
754      /* Field add cgi value */
755      if (eci_field_AT(&(exeVar->program->error),idx,tag,cgip->value))
756         return exeError(exeVar->program,EXE_ERROR_FIELD,cgip->value);
757
758   } /* for */
759
760   /* Return no error */
761   return EXE_ERROR_OK;
762
763} /* exeCgiPrefix */
764
765/* ============================================================== exeCgiScan */
766EXE_ERROR exeCgiScan(EXE_VAR *exeVar,        /* execution variables */
767                     int tag,                /* update field */
768                     CPL_ATVALUE tagValue,   /* alternate cgi option */
769                     BOOLEAN valueOn,        /* value behavior */
770                     char *cgiName,          /* subfield buffer */
771                     long idx)               /* current record index */
772{
773   CGI_PARAM *cgip;     /* cgi list item */
774
775   /* Load all cgi couples */
776   if (strcmp(cgiName,"^n^v") == 0)
777      for (cgip = exeVar->cgiList; cgip; cgip = cgip->next) {
778         sprintf(exeVar->buff,"^n%s^v%s",cgip->name,cgip->value);
779         if (eci_field_AT(&(exeVar->program->error),idx,tag,exeVar->buff))
780            return exeError(exeVar->program,EXE_ERROR_FIELD,exeVar->buff);
781      } /* for */
782
783   /* Load cgi couple named with ^t, ^u and ^w and prefixed */
784   if (tag == 0) {
785      if (tagValue == ATVALUE_CGISFT)
786         if (exeCgiSubfld(exeVar,idx,"^t")) return EXE_ERROR_FIELD;
787      if (tagValue == ATVALUE_CGISFW)
788         if (exeCgiSubfld(exeVar,idx,"^w")) return EXE_ERROR_FIELD;
789      if (tagValue == ATVALUE_CGISFU) {
790         if (exeCgiDelSubfld(exeVar,idx,"^u")) return EXE_ERROR_FIELD;
791         if (exeCgiSubfld(exeVar,idx,"^u")) return EXE_ERROR_FIELD;
792      }
793      if (tagValue == ATVALUE_PREFIX)
794         if (exeCgiPrefix(exeVar,idx,cgiName)) return EXE_ERROR_FIELD;
795   }
796
797   /* Find cgi name, field update corresponding value */
798   for (cgip = exeVar->cgiList; cgip; cgip = cgip->next) {
799      if (strcmp(cgiName,cgip->name) != 0) continue;
800      if (!cgip->value) continue;
801      if (*cgip->value) {
802         if (eci_field_AT(&(exeVar->program->error),idx,tag,cgip->value))
803            return exeError(exeVar->program,EXE_ERROR_FIELD,cgip->value);
804         continue;
805      }
806      if (valueOn)
807         if (eci_field_AT(&(exeVar->program->error),idx,tag,preciseList[PRECISE_ON]))
808            return exeError(exeVar->program,EXE_ERROR_FIELD,preciseList[PRECISE_ON]);
809   } /* for */
810
811   /* Return no error */
812   return EXE_ERROR_OK;
813
814} /* exeCgiScan */
815
816/* ============================================================ exeTableInfo */
817char *exeTableInfo(char *text,      /* text to be scanned */
818                   int *number)     /* number data */
819{
820
821   /* Get number, skip digit characters */
822   *number = atoi(text);
823   while (isdigit(*text)) text++;
824
825   /* Return string pointer after separator character */
826   if (*text) text++;
827   return text;
828
829} /* exeTableInfo */
830
831/* ============================================================= exeCgiTable */
832EXE_ERROR exeCgiTable(EXE_VAR *exeVar,          /* execution variables */
833                      long idx,                 /* current record index */
834                      char *text)               /* cgi table string buffer pointer */
835{
836   EFC_SPLIT_LINES table;                 /* split line structure */
837   long line;                             /* line index */
838   int tag;                               /* update field */
839   CPL_ATVALUE tagValue;                  /* alternate cgi option */
840   BOOLEAN valueOn = FALSE;               /* value behavior */
841   EXE_ERROR errorCode = EXE_ERROR_OK;    /* error code */
842
843   /* Split lines */
844   if (efc_split_lines(&table,text) < 0L)
845      return exeError(exeVar->program,EXE_ERROR_ALLOC,text);
846
847   /* Loop all lines */
848   for (line = 0L; line < table.qtt; line++) {
849
850      /* Get table information: field number and content pointer */
851      text = exeTableInfo(table.list[line].text,&tag);
852
853      /* Empty value acts like "ON" */
854      if (tag == 0) {
855         if (strcmp(text,preciseList[PRECISE_ON]) == 0) valueOn = TRUE;
856         if (strcmp(text,preciseList[PRECISE_OFF]) == 0) valueOn = FALSE;
857      }
858
859      /* Load cgi data */
860      tagValue = cplIdentifier(cplAtValue,ATVALUE_LIST_QTT,text);
861      /* [0.9] Begin */
862      if (tag == 0 && tagValue == ATVALUE_LIST_QTT)
863         tagValue = ATVALUE_PREFIX;
864      /* [0.9] End */
865      errorCode = exeCgiScan(exeVar,tag,tagValue,valueOn,text,idx);
866      if (errorCode) break;
867
868   } /* for */
869
870   /* Garbage collector */
871   efc_split_lines_free(&table);
872
873   /* Return error code */
874   return errorCode;
875
876} /* exeCgiTable */
877
878/* ========================================================== exeFieldDefine */
879EXE_ERROR exeFieldDefine(EXE_VAR *exeVar,             /* execution variables */
880                         SCOPE_DEFINE defineList[],   /* define field list */
881                         int tag,                     /* field number */
882                         char *text)                  /* item */
883{
884   PRECISE_LIST i;      /* auxiliary flow list index */
885
886   /* Find flow option, check invalid option */
887   i = exePrecise(text);
888   if (i == PRECISE_LIST_QTT)
889      return exeError(exeVar->program,EXE_ERROR_INVALID,text);
890
891   /* set field number and apply flag */
892   defineList[i].tag = tag;
893   defineList[i].apply = TRUE;
894
895   /* Return no error */
896   return EXE_ERROR_OK;
897
898} /* exeFieldDefine */
899
900/* =============================================================== exeDefine */
901EXE_ERROR exeDefine(EXE_VAR *exeVar,            /* execution variables */
902                    SCOPE_VAR *scopeVar,     /* scope variables */
903                    char *text)              /* field define list */
904{
905   EFC_SPLIT_LINES table;                 /* split line structure */
906   long line;                             /* line index */
907   int tag;                               /* update field */
908   EXE_ERROR errorCode = EXE_ERROR_OK;    /* error code */
909
910   /* Split lines */
911   if (efc_split_lines(&table,text) < 0L)
912      return exeError(exeVar->program,EXE_ERROR_ALLOC,text);
913
914   /* Loop all lines */
915   for (line = 0L; line < table.qtt; line++) {
916
917      /* Get field number and text information */
918      text = exeTableInfo(table.list[line].text,&tag);
919
920      /* Set table item */
921      errorCode = exeFieldDefine(exeVar,scopeVar->defineList,tag,text);
922      if (errorCode) break;
923
924   } /* for */
925
926   /* Garbage collector */
927   efc_split_lines_free(&table);
928
929   /* Return no error */
930   return errorCode;
931
932} /* exeDefine */
933
934/* ============================================================= exeFieldDir */
935EXE_ERROR exeFieldDir(EXE_VAR *exeVar,    /* execution variables */
936                      CMD_ATTRIBUTE_STRU *attributeType, /* type attribute */
937                      long idx,           /* record index */
938                      int tag)            /* update field */
939{
940   char *p;       /* auxiliary string buffer pointer */
941   int fldDir;    /* field directory entry */
942   int fldQtt;    /* quantity of fields */
943
944   /* Put all fields in the buffer */
945   fldQtt = VMFRnvf(idx);
946   for (p = exeVar->buff,fldDir = 0; fldDir < fldQtt; fldDir++) {
947      sprintf(p,"%05d",VDIRtag(idx,fldDir)); p += 5;
948      if (attributeType->atValue != ATVALUE_LIST) {
949         *p++ = ' ';
950         memcpy(p,VFIELDP(idx,fldDir),VDIRlen(idx,fldDir)); p += VDIRlen(idx,fldDir);
951      }
952      *p++ = '\n';
953   } /* for */
954   *p = '\0';
955
956   /* Field update the buffer */
957   if (attributeType->atValue == ATVALUE_DELETE) {
958      eci_field_D(&(exeVar->program->error),idx,0);
959   }
960   if (eci_field_AT(&(exeVar->program->error),idx,tag,exeVar->buff))
961      return exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
962
963   /* Return no error */
964   return EXE_ERROR_OK;
965
966} /* exeFieldDir */
967
968/* =========================================================== exeFieldSplit */
969EXE_ERROR exeFieldSplit(EXE_VAR *exeVar,        /* execution variables */
970                        SCOPE_VAR *scopeVar,    /* scope variables */
971                        long idx,               /* record index */
972                        CPL_ATVALUE atValue,    /* field option value */
973                        CMD_ATTRIBUTE_STRU *attributeSplit, /* field split attribute */
974                        CMD_ATTRIBUTE_STRU *attributeType,  /* type attribute */
975                        char *text,             /* field split buffer */
976                        int tag)                /* update field */
977{
978
979   /* Evaluate split options */
980   switch (attributeSplit->atValue) {
981
982   case ATVALUE_OCC:
983      /* Field update each line into one new occurrences */
984      return exeFieldSplitOcc(exeVar,scopeVar,idx,atValue,text,'\n',tag);
985
986   case ATVALUE_FLDDIR:
987      /* Field update all the fields into one field */
988      return exeFieldDir(exeVar,attributeType,idx,tag);
989
990   default:
991      return exeError(exeVar->program,EXE_ERROR_UNDEFINED,attributeSplit->text);
992
993   } /* switch */
994
995} /* exeFieldSplit */
996
997/* ========================================================== exeFieldTransf */
998EXE_ERROR exeFieldTransf(EXE_VAR *exeVar,          /* execution variables */
999                         long idxSource,           /* source record index */
1000                         long idxTarget,           /* target record index */
1001                         CPL_ATVALUE actionValue,  /* action attribute value */
1002                         CPL_ATVALUE previousValue,/* previous attribute value */
1003                         char *fieldList)          /* transfer field list */
1004{
1005   char *p;                   /* auxiliary string bufer pointer */
1006   int tag = 0;               /* scaned tag */
1007   int tagFrom = 0;           /* range first tag */
1008   BOOLEAN keep = FALSE;      /* keep source tag */
1009   int tagSource = 0;         /* scanned source tag */
1010   BOOLEAN delFlag = FALSE;   /* delete flag, used for eci_field_copy */
1011
1012   /* Previous copy flag: add or replace */
1013   if (actionValue == ATVALUE_REPLACE) delFlag = TRUE;
1014   else
1015      if (actionValue == ATVALUE_IMPORT || actionValue == ATVALUE_EXPORT)
1016            if (previousValue != ATVALUE_ADD) delFlag = TRUE;
1017
1018   /* Loop all string buffer */
1019   for (p = fieldList; *p; p++) {
1020
1021      /* Skip non digit character, check range specification, check change specification */
1022      if (!isdigit(*p)) {
1023         if (*p == '/') tagFrom = tag;
1024         if (*p == '[') keep = TRUE;
1025         continue;
1026      }
1027
1028      /* Get tag number */
1029      tag = atoi(p);
1030
1031      /* Get change source tag */
1032      if (keep) {
1033         tagSource = tag;
1034         keep = FALSE;
1035         while (isdigit(*(p+1))) p++;
1036         continue;
1037      }
1038
1039      /* Range of tags transfer */
1040      if (tagFrom) {
1041         if (tagFrom > tag)
1042            return exeError(exeVar->program,EXE_ERROR_FIELD,p);
1043         while (++tagFrom < tag)
1044            if (actionValue == ATVALUE_DELETE) {
1045               if (eci_field_D(&(exeVar->program->error),idxTarget,tagFrom))
1046                  return exeError(exeVar->program,EXE_ERROR_FIELD,p);
1047            } else
1048               if (eci_field_copy(&(exeVar->program->error),delFlag,idxTarget,tagFrom,idxSource,tagFrom))
1049                  return exeError(exeVar->program,EXE_ERROR_FIELD,p);
1050         tagFrom = 0;
1051      }
1052
1053      /* Single transfer */
1054      if (!tagSource) tagSource = tag;
1055      if (actionValue == ATVALUE_DELETE) {
1056         if (eci_field_D(&(exeVar->program->error),idxTarget,tag))
1057            return exeError(exeVar->program,EXE_ERROR_FIELD,p);
1058      } else
1059         if (eci_field_copy(&(exeVar->program->error),delFlag,idxTarget,tag,idxSource,tagSource))
1060            return exeError(exeVar->program,EXE_ERROR_FIELD,p);
1061      tagSource = 0;
1062
1063      /* Skip digit character */
1064      while (isdigit(*(p+1))) p++;
1065
1066   } /* for */
1067
1068   /* Return no error */
1069   return EXE_ERROR_OK;
1070
1071} /* exeFieldTransf */
1072
1073/* ========================================================== exeDefineField */
1074ECI_ERROR exeDefineField(EXE_VAR *exeVar,             /* execution variables */
1075                         long idx,                    /* current record index */
1076                         SCOPE_DEFINE *defineItem)    /* define item */
1077{
1078
1079   /* If field number previously set: modify it */
1080   if (defineItem->tag <= 0) return ECI_ERROR_OK;
1081   if (defineItem->text)
1082      return eci_field_MT(&(exeVar->program->error),idx,defineItem->tag,defineItem->text);
1083   return eci_field_MN(&(exeVar->program->error),idx,defineItem->tag,defineItem->value);
1084
1085} /* exeDefineField */
1086
1087/* ============================================================== exeDefines */
1088EXE_ERROR exeDefines(EXE_VAR *exeVar,           /* execution variables */
1089                     SCOPE_VAR *scopeVar,       /* scope variables */
1090                     long idx)                  /* current record index */
1091{
1092   PRECISE_LIST i;            /* auxiliary flow option index */
1093   ECI_ERROR errorCode;       /* error code */
1094
1095   /* Loop all defines, check apply flag */
1096   for (i = 0; i < PRECISE_LIST_QTT; i++) {
1097      if (!scopeVar->defineList[i].apply) continue;
1098      errorCode = exeDefineField(exeVar,idx,&(scopeVar->defineList[i]));
1099      if (errorCode)
1100         return exeError(exeVar->program,EXE_ERROR_FIELD,scopeVar->defineList[i].text);
1101   }
1102
1103   /* Return no error */
1104   return EXE_ERROR_OK;
1105
1106} /* exeDefines */
1107
1108/* ============================================================= exeFieldOcc */
1109EXE_ERROR exeFieldOcc(EXE_VAR *exeVar,          /* execution variables */
1110                      SCOPE_VAR *scopeVar,      /* scope variables */
1111                      int tagFrom,              /* from field number */
1112                      int tagTo,                /* to field number */
1113                      char *text)               /* field define list */
1114{
1115   int occ;       /* from occurrence */
1116
1117   /* Check occurrence */
1118   occ = atoi(text);
1119   if (occ <= 0)
1120      return exeError(exeVar->program,EXE_ERROR_INVALID,text);
1121
1122   /* Delete previous content */
1123   if (eci_field_D(&(exeVar->program->error),scopeVar->idxCurr,tagTo))
1124      return exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
1125
1126   /* Get field occurence, field replace */
1127   if (eci_field(scopeVar->idxCurr,tagFrom,occ,exeVar->buff))
1128      if (eci_field_AT(&(exeVar->program->error),scopeVar->idxCurr,tagTo,exeVar->buff))
1129         return exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
1130
1131   /* Return no error */
1132   return EXE_ERROR_OK;
1133
1134} /* exeFieldOcc */
1135
1136/* ================================================================ exeField */
1137EXE_ERROR exeField(EXE_VAR *exeVar,          /* execution variables */
1138                   SCOPE_VAR *scopeVar,      /* scope variables */
1139                   long idxSource,           /* source record index */
1140                   long idxTarget,           /* target record index */
1141                   CPL_COMMAND *cmd,         /* current command */
1142                   char *text)               /* command text */
1143{
1144   CPL_ATVALUE actionValue;               /* action attribute value */
1145   int tag;                               /* field number */
1146   BOOLEAN tagList;                       /* tag list flag */
1147   BOOLEAN tagFirstLine;                  /* first command text line defines the tag number */
1148   CPL_ATVALUE splitValue;                /* split attribute value */
1149   int occ;                               /* field occurrence */
1150   CPL_ATVALUE previousValue;             /* previous action attribute add/replace */
1151   int parmTag;                           /* parameter field number */
1152   int tagFrom;                           /* from field number */
1153
1154   /* Get tag attribute */
1155   actionValue = cmd->attributeList[ATTRIBUTE_ACTION].atValue;
1156   if (!actionValue)
1157      return exeError(exeVar->program,EXE_ERROR_MISSING,cplAttribute[ATTRIBUTE_ACTION].text);
1158   if (!cmd->attributeList[ATTRIBUTE_TAG].text)
1159      return exeError(exeVar->program,EXE_ERROR_MISSING,cplAttribute[ATTRIBUTE_TAG].text);
1160   tag = atoi(cmd->attributeList[ATTRIBUTE_TAG].text);
1161   if (cmd->attributeList[ATTRIBUTE_TAG].atValue == ATVALUE_LIST_QTT && tag <= 0)
1162      return exeError(exeVar->program,EXE_ERROR_INVALID,cmd->attributeList[ATTRIBUTE_TAG].text);
1163   tagList = (BOOLEAN)(cmd->attributeList[ATTRIBUTE_TAG].atValue == ATVALUE_LIST);
1164
1165   /* 28.Nov.2000 */
1166   tagFirstLine = (BOOLEAN)(cmd->attributeList[ATTRIBUTE_TAG].atValue == ATVALUE_FIRST_LINE);
1167   if (tagFirstLine)
1168   {
1169      tag = atoi(text);
1170      if (tag <= 0)
1171      {
1172         return exeError(exeVar->program,EXE_ERROR_INVALID,text);
1173      }
1174      while (*text)
1175      {
1176         if (*text++ == '\n')
1177         {
1178            break;
1179         }
1180      }
1181   }
1182
1183   splitValue = cmd->attributeList[ATTRIBUTE_SPLIT].atValue;
1184   previousValue = cmd->attributeList[ATTRIBUTE_PREVIOUS].atValue;
1185
1186   /* Evaluate field action */
1187   switch (actionValue) {
1188
1189   case ATVALUE_HL :
1190   case ATVALUE_REPLACE :
1191      /* Delete previous field content */
1192      if (!tagList)
1193         if (eci_field_D(&(exeVar->program->error),idxTarget,tag))
1194            return exeError(exeVar->program,EXE_ERROR_FIELD,text);
1195
1196   case ATVALUE_ADD :
1197      /* Transfer field list */
1198      if (tagList)
1199         return exeFieldTransf(exeVar,idxSource,idxTarget,actionValue,previousValue,text);
1200
1201      /* Add splited field */
1202      if (splitValue)
1203         return exeFieldSplit(exeVar,scopeVar,idxTarget,actionValue,&(cmd->attributeList[ATTRIBUTE_SPLIT]),&(cmd->attributeList[ATTRIBUTE_TYPE]),text,tag);
1204
1205      /* Add high light field */
1206      if (actionValue == ATVALUE_HL)
1207         return exeHighLight(exeVar,scopeVar,idxTarget,tag,text);
1208
1209      /* Add single field */
1210      if (eci_field_AT(&(exeVar->program->error),idxTarget,tag,text))
1211         return exeError(exeVar->program,EXE_ERROR_FIELD,text);
1212
1213      break;
1214
1215   case ATVALUE_CGI :
1216      /* Cgi field */
1217      return exeCgiScan(exeVar,tag,cmd->attributeList[ATTRIBUTE_TAG].atValue,(BOOLEAN)(cmd->attributeList[ATTRIBUTE_TYPE].atValue == ATVALUE_FLAG),text,scopeVar->idxCurr);
1218
1219   case ATVALUE_DEFINE :
1220      /* Define automatic fields */
1221      return exeFieldDefine(exeVar,scopeVar->defineList,tag,text);
1222
1223   case ATVALUE_DELETE :
1224      /* Delete field list */
1225      if (tagList)
1226         if (strcmp(text,"ALL") == 0) {
1227            if (eci_field_D(&(exeVar->program->error),idxTarget,0))
1228               return exeError(exeVar->program,EXE_ERROR_FIELD,text);
1229            break;
1230         } else
1231            return exeFieldTransf(exeVar,idxSource,idxTarget,actionValue,previousValue,text);
1232
1233      /* Delete field / occurrence */
1234      occ = atoi(text);
1235      if (occ < 0) return exeError(exeVar->program,EXE_ERROR_INVALID,text);
1236      if (eci_field_DO(&(exeVar->program->error),idxTarget,tag,occ))
1237         return exeError(exeVar->program,EXE_ERROR_FIELD,text);
1238      break;
1239
1240   case ATVALUE_EXPORT :
1241      /* Field export */
1242      if (tagList)
1243         return exeFieldTransf(exeVar,idxSource,scopeVar->idxPrev,actionValue,previousValue,text);
1244      parmTag = atoi(text);
1245      if (parmTag <= 0) return exeError(exeVar->program,EXE_ERROR_FIELD,text);
1246      if (eci_field_copy(&(exeVar->program->error),(BOOLEAN)previousValue != ATVALUE_ADD,scopeVar->idxPrev,tag,idxSource,parmTag))
1247         return exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
1248      break;
1249
1250   case ATVALUE_IMPORT :
1251      /* Field import */
1252      if (tagList)
1253         return exeFieldTransf(exeVar,scopeVar->idxPrev,idxTarget,actionValue,previousValue,text);
1254      parmTag = atoi(text);
1255      if (parmTag <= 0) return exeError(exeVar->program,EXE_ERROR_FIELD,text);
1256      if (eci_field_copy(&(exeVar->program->error),(BOOLEAN)previousValue != ATVALUE_ADD,idxTarget,tag,scopeVar->idxPrev,parmTag))
1257         return exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
1258      break;
1259
1260   case ATVALUE_OCC :
1261      /* Get specific occurrence */
1262      if (!cmd->attributeList[ATTRIBUTE_FROM].text)
1263         return exeError(exeVar->program,EXE_ERROR_MISSING,cplAttribute[ATTRIBUTE_FROM].text);
1264      tagFrom = atoi(cmd->attributeList[ATTRIBUTE_FROM].text);
1265      if (tagFrom <= 0)
1266         return exeError(exeVar->program,EXE_ERROR_INVALID,cmd->attributeList[ATTRIBUTE_FROM].text);
1267      return exeFieldOcc(exeVar,scopeVar,tagFrom,tag,text);
1268
1269   case ATVALUE_STATUSDB :
1270      /* Database status */
1271      return exeExistDB(exeVar,idxTarget,tag,text);
1272
1273   case ATVALUE_STATUSFILE :
1274      /* File status */
1275      if (eci_field_D(&(exeVar->program->error),idxTarget,tag))
1276         return exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
1277      if (exeFileExist(text,NULL))
1278         if (eci_field_AT(&(exeVar->program->error),idxTarget,tag,"^se"))
1279            return exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
1280      break;
1281
1282   default:
1283      /* Invalid action attribute */
1284      return exeError(exeVar->program,EXE_ERROR_UNDEFINED,cmd->attributeList[ATTRIBUTE_ACTION].text);
1285
1286   } /* switch */
1287
1288   /* Return error code */
1289   return EXE_ERROR_OK;
1290
1291} /* exeField */
1292
1293/* ============================================================= exeUnlockDB */
1294EXE_ERROR exeUnlockDB(EXE_VAR *exeVar,    /* execution variables */
1295                      char *db)           /* data base name */
1296{
1297/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1298   - Copied from retag.c
1299>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
1300   long idxControl;        /* control record index */
1301
1302   /* Get control record index */
1303   idxControl = exeNewRecord(exeVar,sizeof(M0STRU));
1304   if (idxControl < 0L) return exeVar->program->error.code;
1305
1306   /* Read control record, reopen for write */
1307   record(idxControl,db,0L);
1308   dbxopenw("",VRDBname(idxControl),mx1extp,&VRDBmsopn(idxControl),&VRDBmsopw(idxControl),"msopn/w"); /* recwmast() */
1309
1310   /* Write with no lock information */
1311   if (VMF0mfcxx2(idxControl) || VMF0mfcxx3(idxControl)) {
1312      VMF0mfcxx2(idxControl) = VMF0mfcxx3(idxControl) = 0L;
1313      recwmast(vrecp[idxControl],NULL,0L,0,0,sizeof(M0STRU));
1314   }
1315
1316   /* Garbage collector */
1317   eci_rec_free(idxControl);
1318
1319   /* Return no error */
1320   return EXE_ERROR_OK;
1321
1322} /* exeUnlockDB */
1323
1324/* ============================================================= exeFileTemp */
1325EXE_ERROR exeFileTemp(EXE_VAR *exeVar,    /* execution variables */
1326                      char *buff)         /* Return temporary file name buffer */
1327{
1328   FILE *temp;       /* file pointer */
1329
1330   /* Get a temporary file name, if OK, save it, else return error */
1331   if (!dbxtmpnm("CI_TEMPDIR", 0, buff))
1332      return exeError(exeVar->program,EXE_ERROR_FILE,"tmpnam");
1333   temp = fopen(buff,"w");
1334   if (!temp) return exeError(exeVar->program,EXE_ERROR_FILE,buff);
1335   fclose(temp);
1336
1337   /* Return no error */
1338   return EXE_ERROR_OK;
1339
1340} /* exeFileTemp */
1341
1342/* =============================================================== exeOutput */
1343EXE_ERROR exeOutput(EXE_VAR *exeVar,         /* execution variables */
1344                    CPL_ATVALUE mode,        /* output open mode */
1345                    char *fileName)          /* output file name */
1346{
1347   char *p;       /* auxiliary string buffer pointer */
1348
1349   /* Close previously opended output file, open a new one */
1350   if (exeVar->output != stdout) fclose(exeVar->output);
1351   p = dbxcipar(NULL,fileName,'=');
1352   exeVar->output = fopen(p,mode == ATVALUE_APPEND ? "a+" : "w+");
1353   if (exeVar->output) return EXE_ERROR_OK;
1354
1355   /* Error: go back to the standard output, return error code */
1356   exeVar->output = stdout;
1357   return exeError(exeVar->program,EXE_ERROR_FILE,p);
1358
1359} /* exeOutput */
1360
1361/* ============================================================= exeCopyFile */
1362EXE_ERROR exeCopyFile(EXE_VAR *exeVar,    /* execution variables */
1363                      char *text)         /* file names text */
1364{
1365   EFC_SPLIT_LINES table;                 /* split line structure */
1366   char *pIn;                             /* auxiliary string buffer pointer */
1367   char *pOut;                            /* auxiliary string buffer pointer */
1368   EXE_ERROR errorCode = EXE_ERROR_OK;    /* error code */
1369   COPYFILE_ERROR copyFileError;          /* copy file error code */
1370
1371   /* Split lines */
1372   if (efc_split_lines(&table,text) < 0L)
1373      return exeError(exeVar->program,EXE_ERROR_ALLOC,text);
1374
1375   /* Check file name presence */
1376   if (table.qtt < 1)
1377      return exeError(exeVar->program,EXE_ERROR_MISSING,"source copy file");
1378   if (table.qtt < 2)
1379      return exeError(exeVar->program,EXE_ERROR_MISSING,"target copy file");
1380
1381   /* Get cipar file names */
1382   pIn = strdup(dbxcipar(NULL,table.list[0].text,'='));
1383   pOut = strdup(dbxcipar(NULL,table.list[1].text,'='));
1384
1385   /* copy file */
1386   copyFileError = efc_copyFile(pIn,pOut);
1387   if (copyFileError)
1388   {
1389      errorCode = exeError(exeVar->program,EXE_ERROR_FILE,copyFileError == COPYFILE_ERROR_IN_OPEN ? pIn : pOut);
1390   }
1391
1392   /* Garbage collector */
1393   efc_free(pIn);
1394   efc_free(pOut);
1395   efc_split_lines_free(&table);
1396
1397   /* Return error code */
1398   return errorCode;
1399
1400} /* exeCopyFile */
1401
1402/* ================================================================= exeFile */
1403EXE_ERROR exeFile(EXE_VAR *exeVar,        /* execution variables */
1404                  SCOPE_VAR *scopeVar,    /* scope variables */
1405                  CPL_COMMAND *cmd,       /* attribute list */
1406                  char *text)             /* command text */
1407{
1408   int tag;                   /* field number */
1409   EXE_ERROR errorCode;       /* error code */
1410   char *ciparText;           /* cipar translated file name */
1411
1412   /* Evaluate action attribute */
1413   switch (cmd->attributeList[ATTRIBUTE_ACTION].atValue) {
1414
1415   case ATVALUE_APPEND:
1416      /* Evaluate type attribute */
1417      switch (cmd->attributeList[ATTRIBUTE_TYPE].atValue) {
1418
1419      case ATVALUE_OUTPUT:
1420         /* Open output file for append */
1421         return exeOutput(exeVar,ATVALUE_APPEND,text);
1422
1423      default:
1424         return exeError(exeVar->program,EXE_ERROR_INVALID,cplAttribute[ATTRIBUTE_TYPE].text);
1425
1426      } /* switch */
1427
1428   case ATVALUE_CREATE:
1429      /* Evaluate type attribute */
1430      switch (cmd->attributeList[ATTRIBUTE_TYPE].atValue) {
1431
1432      case ATVALUE_DATABASE:
1433      case ATVALUE_MASTER:
1434         /* Create master file */
1435         recisis0(text);
1436         if (cmd->attributeList[ATTRIBUTE_TYPE].atValue == ATVALUE_MASTER) break;
1437
1438      case ATVALUE_INVERTED:
1439         /* Create inverted file */
1440         trmisis0(text);
1441         break;
1442
1443      case ATVALUE_OUTPUT:
1444         /* Open output file for create */
1445         return exeOutput(exeVar,ATVALUE_OUTPUT,text);
1446
1447      case ATVALUE_TEMPFILE:
1448         /* Create an unique temporary file */
1449         tag = atoi(text);
1450         if (tag <= 0) return exeError(exeVar->program,EXE_ERROR_INVALID,text);
1451         errorCode = exeFileTemp(exeVar,exeVar->buff);
1452         if (errorCode) return errorCode;
1453         if (eci_field_MT(&(exeVar->program->error),scopeVar->idxCurr,tag,exeVar->buff))
1454            return exeError(exeVar->program,EXE_ERROR_FIELD,exeVar->buff);
1455         break;
1456
1457      default:
1458         /* Invalid type */
1459         return exeError(exeVar->program,EXE_ERROR_INVALID,cplAttribute[ATTRIBUTE_TYPE].text);
1460
1461      } /* switch */
1462
1463      break;
1464
1465   case ATVALUE_CLOSE:
1466      /* Evaluate type attribute */
1467      switch (cmd->attributeList[ATTRIBUTE_TYPE].atValue) {
1468
1469      case ATVALUE_DATABASE:
1470         /* Database close */
1471         dbxflush(text);
1472         break;
1473
1474      case ATVALUE_OUTPUT:
1475         /* Output close */
1476         if (exeVar->output != stdout) {
1477            fclose(exeVar->output);
1478            exeVar->output = stdout;
1479         }
1480         break;
1481
1482      default:
1483         /* Invalid type */
1484         return exeError(exeVar->program,EXE_ERROR_INVALID,cplAttribute[ATTRIBUTE_TYPE].text);
1485
1486      } /* switch */
1487
1488      break;
1489
1490   case ATVALUE_COPY:
1491      /* Evaluate type attribute */
1492      switch (cmd->attributeList[ATTRIBUTE_TYPE].atValue) {
1493
1494      case ATVALUE_FILE:
1495         /* file copy */
1496         return exeCopyFile(exeVar,text);
1497
1498      default:
1499         return exeError(exeVar->program,EXE_ERROR_INVALID,cplAttribute[ATTRIBUTE_TYPE].text);
1500
1501      } /* switch */
1502
1503   case ATVALUE_DELETE:
1504      /* Delete file */
1505
1506      /* 27.Nov.2000 */
1507      ciparText = dbxcipar(NULL,text,'=');
1508
1509      if (remove(ciparText) == -1) {
1510         sprintf(exeVar->buff,"%s (%d)",ciparText,errno);
1511         return exeError(exeVar->program,EXE_ERROR_FILE,exeVar->buff);
1512      }
1513      break;
1514
1515   case ATVALUE_UNLOCK:
1516      /* Evaluate type attribute */
1517      switch (cmd->attributeList[ATTRIBUTE_TYPE].atValue) {
1518
1519      case ATVALUE_DATABASE:
1520         /* Database unlock */
1521         return exeUnlockDB(exeVar,text);
1522
1523      default:
1524         /* Invalid type */
1525         return exeError(exeVar->program,EXE_ERROR_INVALID,cplAttribute[ATTRIBUTE_TYPE].text);
1526
1527      } /* switch */
1528
1529   default:
1530      /* Invalid type */
1531      return exeError(exeVar->program,EXE_ERROR_MISSING,cplAttribute[ATTRIBUTE_ACTION].text);
1532
1533   } /* switch */
1534
1535   /* Return no error */
1536   return EXE_ERROR_OK;
1537
1538} /* exeFile */
1539
1540/* =============================================================== exeInvert */
1541LOCK_ERROR exeInvert(EXE_VAR *exeVar,           /* execution variables */
1542                     SCOPE_VAR *scopeVar,       /* scope variables */
1543                     CPL_COMMAND *cmd,          /* current command */
1544                     char *db,                  /* data base name */
1545                     long idx)                  /* record index */
1546{
1547   long maxLinks;                            /* maximum inverted links */
1548   FST_CODE *fstCode;                        /* FST code */
1549   LOCK_ERROR lockError = LOCK_ERROR_OK;     /* Lock error code */
1550
1551   /* Check if the invertion was required */
1552   if (!scopeVar->parmList[PARM_FST]) return LOCK_ERROR_OK;
1553   if (!*(scopeVar->parmList[PARM_FST])) return LOCK_ERROR_OK;
1554
1555   /* Set maximum links */
1556   maxLinks = exeNumber(exeVar,scopeVar,PARM_MAXLK,MINIMUM_MAXLK,LONG_MAX,DEFAULT_MAXLK);
1557   if (exeVar->program->error.code) return LOCK_ERROR_LIST_QTT;
1558
1559   /* FST generation */
1560   if (!cmd->func) cmd->func = exeFindParm(scopeVar->father->prev,ATVALUE_FST);
1561   fstCode = (FST_CODE *)cmd->func->altn;
1562   if (!fstCode) return exeError(exeVar->program,EXE_ERROR_FST,cplElement[cmd->element].text);
1563
1564   /* Avoiding cnt buffer */
1565   invflush(db);
1566
1567   /* Update inverted file */
1568   if (exePrecise(scopeVar->parmList[PARM_RESET]) == PRECISE_OFF)
1569      ifupd_reset = 0;
1570   if (ifupdat(db,VMFRmfn(idx),VMFRmfn(idx),db,fstCode,
1571      scopeVar->stwTable,maxLinks,maxLinks,IFUPISIS,IFUPWRIT))
1572      lockError = LOCK_ERROR_IU_DENIED;
1573   ifupd_reset = 2; /* ciifu.c */
1574
1575   /* Return lock error code */
1576   return lockError;
1577
1578} /* exeInvert */
1579
1580/* ============================================================= exeLockDate */
1581char *exeLockDate(char *buff,           /* return buffer */
1582                  time_t *secsNow)      /* return seconds */
1583{
1584   struct tm *tp;    /* time structure pointer */
1585
1586   /* Get current time */
1587   time(secsNow);
1588   tp = localtime(secsNow);
1589
1590   /* Set joint date buffer */
1591   sprintf(buff,"%04d%02d%02d%02d%02d",1900+tp->tm_year,tp->tm_mon+1,
1592      tp->tm_mday,tp->tm_hour,tp->tm_min);
1593
1594   /* Return buffer */
1595   return buff;
1596
1597} /* exeLockDate */
1598
1599/* =============================================================== exeExpire */
1600BOOLEAN exeExpire(EXE_VAR *exeVar,           /* execution variables */
1601                  SCOPE_VAR *scopeVar,       /* scope variables */
1602                  long idxLock,              /* lock record index */
1603                  LOCK_ERROR *lockError)     /* lock error */
1604{
1605   long expireValue;       /* expire value in seconds */
1606   time_t secsNow;         /* time seconds */
1607   long lockTime;          /* recorded lock time */
1608   long gapTime;           /* current time less recorded time */
1609
1610   /* Check if expire was informed */
1611   if (!scopeVar->parmList[PARM_EXPIRE]) return FALSE;
1612   if (!*(scopeVar->parmList[PARM_EXPIRE])) return FALSE;
1613   expireValue = atol(scopeVar->parmList[PARM_EXPIRE]);
1614
1615   /* Get recorded lock time */
1616   if (!eci_sub_field('x',eci_field(idxLock,scopeVar->defineList[PRECISE_LOCK].tag,1,exeVar->buff))) {
1617      /* Missing recorded lock time */
1618      *lockError = LOCK_ERROR_ID_DENIED;
1619
1620   } else {
1621
1622      /* Check difference between recorded lock time and expire limit */
1623      lockTime = atol(exeVar->buff);
1624      exeLockDate(exeVar->buff,&secsNow);
1625      gapTime = (long)difftime(secsNow,(time_t)lockTime);
1626      if (gapTime <= expireValue) {
1627         *lockError = LOCK_ERROR_NOT_EXPIRED;
1628         return FALSE; /* [0.9g] */
1629      }
1630
1631   }
1632
1633   /* Return expire checked */
1634   return TRUE;
1635
1636} /* exeExpire */
1637
1638/* ================================================================= exeLock */
1639EXE_ERROR exeLock(EXE_VAR *exeVar,           /* execution variables */
1640                  SCOPE_VAR *scopeVar,       /* scope variables */
1641                  long idxControl,           /* control record index */
1642                  long mfn,                  /* MFN */
1643                  char *lockId,              /* Lock identification */
1644                  LOCK_ERROR *lockError)     /* lock error */
1645{
1646   long idxLock;           /* lock record index */
1647   time_t secsNow;         /* time seconds */
1648   char *p;                /* auxiliary string buffer pointer */
1649   BOOLEAN updtLock = FALSE;  /* update lock identification field [0.9g] */
1650
1651   /* Get lock record index */
1652   idxLock = exeWorkRecord(exeVar);
1653   if (idxLock < 0L) return exeVar->program->error.code;
1654
1655   /* Try to lock the record */
1656   eci_lock(idxLock,VRDBname(idxControl),mfn,RLOCK);
1657
1658   /* Get recorded lock identification */
1659   if (eci_sub_field('i',eci_field(idxLock,scopeVar->defineList[PRECISE_LOCK].tag,1,exeVar->buff))) {
1660
1661      /* Compare lock identification: recorded X current, if different: lock error */
1662      if (strcmp(exeVar->buff,lockId) != 0) {
1663         if (!exeExpire(exeVar,scopeVar,idxLock,lockError)) {
1664            /* locked and not expired: denied */
1665            *lockError = LOCK_ERROR_ID_DENIED;
1666         } else {
1667            /* locked, but expired: update lock identification field [0.9g] */
1668            updtLock = TRUE;
1669         }
1670      } else {
1671         /* lock again for this user: update lock identification field [0.9g] */
1672         updtLock = TRUE;
1673      }
1674
1675      /* avoid fatal record not locked, simulate record locked [0.9g] */
1676      if (updtLock) {
1677         VRECgdbl(idxLock) = VRECgdbw(idxLock) = (FFI)0-VMFRmfrl(idxLock);
1678      }
1679
1680   } else
1681
1682      /* Check if it is locked for another user */
1683      if (VRECrc(idxLock) != RCNORMAL && VRECrc(idxLock) != RCLDEL)
1684         /* Locked for another user */
1685         *lockError = LOCK_ERROR_R_DENIED;
1686      else
1687         /* Not locked: update lock identification field */
1688         updtLock = TRUE;
1689
1690   /* Update lock identification field */
1691   if (updtLock) {
1692
1693      /* Prepare lock data */
1694      exeLockDate(exeVar->buff,&secsNow);
1695      p = strdup(exeVar->buff);
1696      sprintf(exeVar->buff,"^i%s^t%s^x%ld",lockId,p,secsNow);
1697      efc_free(p);
1698      eci_field_MT(&(exeVar->program->error),idxLock,scopeVar->defineList[PRECISE_LOCK].tag,exeVar->buff);
1699
1700      /* Record update the lock identification */
1701      VRECwlock(idxLock) = WLOCK;
1702      if (recupdat(idxControl,idxLock) == RCLOCK) {
1703         eci_unlock(idxLock,mfn,RLOCK);
1704         *lockError = LOCK_ERROR_U_DENIED;
1705      }
1706
1707   }
1708
1709   /* Garbage collector */
1710   eci_rec_free(idxLock);
1711
1712   /* Return no error */
1713   return EXE_ERROR_OK;
1714
1715} /* exeLock */
1716
1717/* ================================================================ exeWrite */
1718EXE_ERROR exeWrite(EXE_VAR *exeVar,          /* execution variables */
1719                   SCOPE_VAR *scopeVar,      /* scope variables */
1720                   CPL_COMMAND *cmd,         /* current command */
1721                   char *text)               /* command text */
1722{
1723   char *db;                                 /* data base name */
1724   CPL_ATVALUE mfnValue;                     /* MFN option value */
1725   long mfn = 0L;                            /* MFN */
1726   char *lockId = NULL;                      /* lock identification */
1727   CPL_ATVALUE writeValue;                   /* write option value */
1728   long idxControl;                          /* control record index */
1729   LOCK_ERROR lockError = LOCK_ERROR_OK;     /* lock error code */
1730   EXE_ERROR errorCode = EXE_ERROR_OK;       /* error code */
1731
1732   /* Check hierarchic */
1733   if (scopeVar->father->element != ELEMENT_UPDATE)
1734      return exeError(exeVar->program,EXE_ERROR_MISSING,cplElement[ELEMENT_UPDATE].text);
1735
1736   /* Get database name, MFN and lock identification, if missing: error */
1737   db = scopeVar->parmList[PARM_DB];
1738   mfnValue = exePrecise(scopeVar->parmList[PARM_MFN]);
1739   if (mfnValue != PRECISE_NEW && mfnValue != PRECISE_GETNEW) {
1740      mfn = atol(scopeVar->parmList[PARM_MFN]);
1741      if (mfn <= 0L)
1742         exeError(exeVar->program,EXE_ERROR_INVALID,cplAtValue[ATVALUE_MFN].text);
1743      lockId = exeRequiredParm(exeVar,scopeVar,ATVALUE_LOCKID);
1744      if (!lockId) return exeVar->program->error.code;
1745      if (!exeRequiredDefine(exeVar,scopeVar,PRECISE_LOCK))
1746         return exeVar->program->error.code;
1747   }
1748   writeValue = exePrecise(text);
1749
1750   /* Check lock and status defines, if missing: error */
1751   if (!exeRequiredDefine(exeVar,scopeVar,PRECISE_STATUS))
1752      return exeVar->program->error.code;
1753
1754   /* Get control record index */
1755   idxControl = exeNewRecord(exeVar,sizeof(M0STRU));
1756   if (idxControl < 0L) return exeVar->program->error.code;
1757
1758   /* Delete lock control and lock status fields */
1759   if (scopeVar->defineList[PRECISE_LOCK].tag)
1760      if (writeValue != PRECISE_WNOUNLOCK)
1761         eci_field_D(&(exeVar->program->error),scopeVar->idxCurr,scopeVar->defineList[PRECISE_LOCK].tag);
1762   eci_field_D(&(exeVar->program->error),scopeVar->idxCurr,scopeVar->defineList[PRECISE_STATUS].tag);
1763
1764   /* Data entry lock */
1765   if (eci_lock(idxControl,db,0L,DELOCK)) lockError = LOCK_ERROR_DE_DENIED;
1766   else {
1767
1768      if (mfnValue == PRECISE_NEW || mfnValue == PRECISE_GETNEW) {
1769
1770         /* Append new record */
1771         VMFRmfn(scopeVar->idxCurr) = 0L;
1772         VRECwlock(scopeVar->idxCurr) = WUNLOCK|NEWREC;
1773         if (recupdat(idxControl,scopeVar->idxCurr) == RCLOCK) lockError = LOCK_ERROR_R_DENIED;
1774         VMFRmfn(scopeVar->idxCurr) = VMF0nxtmfn(idxControl)-1L;
1775
1776         /* Update inverted file */
1777         if (lockError == LOCK_ERROR_OK)
1778            lockError = exeInvert(exeVar,scopeVar,cmd,db,scopeVar->idxCurr);
1779
1780      } else {
1781
1782         if (writeValue == PRECISE_WLOCK) {
1783
1784            /* Lock current record */
1785            errorCode = exeLock(exeVar,scopeVar,idxControl,VMFRmfn(scopeVar->idxCurr),lockId,&lockError);
1786
1787         } else {
1788
1789            /* Lock specified mfn record */
1790            errorCode = exeLock(exeVar,scopeVar,idxControl,mfn,lockId,&lockError);
1791            if (!errorCode && !lockError) {
1792
1793               /* Delete lock field and lock status field */
1794               if (writeValue != PRECISE_WNOUNLOCK)
1795                  eci_field_D(&(exeVar->program->error),scopeVar->idxCurr,scopeVar->defineList[PRECISE_LOCK].tag);
1796               eci_field_D(&(exeVar->program->error),scopeVar->idxCurr,scopeVar->defineList[PRECISE_STATUS].tag);
1797
1798               /* Forcing RLOCK: record is locked */
1799               VRECgdbl(scopeVar->idxCurr) = VRECgdbw(scopeVar->idxCurr) = (FFI)0-VMFRmfrl(scopeVar->idxCurr);
1800
1801               /* Record update */
1802               VRECwlock(scopeVar->idxCurr) = writeValue == PRECISE_WNOUNLOCK ? WLOCK : WUNLOCK;
1803               VMFRmfn(scopeVar->idxCurr) = mfn;
1804               VMFRstatus(scopeVar->idxCurr) = (writeValue == PRECISE_WDELETE) ? DELETED : ACTIVE;
1805               if (recupdat(idxControl,scopeVar->idxCurr) == RCLOCK) lockError = LOCK_ERROR_R_DENIED;
1806               VRECrc(scopeVar->idxCurr) = (writeValue == PRECISE_WDELETE) ? RCLDEL : RCNORMAL;
1807
1808               /* Update inverted file */
1809               if (lockError == LOCK_ERROR_OK)
1810                  lockError = exeInvert(exeVar,scopeVar,cmd,db,scopeVar->idxCurr);
1811
1812            }
1813
1814         }
1815
1816      }
1817
1818      /* Data entry unlock */
1819      eci_unlock(idxControl,0L,DELOCK);
1820
1821   }
1822
1823   /* Garbage collector */
1824   eci_rec_free(idxControl);
1825
1826   /* Field update error code */
1827   if (!errorCode) {
1828      scopeVar->defineList[PRECISE_STATUS].value = (long)lockError;
1829      errorCode = exeDefineField(exeVar,scopeVar->idxCurr,&(scopeVar->defineList[PRECISE_STATUS]));
1830   }
1831   if (errorCode) return errorCode;
1832
1833   /* Return no error */
1834   scopeVar->defineList[PRECISE_RECSTAT].value = (long)VRECrc(scopeVar->idxCurr);
1835   errorCode = exeDefineField(exeVar,scopeVar->idxCurr,&(scopeVar->defineList[PRECISE_RECSTAT]));
1836   return errorCode;
1837
1838} /* exeWrite */
1839
1840/* =============================================================== exeExport */
1841EXE_ERROR exeExport(EXE_VAR *exeVar,            /* execution variables */
1842                   SCOPE_VAR *scopeVar)         /* scope variables */
1843{
1844   char *fileName;            /* export file name */
1845   char *p;                   /* auxiliary string buffer pointer */
1846
1847   /* If not opened yet, get file name parameter and open export file */
1848   if (!scopeVar->export) {
1849      fileName = exeRequiredParm(exeVar,scopeVar,ATVALUE_FILE);
1850      if (!fileName) return exeVar->program->error.code;
1851      p = dbxcipar(NULL,fileName,'=');
1852
1853      /* Export to the standard output. iAH 26.Jun.2000
1854      scopeVar->export = fopen(p,"w");
1855      */
1856      if (strcmp(p,"STDOUT")==0) scopeVar->export = stdout;
1857      else scopeVar->export = fopen(p,"w");
1858
1859      if (scopeVar->export == NULL)
1860         return exeError(exeVar->program,EXE_ERROR_FILE,p);
1861      scopeVar->exportType = exePrecise(scopeVar->parmList[PARM_TYPE]);
1862   }
1863
1864   /* If required: add MFN in a field */
1865   if (scopeVar->defineList[PARM_MFN].tag)
1866      eci_field_MN(&(exeVar->program->error),scopeVar->idxCurr,scopeVar->defineList[PARM_MFN].tag,VMFRmfn(scopeVar->idxCurr));
1867
1868   /* Select export type */
1869   switch (scopeVar->exportType) {
1870
1871   case PRECISE_HLINE :
1872      /* HLine export */
1873      eci_export_hline(scopeVar->export,scopeVar->idxCurr);
1874      break;
1875
1876   case PRECISE_VLINE :
1877      /* VLine export */
1878      eci_export_vline(scopeVar->export,scopeVar->idxCurr);
1879      break;
1880
1881   case PRECISE_ISO2709_CRLF :
1882      /* ISO 2709 forcing CRLF export */
1883      if (!eci_export_iso2709(scopeVar->export,scopeVar->idxCurr,TRUE))
1884         return exeError(exeVar->program,EXE_ERROR_ALLOC,NULL);
1885      break;
1886
1887   case PRECISE_MARC21:
1888      if (!eci_export_iso2709_marc(scopeVar->export,scopeVar->idxCurr))
1889         return exeError(exeVar->program,EXE_ERROR_ALLOC,NULL);
1890      break;
1891
1892   default :
1893      /* ISO 2709 export */
1894      if (!eci_export_iso2709(scopeVar->export,scopeVar->idxCurr,FALSE))
1895         return exeError(exeVar->program,EXE_ERROR_ALLOC,NULL);
1896      break;
1897
1898   } /* switch */
1899
1900   /* Return no error */
1901   return EXE_ERROR_OK;
1902}
1903
1904/* =============================================================== exeImport */
1905ECI_ERROR exeImport(EXE_VAR *exeVar,         /* execution variables */
1906                    SCOPE_VAR *scopeVar,     /* scope variables */
1907                    FILE *importFile,        /* import file type value */
1908                    PRECISE_LIST typeValue,  /* import file type value */
1909                    long mfn)                /* current import MFN */
1910{
1911   ECI_ERROR errorCode;       /* error code */
1912   char delimiter = '|';
1913
1914   /* Set current MFN */
1915   VMFRmfn(scopeVar->idxCurr) = mfn;
1916
1917   /* Check import type */
1918   switch (typeValue) {
1919
1920   case PRECISE_HLINE:
1921   case PRECISE_VLINE:
1922      /* HLINE and VLINE import */
1923      errorCode = eci_import_hvline(&(exeVar->program->error),importFile,scopeVar->idxCurr,exeVar->buff);
1924      break;
1925
1926   case PRECISE_RLINE:
1927      /* RLINE import */
1928      if (scopeVar->parmList[PARM_DELIMITER])
1929         if (*(scopeVar->parmList[PARM_DELIMITER]))
1930            delimiter = *(scopeVar->parmList[PARM_DELIMITER]);
1931      errorCode = eci_import_rline(&(exeVar->program->error),importFile,delimiter,scopeVar->idxCurr,exeVar->buff);
1932      break;
1933
1934   case PRECISE_MARC21:
1935      /* ISO2709/MARC21 import */
1936      errorCode = eci_import_iso2709_marc(&(exeVar->program->error),importFile,scopeVar->idxCurr,exeVar->buff);
1937      break;
1938
1939   default:
1940      /* ISO2709 import */
1941      errorCode = eci_import_iso2709(&(exeVar->program->error),importFile,scopeVar->idxCurr,exeVar->buff);
1942      break;
1943
1944   } /* switch */
1945
1946   /* Check error code */
1947   if (errorCode) return errorCode;
1948
1949   /* Check field with MFN option */
1950   if (!scopeVar->defineList[PRECISE_MFN].tag) return errorCode;
1951
1952   /* Get field with import MFN */
1953   *exeVar->buff = '\0';
1954   eci_field(scopeVar->idxCurr,scopeVar->defineList[PRECISE_MFN].tag,1,exeVar->buff);
1955   scopeVar->defineList[PRECISE_MFN].value = atol(exeVar->buff);
1956   if (scopeVar->defineList[PRECISE_MFN].value < 1L)
1957      return efc_error(&(exeVar->program->error),ECI_ERROR_IMPORT,cplAtValue[ATVALUE_MFN].text);
1958   VMFRmfn(scopeVar->idxCurr) = mfn;
1959
1960   /* Return error code */
1961   return errorCode;
1962
1963} /* exeImport */
1964
1965/* ================================================================= exeList */
1966EXE_ERROR exeList(EXE_VAR *exeVar,        /* execution variables */
1967                  SCOPE_VAR *scopeVar,    /* scope variables */
1968                  CPL_COMMAND *cmd,       /* first command */
1969                  char *text)             /* identifier text */
1970{
1971   long freqValue;         /* frequency load value */
1972
1973   /* Check action attribute */
1974   if (!cmd->attributeList[ATTRIBUTE_ACTION].text)
1975      return exeError(exeVar->program,EXE_ERROR_MISSING,cplAttribute[ATTRIBUTE_ACTION].text);
1976
1977   /* Evaluate action attribute */
1978   switch (cmd->attributeList[ATTRIBUTE_ACTION].atValue) {
1979
1980   case ATVALUE_DELETE:
1981      /* Delete list */
1982      freq_free(exeVar->freq.head);
1983      memset(&(exeVar->freq),0x00,(size_t)sizeof(FREQLIST_VAR));
1984      break;
1985
1986   case ATVALUE_LOAD:
1987      /* Get load type attribute, list load parameter */
1988      if (!cmd->attributeList[ATTRIBUTE_ACTION].text)
1989         return exeError(exeVar->program,EXE_ERROR_MISSING,cplAttribute[ATTRIBUTE_TYPE].text);
1990
1991      /* Get frequency sum value */
1992      freqValue = 1L;
1993      if (scopeVar->parmList[PARM_FREQSUM])
1994         freqValue = atol(scopeVar->parmList[PARM_FREQSUM]);
1995      if (freqValue <= 0L)
1996         return exeError(exeVar->program,EXE_ERROR_INVALID,cplAtValue[ATVALUE_FREQSUM].text);
1997
1998      /* Load item */
1999      if (!freq_load(&(exeVar->freq),text,freqValue,
2000         (BOOLEAN)(cmd->attributeList[ATTRIBUTE_TYPE].atValue == ATVALUE_LIST),
2001         (BOOLEAN)(cmd->attributeList[ATTRIBUTE_TYPE].atValue == ATVALUE_SORT)))
2002         return exeError(exeVar->program,EXE_ERROR_ALLOC,text);
2003
2004      break;
2005
2006   default :
2007      /* Invalid action attribute */
2008      return exeError(exeVar->program,EXE_ERROR_INVALID,cmd->attributeList[ATTRIBUTE_ACTION].text);
2009
2010   } /* switch */
2011
2012   /* Return no error */
2013   return EXE_ERROR_OK;
2014
2015} /* exeList */
2016
2017/* ========================================================== exeExtractSave */
2018EXE_ERROR exeExtractSave(EXE_VAR *exeVar,          /* execution variables */
2019                         SCOPE_VAR *scopeVar,      /* scope variables */
2020                         char *text)               /* extract list */
2021{
2022   EFC_SPLIT_LINES table;                 /* split line structure */
2023   long line;                             /* line index */
2024   char *db;                              /* database name */
2025   long idxControl = -1L;                 /* control record index */
2026   long idx = -1L;                        /* auxiliary record index */
2027   long len;                              /* auxiliary string lenght */
2028   char *p;                               /* auxiliary string pointer */
2029
2030   long mfn;
2031   long tag;
2032   long occ;
2033   long count;
2034
2035   EXE_ERROR errorCode = EXE_ERROR_OK;    /* error code */
2036
2037   /* Check mandatory parameters */
2038
2039   /*
2040   db = exeRequiredParm(exeVar,scopeVar,ATVALUE_KEYSDB);
2041   if (!db) return exeVar->program->error.code;
2042   */
2043
2044   /* if ATVALUE_KEYSDB is present: generate extraction data base
2045      else: store all fields generated by the fst extraction (like mx)
2046   */
2047   db = scopeVar->parmList[PARM_KEYSDB];
2048
2049   if (db)
2050   {
2051      /* need Isis_Key define */
2052      if (!exeRequiredDefine(exeVar,scopeVar,PRECISE_KEY))
2053      {
2054         return exeError(exeVar->program,EXE_ERROR_MISSING,preciseList[PRECISE_KEY]);
2055      }
2056   }
2057
2058
2059   /* Split lines */
2060   if (efc_split_lines(&table,text) < 0L)
2061      return exeError(exeVar->program,EXE_ERROR_ALLOC,text);
2062
2063   if (db)
2064   {
2065      /* Get control record index */
2066      idxControl = exeNewRecord(exeVar,sizeof(M0STRU));
2067      if (idxControl < 0L) return EXE_ERROR_ALLOC;
2068      record(idxControl,db,0L);
2069
2070      /* Get update record index */
2071      idx = exeWorkRecord(exeVar);
2072      if (idx < 0L) return EXE_ERROR_ALLOC;
2073   }
2074
2075   /* Loop all lines */
2076   for (line = 0L; line < table.qtt; line++) {
2077
2078      /* Check error code */
2079      if (errorCode) break;
2080
2081      /* Check FST line */
2082      if (!*table.list[line].text) {
2083         errorCode = exeError(exeVar->program,EXE_ERROR_EXTRACT,NULL);
2084         break;
2085      }
2086
2087      /* Reverse find subfield m */
2088      len = strlen(table.list[line].text)-1;
2089      for (p = table.list[line].text+len; len; len--,p--)
2090         if (*p == '^')
2091            if (*(p+1) == 'm') break;
2092
2093      /* Extract posting information */
2094      sscanf(p,"^m%ld^t%ld^o%ld^c%ld",&mfn,&tag,&occ,&count);
2095
2096      /* Check if the extraction is to placed at the scope index */
2097      if (!db)
2098      {
2099         /* Add field to the current scope */
2100         if (eci_field_AT(&(exeVar->program->error),scopeVar->idxCurr,tag,table.list[line].text))
2101         {
2102            errorCode = exeError(exeVar->program,EXE_ERROR_FIELD,table.list[line].text);
2103            break;
2104         }
2105         continue;
2106      }
2107
2108      /* Truncate key */
2109      if (len > LE2) len = LE2;
2110      *(table.list[line].text+len) = '\0';
2111
2112      /* Format fixed key */
2113      sprintf(exeVar->buff,"%d|%-*s|%7ld|%5ld|%4ld|%4ld",
2114         len <= LE1 ? 1 : 2,
2115         len <= LE1 ? LE1 : LE2,eci_uctab(table.list[line].text),
2116         mfn,tag,occ,count);
2117
2118      /* Add field */
2119      if (eci_field_MT(&(exeVar->program->error),idx,scopeVar->defineList[PRECISE_KEY].tag,exeVar->buff)) {
2120         errorCode = exeError(exeVar->program,EXE_ERROR_FIELD,table.list[line].text);
2121         break;
2122      }
2123
2124      /* Add record */
2125      VMFRmfn(idx) = VMF0nxtmfn(idxControl);
2126      if (recupdat(idxControl,idx) != RCNORMAL) {
2127         errorCode = exeError(exeVar->program,EXE_ERROR_EXTRACT,table.list[line].text);
2128         break;
2129      }
2130
2131   } /* for */
2132
2133   /* Garbage collector */
2134   efc_split_lines_free(&table);
2135   if (idxControl >= 0L) eci_rec_free(idxControl);
2136   if (idx >= 0L) eci_rec_free(idx);
2137
2138   /* Return error code */
2139   return errorCode;
2140
2141} /* exeExtractSave */
2142
2143/* ============================================================== exeExtract */
2144EXE_ERROR exeExtract(EXE_VAR *exeVar,        /* execution variables */
2145                     SCOPE_VAR *scopeVar,    /* scope variables */
2146                     CPL_COMMAND *cmd)       /* current command */
2147{
2148   char *fst;           /* FST parameter */
2149   long maxLinks;       /* maximum inverted links */
2150   FST_CODE *fstCode;   /* FST code */
2151   char *text;          /* text list */
2152   char *lnk1p = NULL;  /* FST generation parameter */
2153   char *lnk2p = NULL;  /* FST generation parameter */
2154   long qtylk1;         /* FST generation parameter */
2155   long qtylk2;         /* FST generation parameter */
2156
2157   /* Check mandatory parameters */
2158   fst = exeRequiredParm(exeVar,scopeVar,ATVALUE_FST);
2159   if (!fst) return exeVar->program->error.code;
2160
2161   /* Set maximum links */
2162   maxLinks = exeNumber(exeVar,scopeVar,PARM_MAXLK,MINIMUM_MAXLK,LONG_MAX,DEFAULT_MAXLK);
2163   if (exeVar->program->error.code) return exeVar->program->error.code;
2164
2165   /* FST generation */
2166   if (!cmd->func)
2167      cmd->func = exeFindParm(scopeVar->father->prev,ATVALUE_FST);
2168   fstCode = (FST_CODE *)cmd->func->altn;
2169   if (!fstCode) return exeError(exeVar->program,EXE_ERROR_FST,cplElement[cmd->element].text);
2170
2171   /* FST generation */
2172   *exeVar->buff = '\0';
2173   fst_hdrp = exeVar->buff; fst_hdrx = EXE_REC_SIZE-1; fst_hdrt = TRUE;
2174   fst_inter(fstCode,scopeVar->idxCurr,scopeVar->stwTable,
2175      &lnk1p,maxLinks,&lnk2p,maxLinks,&qtylk1,&qtylk2);
2176   efc_free(lnk1p);  /* 04.Aug.1999 fst_inter allocated and doesn't deallocated */
2177   efc_free(lnk2p);  /* 04.Aug.1999 */
2178   fst_hdrp = NULL; fst_hdrx = 0; fst_hdrt = FALSE;
2179   if (fst_error)
2180      return exeError(exeVar->program,EXE_ERROR_FST,fst_errp);
2181
2182   /* Extraction save */
2183   text = strdup(exeVar->buff);
2184   if (exeExtractSave(exeVar,scopeVar,text))
2185      return exeVar->program->error.code;
2186
2187   /* Garbage collector */
2188   efc_free(text);
2189
2190   /* Return no error */
2191   return EXE_ERROR_OK;
2192
2193} /* exeExtract */
2194
2195/* =========================================================== exeStartScope */
2196void exeStartScope(SCOPE_VAR *scopeVar)         /* scope variables */
2197{
2198
2199   /* Reset all variables */
2200   memset(scopeVar,0x00,sizeof(SCOPE_VAR));
2201
2202   /* No record index indicator */
2203   scopeVar->idxPrev = -1L;
2204   scopeVar->idxRetn = -1L;
2205   scopeVar->idxCurr = -1L;
2206
2207} /* exeStartScope */
2208
2209/* =========================================================== exeScopeClose */
2210void exeScopeClose(SCOPE_VAR *scopeVar)      /* scope variables */
2211{
2212
2213   /* Close previously opened files */
2214   if (scopeVar->export) fclose(scopeVar->export);
2215
2216} /* exeScopeClose */
2217
2218/* ============================================================ exeScopeFree */
2219void exeScopeFree(SCOPE_VAR *scopeVar)    /* scope variables */
2220{
2221   PRECISE_LIST i;      /* auxiliary loop index */
2222
2223   /* Close scope */
2224   exeScopeClose(scopeVar);
2225
2226   /* Garbage collector */
2227   for (i = 0; i < PRECISE_LIST_QTT; i++)
2228      efc_free(scopeVar->defineList[i].text);
2229
2230   /* stop word free */
2231   efc_free(scopeVar->stwTable);
2232
2233   /* Code Guard*/
2234   efc_free(scopeVar->parmList[PARM_KEYFIELD]);
2235   efc_free(scopeVar->parmList[PARM_KEYLENGTH]);
2236   efc_free(scopeVar->parmList[PARM_KEYSDB]);
2237
2238} /* exeScopeFree */
2239
2240/* ========================================================= exeFindFunction */
2241CPL_COMMAND *exeFindFunction(EXE_VAR *exeVar,         /* execution variables */
2242                             CPL_COMMAND *cmdFrom,    /* from command */
2243                             char *callName)          /* function call name */
2244{
2245   CPL_COMMAND *cmd;       /* auxiliary command finder */
2246   CPL_COMMAND *cmdFind;   /* auxiliary command finder for sub-command */
2247
2248   /* No commands */
2249   if (!cmdFrom) return NULL;
2250
2251   /* Loop IsisScript commands, if function element and same attribute name: return cmd */
2252   for (cmd = cmdFrom; cmd; cmd = cmd->next) {
2253
2254      /* Find in sub-commands */
2255      if (cmd->element == ELEMENT_ISISSCRIPT) {
2256         cmdFind = exeFindFunction(exeVar,cmd->sub,callName);
2257         if (cmdFind) return cmdFind;
2258      }
2259
2260      /* Find element function with the exact name */
2261      if (cmd->element != ELEMENT_FUNCTION) continue;
2262      if (strcmp(cmd->attributeList[ATTRIBUTE_NAME].text,callName) == 0)
2263         return cmd;
2264
2265   }
2266
2267   /* Function not found */
2268   return NULL;
2269}
2270
2271/* ================================================================= exeCall */
2272EXE_ERROR exeCall(EXE_VAR *exeVar,           /* execution variables */
2273                   SCOPE_VAR *scopeVar,      /* scope variables */
2274                   CPL_COMMAND *cmd,         /* current command */
2275                   char *text)               /* text parameter */
2276{
2277   SCOPE_VAR localScopeVar;               /* local variables for sub-command */
2278   EXE_ERROR errorCode = EXE_ERROR_OK;    /* error code */
2279
2280   /* Find function */
2281   if (!cmd->func) {
2282    if (!cmd->attributeList[ATTRIBUTE_NAME].text)
2283        {
2284         return exeError(exeVar->program,EXE_ERROR_MISSING,cplAttribute[ATTRIBUTE_NAME].text);
2285      }
2286      cmd->func = exeFindFunction(exeVar,exeVar->program->cmd,cmd->attributeList[ATTRIBUTE_NAME].text);
2287      if (!cmd->func)
2288      {
2289         return exeError(exeVar->program,EXE_ERROR_MISSING,cmd->attributeList[ATTRIBUTE_NAME].text);
2290      }
2291   }
2292
2293   /* Start scope variables */
2294   exeStartScope(&localScopeVar);
2295
2296   /* Set local variables */
2297   localScopeVar.idxPrev = scopeVar->idxCurr; /* [0.9a] idxPrev */
2298   localScopeVar.idxRetn = scopeVar->idxCurr;
2299   localScopeVar.idxCurr = exeWorkRecord(exeVar);
2300   if (localScopeVar.idxCurr < 0L)
2301      return exeError(exeVar->program,EXE_ERROR_ALLOC,cplElement[cmd->element].text);
2302   localScopeVar.father = cmd;
2303
2304   /* Get function parameter */
2305   if (cmd->func->attributeList[ATTRIBUTE_ACTION].text ||
2306      cmd->func->attributeList[ATTRIBUTE_TAG].text) {
2307      errorCode = exeField(exeVar,scopeVar,scopeVar->idxCurr,localScopeVar.idxCurr,cmd->func,text);
2308   }
2309
2310   /* Call function command */
2311   if (!exeVar->program->error.code) exeGo(exeVar,&localScopeVar,cmd->func->sub);
2312
2313   /* Garbage collector */
2314   exeScopeFree(&localScopeVar);
2315
2316   /* Garbage collector */
2317   eci_rec_free(localScopeVar.idxCurr);
2318
2319   /* Return error code */
2320   return errorCode;
2321
2322} /* exeCall */
2323
2324/* =============================================================== exeReturn */
2325EXE_ERROR exeReturn(EXE_VAR *exeVar,            /* execution variables */
2326                    SCOPE_VAR *scopeVar,        /* scope variables */
2327                    CPL_COMMAND *cmd,           /* current command */
2328                    char *text)                 /* return parameter */
2329{
2330
2331   /* Check scope */
2332   if (scopeVar->idxRetn < 0L)
2333      return exeError(exeVar->program,EXE_ERROR_RETURN,text);
2334
2335   /* Set return parameter */
2336   if (cmd->attributeList[ATTRIBUTE_ACTION].text ||
2337      cmd->attributeList[ATTRIBUTE_TAG].text) {
2338      return exeField(exeVar,scopeVar,scopeVar->idxCurr,scopeVar->idxRetn,cmd,text);
2339   }
2340
2341   /* Return nothing to do */
2342   return EXE_ERROR_OK;
2343
2344} /* exeReturn */
2345
2346/* ============================================================== exeHtmlPft */
2347char *exeHtmlPft(EXE_VAR *exeVar,         /* execution variables */
2348                 SCOPE_VAR *scopeVar,     /* scope variables */
2349                 char *text)              /* Html text */
2350{
2351   char *prefix = "[pft]";       /* format begin */
2352   char *suffix = "[/pft]";      /* format end */
2353   int pfxLength;                /* prefix lenght */
2354   int sfxLength;                /* suffix lenght */
2355   char *p;                      /* auxiliary string pointer */
2356   char *buff;                   /* auxiliary string pointer */
2357
2358   /* Get prefix and suffix parameters */
2359   if (scopeVar->parmList[PARM_PREFIX_HTMLPFT])
2360      if (*(scopeVar->parmList[PARM_PREFIX_HTMLPFT]))
2361         prefix = scopeVar->parmList[PARM_PREFIX_HTMLPFT];
2362   if (scopeVar->parmList[PARM_SUFFIX_HTMLPFT])
2363      if (*(scopeVar->parmList[PARM_SUFFIX_HTMLPFT]))
2364         suffix = scopeVar->parmList[PARM_SUFFIX_HTMLPFT];
2365
2366   /* Set auxiliary variables */
2367   pfxLength = strlen(prefix);
2368   sfxLength = strlen(suffix);
2369   buff = exeVar->buff;
2370
2371   /* Open format literal, loop all characters */
2372   *buff++ = '\'';
2373   for (p = text; *p; p++) {
2374
2375      /* Check if it is the prefix */
2376      if (*p == *prefix)
2377         if (strncmp(p,prefix,pfxLength) == 0) {
2378
2379            /* Close format literal */
2380            strcpy(buff,"\',"); buff += 2;
2381
2382            /* Loop all characters until suffix */
2383            for (p += pfxLength; *p; p++) {
2384
2385               /* Check if it is the suffix, close format literal */
2386               if (*p == *suffix)
2387                  if (strncmp(p,suffix,sfxLength) == 0) {
2388                     strcpy(buff,",\'"); buff += 2;
2389                     p += sfxLength-1;
2390                  break;
2391               }
2392
2393               /* Substitute the corresponding HTML specificattion to format specificattion */
2394               /* This was used to correct the Front Page behaviour
2395               if (*p == '&') {
2396                  if (strncmp(p+1,"lt;",3) == 0)
2397                     { *buff++ = '<'; p += 3; continue; }
2398                  if (strncmp(p+1,"gt;",3) == 0)
2399                     { *buff++ = '>'; p += 3; continue; }
2400                  if (strncmp(p+1,"quot;",5) == 0)
2401                     { *buff++ = '\"'; p += 5; continue; }
2402               }
2403                  ... it mustn't be done by the WXIS */
2404
2405               /* Copy character */
2406               *buff++ = *p;
2407
2408            } /* for */
2409
2410            /* Format substitution end */
2411            continue;
2412
2413         }
2414
2415      /* Substitute format literal specification to the corresponding HTML specification */
2416      if (*p == '\'') {
2417         strcpy(buff,"&#39"); buff += 4;
2418         continue;
2419      }
2420
2421      /* Copy character */
2422      if (*p != '\r') *buff++ = *p;
2423
2424   } /* for */
2425
2426   /* Close format literal, set string buffer end, show buffer */
2427   *buff++ = '\'';
2428   *buff = '\0';
2429
2430   /* Return new buffer copy */
2431   return strdup(exeVar->buff);
2432}
2433
2434/* ================================================================== exePft */
2435EXE_ERROR exePft(EXE_VAR *exeVar,         /* execution variables */
2436                 SCOPE_VAR *scopeVar,     /* scope variables */
2437                 long idxCurr,            /* current index */
2438                 CPL_COMMAND *cmd)        /* current command */
2439{
2440   EXE_FORMAT *fmt;        /* format structure pointer */
2441   char *text;             /* auxiliary text pointer */
2442   char *htmlpft = NULL;   /* auxiliary text pointer */
2443   long fmtError;          /* format error code */
2444
2445   /* If first time, allocate and reset format structure */
2446   if (!cmd->altn) {
2447      cmd->altn = (EXE_FORMAT *)exeNew(exeVar,sizeof(EXE_FORMAT));
2448      if (!cmd->altn)
2449         return exeError(exeVar->program,EXE_ERROR_ALLOC,cplElement[cmd->element].text);
2450      memset(cmd->altn,0x00,sizeof(EXE_FORMAT));
2451   }
2452
2453   /* Cast alternate pointer to format pointer, reset formated text */
2454   fmt = (EXE_FORMAT *)(cmd->altn);
2455   if (cmd->attributeList[ATTRIBUTE_ACTION].atValue != ATVALUE_CONVERT) /* [0.9b] */
2456      fmt->text = efc_free(fmt->text);
2457
2458   /* Reload format if required */
2459   if (cmd->attributeList[ATTRIBUTE_TYPE].atValue == ATVALUE_RELOAD) {
2460      if (fmt->code) fmt_free(fmt->code);
2461      fmt->code = NULL;
2462      if ( fmt->ciXml )
2463      {
2464            cixmlFree(fmt->ciXml);
2465         efc_free(fmt->ciXml);
2466            fmt->ciXml = NULL;
2467      }
2468   }
2469
2470   /* If first time or reload, get format specification */
2471   if (!fmt->code && !fmt->ciXml) {
2472      text = exeText(exeVar,scopeVar,idxCurr,cmd);
2473      if (!text) return EXE_ERROR_OK;
2474      if (cmd->element == ELEMENT_HTMLPFT)
2475      {
2476         text = htmlpft = exeHtmlPft(exeVar,scopeVar,text);
2477      }
2478       if (cmd->element == ELEMENT_ISISXML)
2479    {
2480        text = "";
2481        if ( scopeVar->parmList[PARM_ISISXML_TABLE] )
2482         {
2483                text = strdup(scopeVar->parmList[PARM_ISISXML_TABLE]);
2484             if ( !text )
2485          {
2486                    return exeError(exeVar->program,EXE_ERROR_ALLOC,"PARM_ISISXML_TABLE");
2487            }
2488         }
2489            if ( !fmt->ciXml )
2490         {
2491            fmt->ciXml = (CIXML_STRUCT *)exeNew(exeVar,sizeof(CIXML_STRUCT));
2492            fmt->ciXml->style = CIXML_STYLE_ALL;
2493         }
2494           if ( scopeVar->parmList[PARM_ISISXML_STYLE] )
2495           {
2496                fmt->ciXml->style = atoi(scopeVar->parmList[PARM_ISISXML_STYLE]);
2497            }
2498           if ( cixmlLoad(text,fmt->ciXml,fmt->ciXml->style) != CIXML_ERROR_OK )
2499        {
2500                return exeError(exeVar->program,EXE_ERROR_ALLOC,"cixmlLoad");
2501           }
2502       }
2503   }
2504
2505   /* If first time or reload, compile format specification */
2506   if (!fmt->code && !fmt->ciXml)
2507   {
2508      if (strcmp(text,"ALL") != 0) {
2509         fmtError = fmt_gener(&(fmt->code),text);
2510
2511         /* Check syntax error */
2512         if (fmtError) {
2513
2514            fmt->code = NULL; /* on error: fmt_gener calls fmt_free */
2515            efc_free(htmlpft);
2516
2517            /* If is check return error code and place else execution error */
2518            if (cmd->attributeList[ATTRIBUTE_TYPE].atValue == ATVALUE_CHECK) {
2519               sprintf(exeVar->buff,"%05ld %.256s",fmtError,text+fmt_errof);
2520               fmt->text = strdup(exeVar->buff);
2521               return EXE_ERROR_OK;
2522            } else {
2523               return exeError(exeVar->program,EXE_ERROR_FORMAT,text+fmt_errof);
2524            }
2525
2526         }
2527
2528         /* If is check return no error buffer */
2529         if (cmd->attributeList[ATTRIBUTE_TYPE].atValue == ATVALUE_CHECK) {
2530            sprintf(exeVar->buff,"%05ld",fmtError);
2531            fmt->text = strdup(exeVar->buff);
2532            return EXE_ERROR_OK;
2533         }
2534
2535      }
2536   }
2537
2538   /* [0.9b] Check action convert attribute */
2539   if (cmd->attributeList[ATTRIBUTE_ACTION].atValue == ATVALUE_CONVERT) {
2540      if (htmlpft) {
2541         efc_free(fmt->text);
2542         fmt->text = htmlpft;
2543      }
2544      return EXE_ERROR_OK;
2545   }
2546
2547   /* Gabage collector */
2548   efc_free(htmlpft);
2549   /* If code absent is ALL specification else interpret format code */
2550   if (!fmt->code && !fmt->ciXml)
2551   {
2552    eci_fmt_all(idxCurr,exeVar->buff);
2553   }
2554   else
2555   {
2556    /* isisxml element */
2557    if (cmd->element == ELEMENT_ISISXML)
2558      {
2559        cixmlRun(vrecp[idxCurr],fmt->ciXml,exeVar->buff);
2560      }
2561      else
2562      {
2563        /* pft element */
2564        if (fmt_inter(fmt->code,idxCurr,exeVar->buffSize,exeVar->buff,exeVar->buffSize) < 0L)
2565         {
2566            return exeError(exeVar->program,EXE_ERROR_FORMAT,fmterrxy);
2567         }
2568      }
2569    }
2570
2571   /* Set format result */
2572   fmt->text = strdup(exeVar->buff);
2573
2574   /* Return no error */
2575   return EXE_ERROR_OK;
2576
2577} /* exePft */
2578
2579/* ================================================================ exeText */
2580char *exeText(EXE_VAR *exeVar,         /* execution variables */
2581              SCOPE_VAR *scopeVar,     /* scope variables */
2582              long idxCurr,            /* current index */
2583              CPL_COMMAND *cmd)        /* current command */
2584{
2585   EXE_FORMAT *fmt;     /* format structure pointer */
2586
2587   /* Check sub-command, if absent return statment */
2588   if (!cmd->sub) return cmd->text;
2589
2590   /* Format to get the parameter */
2591   exePft(exeVar,scopeVar,idxCurr,cmd->sub);
2592
2593   /* Check format result */
2594   fmt = (EXE_FORMAT *)(cmd->sub->altn);
2595   if (fmt->text) {
2596       if (*(fmt->text)) {
2597           return fmt->text;
2598       }
2599   }
2600
2601   /* Return no text supplied */
2602   return NULL;
2603
2604} /* exeText */
2605
2606/* ================================================================== exeCmd */
2607CPL_COMMAND *exeCmd(EXE_VAR *exeVar,      /* execution variables */
2608                    SCOPE_VAR *scopeVar,        /* scope variables */
2609                    CPL_COMMAND *cmd)           /* first command */
2610{
2611   char *text;       /* text parameter */
2612
2613   /* Get command parameter */
2614   text = exeText(exeVar,scopeVar,scopeVar->idxCurr,cmd);
2615   if (!text) return cmd;
2616
2617   /* Evaluate element */
2618   switch (cmd->element) {
2619
2620   case ELEMENT_CALL:
2621      /* Call function */
2622      if (exeCall(exeVar,scopeVar,cmd,text)) return cmd;
2623      break;
2624
2625   case ELEMENT_CGITABLE:
2626      /* CGI table list */
2627      if (exeCgiTable(exeVar,scopeVar->idxCurr,text)) return cmd;
2628      break;
2629
2630   case ELEMENT_DEFINE:
2631      /* Define list */
2632      if (exeDefine(exeVar,scopeVar,text)) return cmd;
2633      break;
2634
2635   case ELEMENT_EXPORT:
2636      /* Export record */
2637      exeExport(exeVar,scopeVar);
2638      break;
2639
2640   case ELEMENT_EXTRACT:
2641      /* Extract record keys */
2642      if (exeExtract(exeVar,scopeVar,cmd)) return cmd;
2643      break;
2644
2645   case ELEMENT_FIELD:
2646      /* Field action */
2647      exeField(exeVar,scopeVar,scopeVar->idxCurr,scopeVar->idxCurr,cmd,text);
2648      break;
2649
2650   case ELEMENT_FILE:
2651      /* File action */
2652      exeFile(exeVar,scopeVar,cmd,text);
2653      break;
2654
2655   case ELEMENT_FLOW:
2656      /* Flow shotcut */
2657      exeFlow(exeVar,scopeVar,cmd,text);
2658      break;
2659
2660   case ELEMENT_LIST:
2661      /* List item */
2662      exeList(exeVar,scopeVar,cmd,text);
2663      break;
2664
2665   case ELEMENT_PROC:
2666      /* Field update specification format */
2667      if (eci_field_update(&(exeVar->program->error),scopeVar->idxCurr,text)) {
2668         exeError(exeVar->program,EXE_ERROR_PROC,NULL);
2669         return cmd;
2670      }
2671      break;
2672
2673   case ELEMENT_RETURN:
2674      /* Return from function */
2675      exeReturn(exeVar,scopeVar,cmd,text);
2676      return NULL; /* [0.9d] */
2677
2678   case ELEMENT_TRACE:
2679      /* Trace commands */
2680      exeVar->trace = exePrecise(text);
2681      if (exeVar->trace != PRECISE_ON && exeVar->trace != PRECISE_BR &&
2682          exeVar->trace != PRECISE_TABLE) exeVar->trace = PRECISE_OFF;
2683
2684      if (exeVar->trace == PRECISE_OFF) {
2685
2686         if (strcmp(text,"dbxtrace") == 0) dbxtrace = 1; /* dbxopen/dbxcipar trace */
2687         if (strcmp(text,"rectrace") == 0) rectrace = 1; /* rec RESTRACE runtime switch */
2688         if (strcmp(text,"dectrace") == 0) dectrace = 1; /* decoread()/recdeco() runtime switch  */
2689         if (strcmp(text,"trmtrace") == 0) trmtrace = 1; /* trm TRSTRACE runtime switch */
2690#if !CIB71
2691         if (strcmp(text,"b50trace") == 0) b50trace = 1; /* b50 RUXTRACE runtime switch */
2692#else /* CIB71 */
2693         if (strcmp(text,"b70trace") == 0) b70trace = 1; /* b50 RUXTRACE runtime switch */
2694#endif /* CIB71 */
2695         if (strcmp(text,"fmttrace") == 0) fmttrace = 1; /* fmt runtime switch */
2696         if (strcmp(text,"fsttrace") == 0) fsttrace = 1; /* fst FSSTRACE runtime switch */
2697         if (strcmp(text,"multrace") == 0) multrace = 1; /* upd MULTRACE runtime switch */
2698
2699         if (strcmp(text,"-dbxtrace") == 0) dbxtrace = 0;   /* dbxopen/dbxcipar trace */
2700         if (strcmp(text,"-rectrace") == 0) rectrace = 0;   /* rec RESTRACE runtime switch */
2701         if (strcmp(text,"-dectrace") == 0) dectrace = 0;   /* decoread()/recdeco() runtime switch  */
2702         if (strcmp(text,"-trmtrace") == 0) trmtrace = 0;   /* trm TRSTRACE runtime switch */
2703#if !CIB71
2704         if (strcmp(text,"-b50trace") == 0) b50trace = 0;   /* b50 RUXTRACE runtime switch */
2705#else /* CIB71 */
2706         if (strcmp(text,"-b70trace") == 0) b70trace = 0;   /* b50 RUXTRACE runtime switch */
2707#endif /* CIB71 */
2708         if (strcmp(text,"-fmttrace") == 0) fmttrace = 0;   /* fmt runtime switch */
2709         if (strcmp(text,"-fsttrace") == 0) fsttrace = 0;   /* fst FSSTRACE runtime switch */
2710         if (strcmp(text,"-multrace") == 0) multrace = 0;   /* upd MULTRACE runtime switch */
2711
2712      }
2713
2714      break;
2715
2716   case ELEMENT_WRITE:
2717      /* Write record */
2718      exeWrite(exeVar,scopeVar,cmd,text);
2719      break;
2720
2721   default :
2722      /* Invalid option */
2723      exeError(exeVar->program,EXE_ERROR_UNDEFINED,cplElement[cmd->element].text);
2724      return cmd;
2725
2726   } /* switch */
2727
2728   /* return command */
2729   return cmd;
2730
2731} /* exeCmd */
2732
2733/* ================================================================= exeParm */
2734void exeParm(EXE_VAR *exeVar,             /* execution variables */
2735             SCOPE_VAR *scopeVar,         /* scope variables */
2736             CPL_COMMAND *cmd)            /* current command */
2737{
2738   PARM_LIST parmIndex;             /* parameter index */
2739   FST_CODE *fstCode;               /* FST code */
2740   char *p;                         /* auxiliary string pointer */
2741   int tag;                         /* field number */
2742
2743   /* Get parameter text */
2744   parmIndex = atValueParm[cmd->attributeList[ATTRIBUTE_NAME].atValue];
2745   scopeVar->parmList[parmIndex] = exeText(exeVar,scopeVar,scopeVar->idxCurr,cmd);
2746   if (parmIndex == PARM_SORT) scopeVar->parmList[parmIndex] = "void";
2747   if (!scopeVar->parmList[parmIndex]) return;
2748
2749   /* Evaluate parameter option */
2750   switch (parmIndex) {
2751
2752   case PARM_ACTAB:
2753      /* Alphabetic character table */
2754      if (eci_set_actab(&(exeVar->program->error),scopeVar->parmList[parmIndex])) {
2755         exeError(exeVar->program,EXE_ERROR_ACTAB,NULL);
2756         return;
2757      }
2758      break;
2759
2760   case PARM_BUFFERSIZE:
2761      /* Reallocate common string buffer area, if error return */
2762      exeVar->buffSize = atol(scopeVar->parmList[parmIndex]);
2763      efc_free(exeVar->buff);
2764      exeVar->buff = exeNew(exeVar,exeVar->buffSize);
2765      if (!exeVar->buff) {
2766         exeError(exeVar->program,EXE_ERROR_ALLOC,scopeVar->parmList[parmIndex]);
2767         return;
2768      }
2769      break;
2770
2771   case PARM_CIPAR:
2772      /* CISIS file assignment table */
2773      dbxcdcip = efc_strrepl(dbxcdcip,scopeVar->parmList[parmIndex]);
2774      break;
2775
2776   case PARM_FST:
2777      /* FST generation */
2778      fstCode = (FST_CODE *)cmd->altn;
2779      if (fstCode) fst_free(fstCode);
2780      fst_gener(&fstCode,scopeVar->parmList[PARM_FST]);
2781
2782      if (fst_error) {
2783
2784         if (cmd->attributeList[ATTRIBUTE_TYPE].atValue == ATVALUE_CHECK) {
2785            sprintf(exeVar->buff,"%05ld %.256s",fst_error,fst_errp);
2786            for (p = exeVar->buff; *p; p++) {
2787               if (*p == '\r' || *p == '\n') {
2788                  *p = '\0';
2789                  break;
2790               }
2791            }
2792            tag = atoi(cmd->attributeList[ATTRIBUTE_TAG].text);
2793            if (tag <= 0) {
2794               exeError(exeVar->program,EXE_ERROR_INVALID,cplAttribute[ATTRIBUTE_TAG].text);
2795               return;
2796            }
2797            if (eci_field_MT(&(exeVar->program->error),scopeVar->idxCurr,tag,exeVar->buff))
2798               exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
2799
2800         } else {
2801
2802            exeError(exeVar->program,EXE_ERROR_FST,fst_errp);
2803
2804         }
2805         return;
2806
2807      } else {
2808
2809         if (cmd->attributeList[ATTRIBUTE_TYPE].atValue == ATVALUE_CHECK) {
2810            sprintf(exeVar->buff,"%05ld",fst_error);
2811            tag = atoi(cmd->attributeList[ATTRIBUTE_TAG].text);
2812            if (tag <= 0) {
2813               exeError(exeVar->program,EXE_ERROR_INVALID,cplAttribute[ATTRIBUTE_TAG].text);
2814               return;
2815            }
2816            if (eci_field_MT(&(exeVar->program->error),scopeVar->idxCurr,tag,exeVar->buff))
2817               exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
2818         }
2819
2820      }
2821      cmd->altn = fstCode;
2822      break;
2823
2824   case PARM_STW:
2825      /* Load stop word, if required */
2826      if (scopeVar->parmList[PARM_STW]) {
2827         int wordsLoaded;
2828         efc_free(scopeVar->stwTable);
2829         scopeVar->stwTable = loadstw(NULL,scopeVar->parmList[PARM_STW],NULL,0L,&wordsLoaded);
2830         if (!scopeVar->stwTable) {
2831            exeError(exeVar->program,EXE_ERROR_STW,scopeVar->parmList[PARM_STW]);
2832            return;
2833         }
2834      }
2835      break;
2836
2837   case PARM_UCTAB:
2838      /* Upper case character table */
2839      if (eci_set_uctab(&(exeVar->program->error),scopeVar->parmList[parmIndex])) {
2840         exeError(exeVar->program,EXE_ERROR_UCTAB,NULL);
2841         return;
2842      }
2843      break;
2844
2845   } /* switch */
2846
2847} /* exeParm */
2848
2849/* ============================================================== exeDBDecod */
2850EXE_ERROR exeDBDecod(EXE_VAR *exeVar,     /* execution variables */
2851                     char *db,            /* target database */
2852                     char *p)             /* decod database */
2853{
2854   long idx;                              /* auxiliary record index */
2855   long idxDecod;                         /* auxiliary decod record index */
2856   EXE_ERROR errorCode = EXE_ERROR_OK;    /* error code */
2857
2858   /* Allocate auxiliary record indexes */
2859   idx = exeWorkRecord(exeVar);
2860   if (idx < 0L) errorCode = exeVar->program->error.code;
2861   idxDecod = exeWorkRecord(exeVar);
2862   if (idxDecod < 0L) errorCode = exeVar->program->error.code;
2863
2864   /* Set decod database table */
2865   if (!errorCode) {
2866      record(idx,db,1L);
2867      recdecod(idx,p,idxDecod);
2868   }
2869
2870   /* Garbage collector */
2871   eci_rec_free(idx);
2872   eci_rec_free(idxDecod);
2873
2874   /* Return error code */
2875   return errorCode;
2876
2877} /* exeDBDecod */
2878
2879/* ============================================================== exeDBGizmo */
2880EXE_ERROR exeDBGizmo(EXE_VAR *exeVar,     /* execution variables */
2881                     char *db,            /* target database */
2882                     char *p)             /* gizmo list */
2883{
2884   EFC_SPLIT_LINES table;                 /* split line structure */
2885   long line;                             /* line index */
2886   DBXSTRU *dbxp;                         /* dbx structure pointer */
2887   VGIZPSTRU *gizmap;                     /* gizmo map structure pointer */
2888   long idx;                              /* auxiliary record index */
2889   EXE_ERROR errorCode = EXE_ERROR_OK;    /* error code */
2890
2891   /* Split lines */
2892   if (efc_split_lines(&table,p) < 0L)
2893      return exeError(exeVar->program,EXE_ERROR_ALLOC,p);
2894
2895   /* Get auxiliary record */
2896   idx = exeWorkRecord(exeVar);
2897   if (idx < 0L) errorCode = exeVar->program->error.code;
2898
2899   /* Loop all lines */
2900   for (line = 0L; line < table.qtt; line++) {
2901
2902      /* Check error code */
2903      if (errorCode) break;
2904
2905      /* Set gizmo reference */
2906      dbxp = dbxstorp(db);
2907      if (DBXvgzrp) {
2908         for (gizmap = DBXvgzrp; gizmap->nextp; gizmap = gizmap->nextp);
2909         gizmread(table.list[line].text,&(gizmap->nextp),idx);
2910      } else gizmread(table.list[line].text,&DBXvgzrp,idx);
2911
2912   } /* for */
2913
2914   /* Garbage collector */
2915   efc_split_lines_free(&table);
2916   eci_rec_free(idx);
2917
2918   /* Return error code */
2919   return errorCode;
2920
2921} /* exeDBGizmo */
2922
2923/* =================================================================== exeDB */
2924char *exeDB(EXE_VAR *exeVar,           /* execution variables */
2925            SCOPE_VAR *scopeVar)       /* scope variables */
2926{
2927   char *db;      /* auxiliary database parameter string pointer */
2928
2929   /* Check if db paramete is present */
2930   db = scopeVar->parmList[PARM_DB];
2931   if (!db) return NULL;
2932
2933   /* Check gizmo parameter */
2934   if (scopeVar->parmList[PARM_GIZMO])
2935      if (*(scopeVar->parmList[PARM_GIZMO]))
2936         if (exeDBGizmo(exeVar,db,scopeVar->parmList[PARM_GIZMO]))
2937            return NULL;
2938
2939   /* Check decod parameter */
2940   if (scopeVar->parmList[PARM_DECOD])
2941      if (*(scopeVar->parmList[PARM_DECOD]))
2942         exeDBDecod(exeVar,db,scopeVar->parmList[PARM_DECOD]);
2943
2944   /* Return database name pointer */
2945   return db;
2946
2947} /* exeDB */
2948
2949/* ======================================================= exeTaskMasterSort */
2950void exeTaskMasterSort(EXE_VAR *exeVar,         /* execution variables */
2951                       SCOPE_VAR *scopeVar,     /* scope variables */
2952                       EXE_FORMAT *fmt)         /* sort format */
2953{
2954   char *db;               /* data base name */
2955   long keyField;          /* sort key field */
2956   long keyLength;         /* sort key length */
2957   long idxControl;        /* control record index */
2958   CPL_COMMAND *func;      /* format reference */
2959
2960   /* Get database name, if missing: error */
2961   db = exeDB(exeVar,scopeVar);
2962   if (!db) return;
2963
2964   /* Get required sort parameters */
2965   keyField = exeNumber(exeVar,scopeVar,PARM_KEYFIELD,0L,LONG_MAX,0L);
2966   if (exeVar->program->error.code) return;
2967   if (!keyField)
2968      if (!exeRequiredParm(exeVar,scopeVar,ATVALUE_KEY)) return;
2969   if (!exeRequiredParm(exeVar,scopeVar,ATVALUE_KEYLENGTH)) return;
2970   keyLength = exeNumber(exeVar,scopeVar,PARM_KEYLENGTH,1L,EXE_REC_SIZE,DEFAULT_KEYLENGTH);
2971   if (exeVar->program->error.code) return;
2972   if (!exeRequiredDefine(exeVar,scopeVar,PRECISE_STATUS)) return;
2973
2974   /* Find key parameter backward */
2975   if (!keyField) {
2976      if (!fmt) {
2977         func = exeFindParm(scopeVar->father->prev,ATVALUE_KEY);
2978         if (func)
2979            if (func->sub)
2980               fmt = (EXE_FORMAT *)func->sub->altn;
2981      }
2982      if (!fmt) {
2983         exeError(exeVar->program,EXE_ERROR_MSRT,cplAtValue[ATVALUE_KEY].text);
2984         return;
2985      }
2986   }
2987
2988   /* Get control record index */
2989   idxControl = exeNewRecord(exeVar,sizeof(M0STRU));
2990   if (idxControl < 0L) return;
2991
2992   /* Exclusive write lock */
2993   if (eci_lock(idxControl,db,0L,EWLOCK))
2994      scopeVar->defineList[PRECISE_STATUS].value = LOCK_ERROR_EW_DENIED;
2995   else {
2996      scopeVar->defineList[PRECISE_STATUS].value = LOCK_ERROR_OK;
2997
2998      /* Sort master file */
2999      if (!cms_sort(db,EXE_REC_SIZE,keyLength,fmt ? fmt->code : NULL,FALSE/*fmtgen*/,TRUE/*parmmfn*/,keyField)) {
3000         exeError(exeVar->program,EXE_ERROR_MSRT,NULL);
3001         return;
3002      }
3003   }
3004
3005   /* Exclusive write unlock */
3006   if (scopeVar->defineList[PRECISE_STATUS].value == LOCK_ERROR_OK)
3007      eci_unlock(idxControl,0L,EWLOCK);
3008
3009   /* Garbage collector */
3010   eci_rec_free(idxControl);
3011
3012} /* exeTaskMasterSort */
3013
3014#if LIND
3015/* =============================================================== svdifload */
3016long svdifload(char *dbnp,char *filekeys_1,char *filekeys_2,
3017                  int pstflag,long tell)
3018{
3019   fatal("svdifload X svdiflind");
3020   return 0L;
3021}
3022#endif /* LIND */
3023
3024/* ===================================================== exeTaskInvertedLoad */
3025extern int ifl_balan;   /* ciifl.c */
3026
3027void exeTaskInvertedLoad(EXE_VAR *exeVar,             /* execution variables */
3028                         SCOPE_VAR *scopeVar,         /* scope variables */
3029                         BOOLEAN needLock)            /* need lock */
3030{
3031   char *db;               /* data base name */
3032   char *keysDB;           /* keys data base name */
3033   long idxControl;        /* control record index */
3034   long idxAux;            /* auxiliary record index */
3035   LOCK_ERROR lockErr;     /* lock error */
3036
3037   /*  */
3038#if LIND
3039   exeError(exeVar->program,EXE_ERROR_INVALID,"LIND - Inverted load");
3040   if (exeVar->program->error.code) return;
3041#endif /* LIND */
3042
3043   /* Get database name, if missing: error */
3044   db = exeDB(exeVar,scopeVar);
3045   if (!db) return;
3046
3047   /* Check mandatory parameters */
3048   keysDB = exeRequiredParm(exeVar,scopeVar,ATVALUE_KEYSDB);
3049   if (!keysDB) return;
3050   if (!exeRequiredDefine(exeVar,scopeVar,PRECISE_KEY)) {
3051      exeError(exeVar->program,EXE_ERROR_MISSING,preciseList[PRECISE_KEY]);
3052      return;
3053   }
3054
3055   /* Check if exclusive write lock was required */
3056   lockErr = -1L;
3057   if (needLock) {
3058
3059      /* Get lock parameter */
3060      if (!exeRequiredDefine(exeVar,scopeVar,PRECISE_STATUS)) {
3061         exeError(exeVar->program,EXE_ERROR_MISSING,preciseList[PRECISE_STATUS]);
3062         return;
3063      }
3064
3065      /* Get control record index */
3066      idxControl = exeNewRecord(exeVar,sizeof(M0STRU));
3067      if (idxControl < 0L) return;
3068
3069      /* Exclusive write lock */
3070      if (eci_lock(idxControl,db,0L,EWLOCK)) lockErr = LOCK_ERROR_EW_DENIED;
3071      else lockErr = LOCK_ERROR_OK;
3072
3073   }
3074
3075   /* If allowed, load inverted and reset master */
3076   if (lockErr != LOCK_ERROR_EW_DENIED) {
3077
3078      /* Inverted load */
3079      sprintf(exeVar->buff,"%d",scopeVar->defineList[PRECISE_KEY].tag);
3080
3081#if SUN
3082      ifl_balan = 0;
3083#endif /* SUN */
3084
3085      svdifload(db,keysDB,exeVar->buff,IFUPISIS/* ? IFUPDICT */,-1L);
3086
3087#if SUN
3088      ifl_balan = 1;
3089#endif /* SUN */
3090
3091      if (exePrecise(scopeVar->parmList[PARM_RESET]) != PRECISE_OFF) {
3092
3093         /* Get auxiliary record index */
3094         idxAux = exeNewRecord(exeVar,sizeof(M0STRU));
3095         if (idxAux < 0L) return;
3096
3097         /* Reset master */
3098         recreset(db,1L,MAXUPDMFN,idxAux,0L/*parmtell*/);
3099
3100         /* Garbage collector */
3101         eci_rec_free(idxAux);
3102
3103      }
3104
3105   }
3106
3107   /* Check if exclusive write lock was set */
3108   if (needLock) {
3109      scopeVar->defineList[PRECISE_STATUS].value = lockErr;
3110      if (lockErr == LOCK_ERROR_OK) eci_unlock(idxControl,0L,EWLOCK);
3111      eci_rec_free(idxControl);
3112   }
3113
3114} /* exeTaskInvertedLoad */
3115
3116/* ============================================== exeTaskFullInvertionReturn */
3117int exeTaskFullInvertionReturn(SCOPE_VAR *scopeVar,      /* scope variables */
3118                               long idxControl)          /* control record index */
3119{
3120
3121   /* If locked, exclusive write unlock */
3122   if (scopeVar->defineList[PRECISE_STATUS].value == LOCK_ERROR_OK)
3123      eci_unlock(idxControl,0L,EWLOCK);
3124
3125   /* Garbage collector */
3126   if (idxControl > -1L) eci_rec_free(idxControl);
3127
3128   /* Return */
3129   return 0;
3130
3131} /* exeTaskFullInvertionReturn */
3132
3133/* ==================================================== exeTaskFullInvertion */
3134int exeTaskFullInvertion(EXE_VAR *exeVar,          /* execution variables */
3135                         SCOPE_VAR *scopeVar)      /* scope variables */
3136{
3137   char *db;               /* data base name */
3138   char *keysDB;           /* keys data base name */
3139   long idxControl;        /* control record index */
3140   long pos;               /* current position */
3141   CPL_COMMAND cmd;        /* extract FST host */
3142   char *sortLength = "80";   /* sort lenght */
3143
3144   /* Get database name, if missing: error */
3145   db = exeDB(exeVar,scopeVar);
3146   if (!db) return 0;
3147
3148   /* Check mandatory parameters */
3149   if (!scopeVar->parmList[PARM_KEYSDB]) {
3150      if (exeFileTemp(exeVar,exeVar->buff)) return 0;
3151      scopeVar->parmList[PARM_KEYSDB] = strdup(exeVar->buff);
3152   }
3153   keysDB = exeRequiredParm(exeVar,scopeVar,ATVALUE_KEYSDB);
3154   if (!keysDB) return 0;
3155   if (!exeRequiredDefine(exeVar,scopeVar,PRECISE_STATUS)) {
3156      exeError(exeVar->program,EXE_ERROR_MISSING,preciseList[PRECISE_STATUS]);
3157      return 0;
3158   }
3159
3160   /* Set define tags and FST host */
3161   if (!scopeVar->defineList[PRECISE_KEY].tag)
3162      scopeVar->defineList[PRECISE_KEY].tag = FULLINV_TAG_KEY;
3163   memset(&cmd,0x00,sizeof(CPL_COMMAND));
3164   cmd.element = ELEMENT_EXTRACT;
3165
3166   /* Set define value */
3167   scopeVar->defineList[PRECISE_STATUS].value = -1L;
3168
3169   /* Get control record index */
3170   idxControl = exeNewRecord(exeVar,sizeof(M0STRU));
3171   if (idxControl < 0L) return exeTaskFullInvertionReturn(scopeVar,idxControl);
3172
3173   /* Exclusive write lock */
3174   if (eci_lock(idxControl,db,0L,EWLOCK)) {
3175      scopeVar->defineList[PRECISE_STATUS].value = LOCK_ERROR_EW_DENIED;
3176      return exeTaskFullInvertionReturn(scopeVar,idxControl);
3177   }
3178   scopeVar->defineList[PRECISE_STATUS].value = LOCK_ERROR_OK;
3179
3180   /* Reinitialize links extraction database */
3181   recisis0(keysDB);
3182
3183   /* Loop all records */
3184   for (pos = 1L; ; pos++) {
3185
3186      /* Read record */
3187      record(scopeVar->idxCurr,db,pos);
3188      if (VRECrc(scopeVar->idxCurr) == RCEOF) break;
3189      if (VRECrc(scopeVar->idxCurr) != RCNORMAL) continue;
3190
3191      /* Extract keys */
3192      if (exeExtract(exeVar,scopeVar,&cmd))
3193         return exeTaskFullInvertionReturn(scopeVar,idxControl);
3194
3195   } /* for */
3196
3197   /* Get sort parameters */
3198
3199   scopeVar->parmList[PARM_DB] = scopeVar->parmList[PARM_KEYSDB];
3200   sprintf(exeVar->buff,"%d",scopeVar->defineList[PRECISE_KEY].tag);
3201   scopeVar->parmList[PARM_KEYFIELD] = strdup(exeVar->buff);
3202   scopeVar->parmList[PARM_KEYLENGTH] = strdup(sortLength);
3203
3204   /* Sort extracted keys database */
3205   exeTaskMasterSort(exeVar,scopeVar,NULL);
3206   if (exeVar->program->error.code) {
3207      scopeVar->parmList[PARM_DB] = db;
3208      return exeTaskFullInvertionReturn(scopeVar,idxControl);
3209   }
3210
3211   /* Restore original database parameter */
3212   scopeVar->parmList[PARM_DB] = db;
3213
3214   /* Inverted load from sorted extracted keys database */
3215   exeTaskInvertedLoad(exeVar,scopeVar,FALSE);
3216   if (exeVar->program->error.code)
3217      return exeTaskFullInvertionReturn(scopeVar,idxControl);
3218
3219   /* Remove temporary files */
3220   remove(keysDB);
3221   dbxflush(keysDB);
3222   sprintf(exeVar->buff,"%s.xrf",keysDB);
3223   remove(exeVar->buff);
3224   sprintf(exeVar->buff,"%s.mst",keysDB);
3225   remove(exeVar->buff);
3226
3227   /* Return */
3228   return exeTaskFullInvertionReturn(scopeVar,idxControl);
3229
3230} /* exeTaskFullInvertion */
3231
3232/* ============================================================= exeListSort */
3233EXE_ERROR exeListSort(EXE_VAR *exeVar,          /* execution variables */
3234                      SCOPE_VAR *scopeVar,      /* scope variables */
3235                      CPL_COMMAND *cmd,         /* sort command */
3236                      long idx)                 /* record index */
3237{
3238   STRUCT_FREQLIST *freqPos;     /* frequency list current position */
3239   EXE_FORMAT *fmt;              /* format parameter structure */
3240
3241   /* Get sort format */
3242   if (!cmd->sub) return exeError(exeVar->program,EXE_ERROR_SORT,cplElement[ELEMENT_PFT].text);
3243   fmt = (EXE_FORMAT *)(cmd->sub->altn);
3244   if (!fmt) return exeError(exeVar->program,EXE_ERROR_SORT,cplElement[ELEMENT_PFT].text);
3245
3246   /* Loop all loaded itens */
3247   for (freqPos = exeVar->freq.head; freqPos; freqPos = freqPos->next) {
3248
3249      /* Clear sort record */
3250      eci_field_D(&(exeVar->program->error),idx,0);
3251
3252      /* Set define values */
3253      scopeVar->defineList[PRECISE_ITEM].text = freqPos->item;
3254      scopeVar->defineList[PRECISE_VALUE].value = freqPos->qtt;
3255
3256      /* Field update defines */
3257      exeDefines(exeVar,scopeVar,idx);
3258
3259      /* Format sort key */
3260      if (fmt_inter(fmt->code,idx,exeVar->buffSize,exeVar->buff,exeVar->buffSize) < 0L)
3261         return exeError(exeVar->program,EXE_ERROR_FORMAT,fmterrxy);
3262
3263      /* Store sort key */
3264      freqPos->sort = strdup(exeVar->buff);
3265      if (!freqPos->sort)
3266         return exeError(exeVar->program,EXE_ERROR_ALLOC,exeVar->buff);
3267
3268   } /* for */
3269
3270   /* Sort frequency list */
3271   freq_sort(&(exeVar->freq));
3272
3273   /* Return no error */
3274   return EXE_ERROR_OK;
3275
3276} /* exeListSort */
3277
3278/* ============================================================= exeTaskList */
3279void exeTaskList(EXE_VAR *exeVar,         /* execution variables */
3280                 SCOPE_VAR *scopeVar,     /* scope variables */
3281                 CPL_COMMAND *cmd)        /* first command */
3282{
3283   STRUCT_FREQLIST *freqPos;  /* frequency current position */
3284   long from;                 /* first item */
3285   long to;                   /* last item */
3286   long count;                /* quantity limit */
3287   long pos;                  /* current position */
3288   long relPos = 0L;          /* relative current position */
3289   BOOLEAN reverse;           /* reverse flag */
3290
3291   /* Check if any freq was previously loaded */
3292   if (!exeVar->freq.head) return;
3293
3294   /* Check mandatory parameters */
3295   if (!scopeVar->defineList[PRECISE_ITEM].tag) {
3296      exeError(exeVar->program,EXE_ERROR_MISSING,preciseList[PRECISE_ITEM]);
3297      return;
3298   }
3299   if (scopeVar->defineList[PRECISE_ITEM].tag < 0) {
3300      exeError(exeVar->program,EXE_ERROR_INVALID,preciseList[PRECISE_ITEM]);
3301      return;
3302   }
3303
3304   /* Get range limit */
3305   from = exeNumber(exeVar,scopeVar,PARM_FROM,1L,LONG_MAX,1L);
3306   to = exeNumber(exeVar,scopeVar,PARM_TO,from,LONG_MAX,LONG_MAX);
3307   count = exeNumber(exeVar,scopeVar,PARM_COUNT,1L,LONG_MAX,LONG_MAX);
3308   if (exeVar->program->error.code) return;
3309   reverse = (BOOLEAN)(exePrecise(scopeVar->parmList[PARM_REVERSE]) == PRECISE_ON);
3310
3311   /* Set define values */
3312   scopeVar->defineList[PRECISE_FROM].value = from;
3313   scopeVar->defineList[PRECISE_TO].value = to;
3314   scopeVar->defineList[PRECISE_ITENS].value = exeVar->freq.item_tot;
3315   scopeVar->defineList[PRECISE_ITEMS].value = exeVar->freq.item_tot;
3316   scopeVar->defineList[PRECISE_TOTAL].value = exeVar->freq.freq_tot;
3317
3318   /* Sort frequency, if required */
3319   if (scopeVar->parmList[PARM_SORT]) {
3320
3321      /* Find sort parameter backward */
3322      if (!cmd->func) cmd->func = exeFindParm(scopeVar->father->prev,ATVALUE_SORT);
3323
3324      /* Call list sort */
3325      exeListSort(exeVar,scopeVar,cmd->func,scopeVar->idxCurr);
3326
3327   }
3328
3329   /* Loop range of itens */
3330   for (pos = 1L,freqPos = reverse ? exeVar->freq.tail : exeVar->freq.head; relPos < count && freqPos; pos++,freqPos = reverse ? freqPos->prev : freqPos->next) {
3331
3332      /* Check limits */
3333      if (pos < from) continue;
3334      if (pos > to) break;
3335      relPos++;
3336
3337      /* Clear frequency record */
3338      eci_field_D(&(exeVar->program->error),scopeVar->idxCurr,0);
3339
3340      /* Set define values */
3341      scopeVar->defineList[PRECISE_ITEM].text = freqPos->item;
3342      scopeVar->defineList[PRECISE_VALUE].value = freqPos->qtt;
3343      scopeVar->defineList[PRECISE_CURRENT].value = pos;
3344
3345      /* Call record execution */
3346      exeGo(exeVar,scopeVar,cmd);
3347      if (scopeVar->skip == PRECISE_QUIT) break;
3348
3349   } /* for */
3350
3351   /* Reset define values */
3352   scopeVar->defineList[PRECISE_ITEM].text = NULL;
3353
3354} /* exeTaskList */
3355
3356/* =========================================================== exeTaskImport */
3357void exeTaskImport(EXE_VAR *exeVar,          /* execution variables */
3358                   SCOPE_VAR *scopeVar,      /* scope variables */
3359                   CPL_COMMAND *cmd)         /* first command */
3360{
3361   char *fileName;            /* export file name */
3362   char *p;                   /* auxiliary string buffer pointer */
3363   FILE *importFile;          /* import file pointer */
3364   PRECISE_LIST typeValue;    /* import file type value */
3365   long count;                /* quantity limit */
3366   long pos;                  /* current position */
3367   ECI_ERROR errorCode;
3368
3369   /* Get range limit */
3370   count = exeNumber(exeVar,scopeVar,PARM_COUNT,1L,LONG_MAX,LONG_MAX);
3371   if (exeVar->program->error.code) return;
3372
3373   /* Open import file */
3374   fileName = exeRequiredParm(exeVar,scopeVar,ATVALUE_FILE);
3375   if (!fileName) return;
3376   p = dbxcipar(NULL,fileName,'=');
3377   importFile = fopen(p,"r");
3378   if (importFile == NULL) {
3379      exeError(exeVar->program,EXE_ERROR_FILE,p);
3380      return;
3381   }
3382   typeValue = exePrecise(scopeVar->parmList[PARM_TYPE]);
3383
3384   /* Loop all import file */
3385   for (pos = 1L; pos <= count; pos++) {
3386
3387      /* Get next import record */
3388      errorCode = exeImport(exeVar,scopeVar,importFile,typeValue,pos);
3389      if (errorCode) {
3390         if (errorCode == ECI_ERROR_EOF) break;
3391         exeError(exeVar->program,EXE_ERROR_IMPORT,NULL);
3392         break;
3393      }
3394
3395      /* Set define current position */
3396      scopeVar->defineList[PRECISE_CURRENT].value = pos;
3397
3398      /* Call record execution */
3399      exeGo(exeVar,scopeVar,cmd);
3400      if (scopeVar->skip == PRECISE_QUIT) break;
3401
3402   } /* for */
3403
3404   /* Close import file */
3405   fclose(importFile);
3406
3407} /* exeTaskImport */
3408
3409/* =========================================================== exeTaskUpdate */
3410void exeTaskUpdate(EXE_VAR *exeVar,             /* execution variables */
3411                   SCOPE_VAR *scopeVar,         /* scope variables */
3412                   CPL_COMMAND *cmd)            /* first command */
3413{
3414   char *db;                                 /* data base name */
3415   char *mfnText;                   /* MFN text */
3416   CPL_ATVALUE mfnValue;            /* MFN option value */
3417   long mfn;                        /* MFN */
3418
3419   /* Get required parameters */
3420   db = exeDB(exeVar,scopeVar);
3421   if (!db) return;
3422   mfnText = exeRequiredParm(exeVar,scopeVar,ATVALUE_MFN);
3423   if (!mfnText) return;
3424   mfnValue = exePrecise(mfnText);
3425   mfn = atol(mfnText);
3426
3427   /* If not new record, read original record */
3428   if (mfnValue == PRECISE_GETNEW)
3429      eci_rec_copy(scopeVar->idxCurr,scopeVar->idxPrev);
3430   else
3431      if (mfnValue != PRECISE_NEW) record(scopeVar->idxCurr,db,mfn);
3432
3433   /* Valid only at the update scope [0.9g] */
3434   scopeVar->defineList[PRECISE_LOCK].apply = FALSE;
3435   scopeVar->defineList[PRECISE_STATUS].apply = FALSE;
3436
3437   /* Call record execution */
3438   exeGo(exeVar,scopeVar,cmd);
3439
3440} /* exeTaskUpdate */
3441
3442/* ================================================================== exePos */
3443long exePos(BOOLEAN reverse,     /* reverse flag */
3444            long last,           /* last position */
3445            long pos)            /* orignal position */
3446{
3447
3448   /* If reverse: return complement postition, else: return current position */
3449   return reverse ? (last - pos) + 1L : pos;
3450
3451} /* exePos */
3452
3453#if !CIB71
3454/* ================================================================== b5_msg */
3455int b5_msg(int tline,
3456           char *msg,
3457           long docs,
3458           int tmsg)
3459{
3460   extern char b5_pfxmsg[];   /* prefix message */
3461   char buff[LE2+LE2+1];      /* auxiliary string buffer */
3462   EFC_ERROR error;           /* error structure */
3463
3464   /* If no target message index and field: quit */
3465   if (b5msg_idx < 0L || b5msg_tag < 1) return 0;
3466
3467   /* Store search message for highlight */
3468   if (tmsg == 1 && docs) {
3469      sprintf(buff,"%-.*s%-.*s",LE2,b5_pfxmsg,LE2,msg);
3470      eci_field_AT(&error,b5msg_idx,b5msg_tag,buff);
3471   }
3472
3473   /* Return OK */
3474   return 0;
3475
3476}
3477
3478#else /* CIB71 */
3479
3480/* ================================================================== b7_msg */
3481int b7_msg(b7_CIB7 *cib7p,
3482              int tline,
3483           char *msg,
3484           long psts,
3485           long docs,
3486           int tmsg)
3487{
3488   char buff[LE2+LE2+1];      /* auxiliary string buffer */
3489   EFC_ERROR error;           /* error structure */
3490
3491   /* If no target message index and field: quit */
3492   if (b5msg_idx < 0L || b5msg_tag < 1) return 0;
3493
3494   /* Store search message for highlight */
3495   if (tmsg == 1 && docs)
3496   {
3497       if (cib7p->nqualts) /* tagged key: plants/(24,70) */
3498    {
3499        for (cib7p->qualtp=cib7p->vqualt; *cib7p->qualtp; cib7p->qualtp++)
3500          {
3501        sprintf(buff,"%d %-.*s",*cib7p->qualtp,LE2,msg);
3502            eci_field_AT(&error,b5msg_idx,b5msg_tag,buff);
3503          }
3504    }
3505      else /* normal key: PLANTS or prefixed key: TI PLANTS */
3506      {
3507        sprintf(buff,"%-.*s%-.*s",LE2,cib7p->b7_pfxmsg,LE2,msg);
3508        eci_field_AT(&error,b5msg_idx,b5msg_tag,buff);
3509      }
3510   }
3511
3512   /* Return OK */
3513   return 0;
3514
3515}
3516#endif /* CIB71 */
3517
3518/* ================================================================== b5_kbh */
3519int b5_kbh(void)
3520{
3521
3522   /* Return no interruption */
3523   return 0;
3524
3525}
3526
3527/* ================================================================== exeHit */
3528long exeHit
3529(
3530    b7_CIB7 *cib7p,
3531    long idx,       /* search hit record index */
3532    long hit            /* request hit */
3533)
3534{
3535
3536   /* Return MFN of requested hit */
3537#if !CIB71
3538   return b6_hit(idx,hit,VMFRmfn(idx),b6bufferp);
3539#else /* !CIB71 */
3540   return b7_hit(cib7p,idx,hit,VMFRmfn(idx));
3541#endif /* !CIB71 */
3542
3543} /* exeHit */
3544
3545/* ==================================================== exeSearchCisisReturn */
3546SEARCH_ERROR exeSearchCisisReturn(EFC_ERROR *err,           /* error structure */
3547                                  long idxControl,          /* record index to be freed */
3548                                  char *buff,               /* buffer to be freed */
3549                                  SEARCH_ERROR errorCode,   /* error code */
3550                                  char *msg)                /* error message */
3551{
3552
3553   /* Garbage collector */
3554   if (idxControl >= -1L) eci_rec_free(idxControl);
3555   efc_free(buff);
3556
3557   /* Return error code */
3558   return efc_error(err,errorCode,msg);
3559
3560} /* exeSearchCisisReturn */
3561
3562/* ======================================== exeSearchCisisPropagateQualifier */
3563void exeSearchCisisPropagateQualifier
3564(
3565    EFC_ERROR *err,         /* error structure */
3566    long idx,
3567   char *buff
3568)
3569{
3570    char *expr;
3571    char *e;
3572    char *p;
3573    char qlf[LE2+1] = "";
3574   char *q;
3575
3576    eci_field(idx,MFQTOBJ0,1,buff);
3577   expr = strdup(buff);
3578/* printf("<!-- antes : %s -->\n",expr); */
3579
3580    for (e = expr,p = buff; *e; e++)
3581   {
3582        if ( *e == '[' )
3583        {
3584            if ( *(e+1) == '/' )
3585         {
3586            *p++ = '[';
3587               for (q = qlf; *++e; q++)
3588            {
3589            *p++ = *q = *e;
3590             if ( *e == TOKDELIM )
3591                {
3592                    break;
3593                }
3594            }
3595                *q = '\0';
3596            continue;
3597         }
3598         else
3599         {
3600            qlf[0] = '\0';
3601         }
3602        }
3603        if ( *e == '_' && qlf[0] != '\0' )
3604        {
3605            if ( *(p-1) != TOKDELIM )
3606         {
3607                *p++ = TOKDELIM;
3608            }
3609            strcpy(p,qlf);
3610         p += strlen(qlf);
3611         *p++ = TOKDELIM;
3612        }
3613        *p++ = *e;
3614    }
3615    *p='\0';
3616
3617    eci_field_MT(err,idx,MFQTOBJ0,buff);
3618/* printf("<!-- depois: %s -->\n",buff); */
3619
3620} /* exeSearchCisisPropagateQualifier */
3621
3622/* ========================================================== exeSearchCisis */
3623SEARCH_ERROR exeSearchCisis
3624(
3625    EFC_ERROR *err,         /* error structure */
3626    b7_CIB7 *cib7p,
3627    long idxHit,            /* search hit record index */
3628    char *db,               /* database name */
3629    char *expression,       /* search expression */
3630   char *dbLog,         /* search log database */
3631   long setNumber,      /* log set number */
3632    char *tempFile,         /* temporary file name */
3633    char *pfxList,          /* prefix list */
3634    long idxPfx,            /* search prefix record index */
3635    int tag                 /* message tag */
3636)
3637{
3638   char *searchErrorText;        /* search error point */
3639   char *searchPrefix;           /* search prefix auxiliary buffer */
3640   char *defSearchPrefix = "^p*^y"; /* default search prefix */
3641   char *buff = NULL;            /* auxiliary buffer */
3642   long idxControl;              /* auxiliary search control record index */
3643   int searchErrorCode;          /* search error code */
3644#if !CIB71
3645   long nbytes1;                 /* bit string space */
3646#endif /* CIB71 */
3647
3648   /* Get auxiliary record index: prefix and control */
3649   idxControl = eci_rec_new(err,EXE_REC_SIZE/*sizeof(M0STRU)*/);
3650   if (idxControl < 0L) return SEARCH_ERROR_ALLOC;
3651
3652   /* Set search prefix index list */
3653   if (pfxList)
3654      if (!*pfxList) pfxList = NULL;
3655   if (pfxList) eci_field_ML(err,idxPfx,MFQTXTAG,pfxList);
3656   else {
3657      searchPrefix = efc_new(strlen(defSearchPrefix)+strlen(db)+1);
3658      if (!searchPrefix)
3659         return exeSearchCisisReturn(err,idxControl,buff,SEARCH_ERROR_ALLOC,NULL);
3660      sprintf(searchPrefix,"%s%s",defSearchPrefix,db);
3661      eci_field_MT(err,idxPfx,MFQTXTAG,searchPrefix);
3662      efc_free(searchPrefix);
3663   }
3664
3665   /* Search needed parameters */
3666   VMFRmfn(idxHit) = 0L;
3667   if ( dbLog )
3668   {
3669    record(idxControl,dbLog,0L);
3670   }
3671    record(idxControl,db,0L);
3672#if !CIB71
3673    nbytes1 = (VMF0nxtmfn(idxControl) / 8) + 1L;
3674    if (nbytes1 > ALLOMAXV) nbytes1 = ALLOMAXV;
3675#endif /* !CIB71 */
3676   buff = efc_new(EXE_REC_SIZE);
3677   if (!buff) return exeSearchCisisReturn(err,idxControl,buff,SEARCH_ERROR_ALLOC,NULL);
3678
3679   /* Call search expression */
3680#if !CIB71
3681   searchErrorText = b5_exp(idxHit,db,expression,buff,NULL,idxControl,&searchErrorCode);
3682#else /* !CIB71 */
3683   searchErrorText = b7_exp(cib7p,idxHit,db,expression,buff,dbLog,idxControl,&searchErrorCode);
3684#endif /* !CIB71 */
3685
3686   /* Check search expression error code */
3687   if (searchErrorCode)
3688      return exeSearchCisisReturn(err,idxControl,buff,SEARCH_ERROR_SYNTAX,searchErrorText);
3689
3690   /* Propagating field qualifier */
3691//      exeSearchCisisPropagateQualifier(err,idxHit,buff);
3692
3693   /* Add search temporary file name */
3694   if ( dbLog )
3695   {
3696    sprintf(tempFile,"%s.%03d",dbLog,VMF0nxtmfn(idxControl)-1L);
3697    eci_field_MT(err,idxHit,MFQTHMEM,tempFile);
3698      *tempFile = '\0';
3699   }
3700   else if (SRC_TMP_FILE)
3701   {
3702    eci_field_MT(err,idxHit,MFQTHMEM,tempFile);
3703   } else {           // HB 20070320
3704    char *hitfnamp="null";
3705    char bup[512];
3706    sprintf(bup,"D%dA%d|%s|",MFQTHMEM,MFQTHMEM,hitfnamp);
3707    if (fldupdat(idxHit,bup) != NULL) fatal("mxbol/fldupdat");
3708   }
3709
3710   /* Set global parameters, call search run, reset global parameters */
3711   b5msg_idx = idxPfx;
3712   b5msg_tag = tag;
3713#if !CIB71
3714   searchErrorText = b6_run(idxHit,db,buff,EXE_REC_SIZE,nbytes1,2L,isisuctab,"",idxPfx,idxControl,&searchErrorCode);
3715#else /* CIB71 */
3716   searchErrorText = b7_run(cib7p,idxHit,db,buff,EXE_REC_SIZE,2L,isisuctab,"",idxPfx,idxControl,&searchErrorCode);
3717#endif /* CIB71 */
3718   b5msg_idx = -1L;
3719   b5msg_tag = 0;
3720
3721   /* Check search run error code */
3722   if (searchErrorCode)
3723      return exeSearchCisisReturn(err,idxControl,buff,SEARCH_ERROR_RUN,searchErrorText);
3724
3725   /* Return error code */
3726   return exeSearchCisisReturn(err,idxControl,buff,SEARCH_ERROR_OK,NULL);
3727
3728} /* exeSearchCisis */
3729
3730/* ===================================================== exeTaskSearchReturn */
3731int exeTaskSearchReturn(SCOPE_VAR *scopeVar,       /* scope variables */
3732                        SEARCH_VAR *searchVar)     /* search variables */
3733{
3734
3735   /* Previous call will be able to see the search result */
3736   scopeVar->defineList[PRECISE_STATUS].apply = TRUE;
3737   scopeVar->defineList[PRECISE_ERRORINFO].apply = TRUE;
3738
3739   /* Garbage collector */
3740   /* <R> */
3741   if( searchVar->dbLog )
3742   {
3743    dbxflush( searchVar->dbLog );
3744   }
3745   /* </R> */
3746#if CIB71
3747    if (searchVar->cib7p) b7_cib7_delete(searchVar->cib7p);
3748#endif /* CIB71 */
3749    if (*searchVar->tempFile) remove(searchVar->tempFile);
3750   if (searchVar->idxHit > -1L) eci_rec_free(searchVar->idxHit);
3751   if (searchVar->idxPfx > -1L) eci_rec_free(searchVar->idxPfx);
3752
3753   /* Return */
3754   return 0;
3755
3756} /* exeTaskSearchReturn */
3757
3758/* =============================================================== exeTaskSearch */
3759int exeTaskSearch(EXE_VAR *exeVar,           /* execution variables */
3760                  SCOPE_VAR *scopeVar,       /* scope variables */
3761                  CPL_COMMAND *cmd)          /* first command */
3762{
3763   char *db;               /* data base name */
3764   char *expression;       /* expression */
3765   long setNumber = 0L;     /* log set number */
3766   SEARCH_VAR searchVar;   /* search variables */
3767   long from;              /* first hit */
3768   long to;                /* last hit */
3769   long count;             /* quantity limit */
3770   BOOLEAN reverse;        /* reverse flag */
3771   long pos;               /* current position */
3772   long relPos = 0L;       /* relative position */
3773   int hlTag;              /* highlight term list field number */
3774   EFC_ERROR err;          /* error structure */
3775
3776   /* Get data base name, if missing: error */
3777   db = exeDB(exeVar,scopeVar);
3778   if (!db) return 0;
3779
3780   /* search parameters */
3781   expression = exeRequiredParm(exeVar,scopeVar,ATVALUE_EXPRESSION);
3782   if (!expression) return 0;
3783
3784   /* Setup search variables */
3785   searchVar.dbLog = NULL;
3786   if (scopeVar->parmList[PARM_LOG])
3787      if (*(scopeVar->parmList[PARM_LOG]))
3788         searchVar.dbLog = scopeVar->parmList[PARM_LOG];
3789   *(searchVar.tempFile) = '\0';
3790   searchVar.idxHit = exeWorkRecord(exeVar);
3791   searchVar.idxPfx = exeNewRecord(exeVar,SEARCH_PREFIX_SIZE);
3792   if (searchVar.idxHit < 0L || searchVar.idxPfx < 0L) {
3793      exeError(exeVar->program,EXE_ERROR_ALLOC,NULL);
3794      return exeTaskSearchReturn(scopeVar,&searchVar);
3795   }
3796   eci_rec_active(searchVar.idxPfx);
3797   /* Allocate work area */
3798#if !CIB71
3799    if (!b6bufferp) b6_hballoc(SEARCH_AUX_SIZE,&b6bufferp);
3800#else /* !CIB71 */
3801    searchVar.cib7p = NULL;
3802//  searchVar.cib7p = (b7_CIB7 *)b7_cib7(searchVar.cib7p);
3803    searchVar.cib7p = b7_cib7(searchVar.cib7p,NULL);
3804//  b7_hballoc(searchVar.cib7p,SEARCH_AUX_SIZE,&(searchVar.cib7p->b7bufferp));
3805#endif /* !CIB71 */
3806
3807   /* get temporary file */
3808   if ( !searchVar.dbLog && SRC_TMP_FILE)
3809   {
3810       if (!dbxtmpnm("CI_TEMPDIR", 0, searchVar.tempFile))
3811    {
3812        exeTaskSearchReturn(scopeVar,&searchVar);
3813          return exeError(exeVar->program,EXE_ERROR_SEARCH,"temporary file");
3814    }
3815   }
3816
3817   /* Set defines parameters */
3818   hlTag = scopeVar->defineList[PRECISE_KEYS].tag;
3819   scopeVar->defineList[PRECISE_KEYS].apply = FALSE;
3820   scopeVar->defineList[PRECISE_STATUS].apply = FALSE;
3821   scopeVar->defineList[PRECISE_ERRORINFO].apply = FALSE;
3822
3823   /* Call CISIS search */
3824   if (exeSearchCisis(&err,searchVar.cib7p,searchVar.idxHit,db,expression,searchVar.dbLog,setNumber,searchVar.tempFile,
3825      scopeVar->parmList[PARM_INDEXLIST],searchVar.idxPfx,hlTag)) {
3826      if (err.code == SEARCH_ERROR_SYNTAX || err.code == SEARCH_ERROR_RUN) {
3827         scopeVar->defineList[PRECISE_STATUS].value = err.code;
3828         scopeVar->defineList[PRECISE_ERRORINFO].text = efc_strrepl(scopeVar->defineList[PRECISE_ERRORINFO].text,err.info);
3829         return exeTaskSearchReturn(scopeVar,&searchVar);
3830      }
3831      exeError(exeVar->program,err.code,err.info);
3832      return exeTaskSearchReturn(scopeVar,&searchVar);
3833   }
3834
3835   /* Get range limit */
3836   from = exeNumber(exeVar,scopeVar,PARM_FROM,1L,LONG_MAX,1L);
3837   to = exeNumber(exeVar,scopeVar,PARM_TO,from,LONG_MAX,LONG_MAX);
3838   count = exeNumber(exeVar,scopeVar,PARM_COUNT,1L,LONG_MAX,LONG_MAX);
3839   if (exeVar->program->error.code)
3840      return exeTaskSearchReturn(scopeVar,&searchVar);
3841   reverse = (BOOLEAN)(exePrecise(scopeVar->parmList[PARM_REVERSE]) == PRECISE_ON);
3842
3843   /* Set define values */
3844#if CIB71
3845   scopeVar->defineList[PRECISE_SETNUMBER].value = searchVar.cib7p->b7setno;
3846#endif /* CIB71 */
3847   scopeVar->defineList[PRECISE_TOTAL].value = exeHit(searchVar.cib7p,searchVar.idxHit,0L);
3848   scopeVar->defineList[PRECISE_FROM].value = from;
3849   scopeVar->defineList[PRECISE_TO].value = to;
3850
3851   /* Check search quantity of hits retrieved */
3852   if (scopeVar->defineList[PRECISE_TOTAL].value <= 0)
3853      return exeTaskSearchReturn(scopeVar,&searchVar);
3854
3855   /* Loop range of hits */
3856   for (pos = from; pos <= to; pos++) {
3857
3858      /* Check count and total limit */
3859      if (relPos++ >= count) break;
3860      if (pos > scopeVar->defineList[PRECISE_TOTAL].value) break;
3861
3862      /* Read record, check record status */
3863      record(scopeVar->idxCurr,db,exeHit(searchVar.cib7p,searchVar.idxHit,exePos(reverse,scopeVar->defineList[PRECISE_TOTAL].value,pos)));
3864      if (VRECrc(scopeVar->idxCurr) != RCNORMAL) continue;
3865
3866      /* Set define current position, copy highlight fields */
3867      scopeVar->defineList[PRECISE_CURRENT].value = pos;
3868      if (hlTag)
3869         eci_field_copy(&(exeVar->program->error),TRUE,scopeVar->idxCurr,hlTag,searchVar.idxPfx,hlTag);
3870
3871      /* Call record execution */
3872      exeGo(exeVar,scopeVar,cmd);
3873      if (scopeVar->skip == PRECISE_QUIT) break;
3874
3875   } /* for */
3876
3877   /* Return */
3878   return exeTaskSearchReturn(scopeVar,&searchVar);
3879
3880} /* exeTaskSearch */
3881
3882/* ================================================================== exeKey */
3883void exeKey(char *target,        /* target key buffer */
3884            char *parameter)     /* key parameter */
3885{
3886
3887   /* Reset target content, copy parameter, convert with current upper case table */
3888   memset(target,0x00,LE2+1);
3889   if (parameter) strncpy(target,parameter,LE2);
3890   eci_uctab(target);
3891
3892} /* exeKey */
3893
3894/* ============================================================== exeNextKey */
3895void exeNextKey(BOOLEAN reverse,             /* reverse flag */
3896                long idx,                    /* current term index */
3897                STRUCT_PREVTERM *prevTrm)    /* previous term structure */
3898{
3899
3900   /* If reverse, return previous term, else return next term */
3901   if (reverse)
3902      if (TermPrevious(prevTrm,idx,"",VTRMkey(idx)) < 0L) VTRMrc(idx) = RCEOF;
3903      else VTRMrc(idx) = RCNORMAL;
3904   else nxterm(idx);
3905
3906} /* exeNextKey */
3907
3908/* =================================================== exeTaskKeyrangeReturn */
3909int exeTaskKeyrangeReturn
3910(
3911    long idxTerm,                               /* term index */
3912   EFC_NUMBER_LIST *listPostTagValue    /* splited line structure */
3913)
3914{
3915   /* Garbage collector */
3916   if (idxTerm > -1L) eci_trm_free(idxTerm);
3917    efc_numberListFree(listPostTagValue);
3918
3919   /* Return */
3920   return 0;
3921
3922} /* exeTaskKeyrangeReturn */
3923
3924/* ========================================================= exeTaskKeyrange */
3925int exeTaskKeyrange(EXE_VAR *exeVar,            /* execution variables */
3926                    SCOPE_VAR *scopeVar,        /* scope variables */
3927                    CPL_COMMAND *cmd)           /* first command */
3928{
3929   char *db;               /* data base name */
3930   long idxTerm = -1L;     /* term index */
3931   char from[LE2+1];       /* first key */
3932   char to[LE2+1];         /* last key */
3933   long count;             /* quantity limit */
3934   BOOLEAN reverse;        /* reverse flag */
3935   long postingValue;      /* parameter posting value */
3936   EFC_NUMBER_LIST listPostTagValue = { 0, NULL };  /* parameter posting tag value list */
3937    EFC_ERROR efcError = { 0, "" };                     /* efc module error locator */
3938    int line;                   /* text lit line count */
3939   long post;              /* posting index */
3940   long postTagCount;      /* posting tag index */
3941   char *postFlag;         /* posting required flag */
3942   STRUCT_PREVTERM prevTrm;   /* previous term structure */
3943   char key[LE2+1];        /* current key */
3944   long relPos = 0L;       /* relative position */
3945
3946   /* Get data base name, if missing: error */
3947   db = exeRequiredParm(exeVar,scopeVar,ATVALUE_DB);
3948   if (!db) return 0;
3949
3950   /* Get range limit */
3951   exeKey(from,scopeVar->parmList[PARM_FROM]);
3952   exeKey(to,scopeVar->parmList[PARM_TO]);
3953   count = exeNumber(exeVar,scopeVar,PARM_COUNT,1L,LONG_MAX,LONG_MAX);
3954   postingValue = exeNumber(exeVar,scopeVar,PARM_POSTING,0L,LONG_MAX,0L);
3955   if (scopeVar->parmList[PARM_POSTTAG])
3956   {
3957        if (efc_numberList(&efcError,&listPostTagValue,scopeVar->parmList[PARM_POSTTAG]) < 0L)
3958      {
3959        exeError(exeVar->program,EXE_ERROR_ALLOC,efcError.info);
3960        return exeTaskKeyrangeReturn(idxTerm,&listPostTagValue);
3961      }
3962   }
3963   reverse = (BOOLEAN)(exePrecise(scopeVar->parmList[PARM_REVERSE]) == PRECISE_ON);
3964
3965   /* Get local term index */
3966   idxTerm = eci_trm_new(&(exeVar->program->error));
3967   if (idxTerm < 0L) {
3968      exeError(exeVar->program,EXE_ERROR_MAXNTRM,NULL);
3969      return exeTaskKeyrangeReturn(idxTerm,&listPostTagValue);
3970   }
3971
3972   /* Set parameters */
3973   scopeVar->defineList[PRECISE_FROM].text = efc_strrepl(scopeVar->defineList[PRECISE_FROM].text,from);
3974   scopeVar->defineList[PRECISE_TO].text = efc_strrepl(scopeVar->defineList[PRECISE_TO].text,to);
3975   postFlag = scopeVar->parmList[PARM_POSTING];
3976   if (postFlag)
3977      if (!*postFlag) postFlag = NULL;
3978   if (listPostTagValue.qtt && !postFlag) postFlag = scopeVar->parmList[PARM_POSTTAG];
3979
3980   /* Start previous term sctructure */
3981   IniPreviousTerm(&prevTrm);
3982
3983   /* Call term, check end of inverted */
3984   term(idxTerm,db,from);
3985   if (reverse)
3986      if (VTRMrc(idxTerm) != RCNORMAL) exeNextKey(reverse,idxTerm,&prevTrm);
3987   if (VTRMrc(idxTerm) == RCEOF) return exeTaskKeyrangeReturn(idxTerm,&listPostTagValue);
3988
3989   /* Loop range of terms */
3990   for ( ; ; exeNextKey(reverse,idxTerm,&prevTrm)) {
3991
3992      /* Check end of inverted, check quantity of itens limit */
3993      if (VTRMrc(idxTerm) == RCEOF) break;
3994      if (relPos >= count) break;
3995
3996      /* Check end of range */
3997      if (*to)
3998         if (reverse) {
3999            if (strcmp(VTRMkey(idxTerm),to) < 0) break;
4000         } else
4001            if (strcmp(VTRMkey(idxTerm),to) > 0) break;
4002
4003      /* Get total of postings */
4004      scopeVar->defineList[PRECISE_POSTINGS].value = posting(idxTerm,0L);
4005      if (scopeVar->defineList[PRECISE_POSTINGS].value <= 0L) continue;
4006
4007      /* Trim right current key */
4008      efc_trim_right(strcpy(key,VTRMkey(idxTerm)));
4009      scopeVar->defineList[PRECISE_KEY].text = efc_strrepl(scopeVar->defineList[PRECISE_KEY].text,key);
4010
4011      /* Loop all postings */
4012      for (post = 1L,postTagCount = 1L; /* no error */; post++) {
4013
4014         /* Posting information required */
4015         if (postFlag) {
4016
4017            /* Get current posting information */
4018            if (posting(idxTerm,post) < 1L) break;
4019
4020            /* Check posting tag value list */
4021                if (listPostTagValue.qtt > 0)
4022            {
4023                 for (line = 0L; line < listPostTagValue.qtt; line++)
4024               {
4025                if (VTRMptag(idxTerm) == listPostTagValue.list[line]) break;
4026               }
4027               if (line >= listPostTagValue.qtt) continue;
4028            }
4029
4030            /* Check posting limit */
4031            if (postingValue)
4032               if (listPostTagValue.qtt > 0) {
4033                  if (postTagCount > postingValue) break;
4034                  else postTagCount++;
4035               } else
4036                  if (post > postingValue) break;
4037
4038            /* Make posting information buffer */
4039            if (scopeVar->defineList[PRECISE_POSTING].tag) {
4040               sprintf(exeVar->buff,"^i%ld^m%ld^t%d^o%d^c%d",post,VTRMpmfn(idxTerm),
4041                  VTRMptag(idxTerm),VTRMpocc(idxTerm),VTRMpcnt(idxTerm));
4042               scopeVar->defineList[PRECISE_POSTING].text = efc_strrepl(scopeVar->defineList[PRECISE_POSTING].text,exeVar->buff);
4043            }
4044
4045         }
4046
4047         /* Check quantity of itens limit */
4048         if (relPos++ >= count) break;
4049
4050         /* Set define current position */
4051         scopeVar->defineList[PRECISE_CURRENT].value = relPos;
4052
4053         /* Call record execution */
4054         exeGo(exeVar,scopeVar,cmd);
4055         if (scopeVar->skip == PRECISE_QUIT) break;
4056
4057         /* Check posting loop */
4058         if (!postFlag) break;
4059
4060      } /* for */
4061
4062      /* Check skip flag */
4063      if (scopeVar->skip == PRECISE_QUIT) break;
4064
4065   } /* for */
4066
4067   /* Return */
4068   return exeTaskKeyrangeReturn(idxTerm,&listPostTagValue);
4069
4070} /* exeTaskKeyrange */
4071
4072/* =============================================================== exeTaskDo */
4073void exeTaskDo(EXE_VAR *exeVar,           /* execution variables */
4074               SCOPE_VAR *scopeVar,       /* scope variables */
4075               CPL_COMMAND *cmd)          /* first command */
4076{
4077   long from;              /* first MFN */
4078   long to;                /* last MFN */
4079   long count;             /* quantity limit */
4080   BOOLEAN reverse;        /* reverse flag */
4081   long pos;               /* current position */
4082   long relPos = 0L;       /* relative position */
4083
4084   /* Get range limit */
4085   from = exeNumber(exeVar,scopeVar,PARM_FROM,1L,LONG_MAX,1L);
4086   to = exeNumber(exeVar,scopeVar,PARM_TO,from,LONG_MAX,LONG_MAX);
4087   count = exeNumber(exeVar,scopeVar,PARM_COUNT,1L,LONG_MAX,LONG_MAX);
4088   if (exeVar->program->error.code) return;
4089   reverse = (BOOLEAN)(exePrecise(scopeVar->parmList[PARM_REVERSE]) == PRECISE_ON);
4090
4091   /* Set define variables */
4092   scopeVar->defineList[PRECISE_FROM].value = from;
4093   scopeVar->defineList[PRECISE_TO].value = to;
4094   scopeVar->defineList[PRECISE_TOTAL].value = to;
4095
4096   /* Loop range of limits */
4097   for (pos = from; pos <= to; pos++) {
4098
4099      /* Check quantity of records limit */
4100      if (relPos++ >= count) break;
4101
4102      /* Set define current position */
4103      /* scopeVar->defineList[PRECISE_CURRENT].value = pos */
4104      scopeVar->defineList[PRECISE_CURRENT].value = exePos(reverse,to,pos); /* 0.9g */
4105
4106      /* Clear record */
4107      if (eci_field_D(&(exeVar->program->error),scopeVar->idxCurr,0)) {
4108         exeError(exeVar->program,EXE_ERROR_FIELD,NULL);
4109         return;
4110      }
4111
4112      /* Call record execution */
4113      exeGo(exeVar,scopeVar,cmd);
4114      if (scopeVar->skip == PRECISE_QUIT) break;
4115
4116   } /* for */
4117
4118} /* exeTaskDo */
4119
4120/* ========================================================= exeTaskMfnrange */
4121void exeTaskMfnrange(EXE_VAR *exeVar,           /* execution variables */
4122                     SCOPE_VAR *scopeVar,       /* scope variables */
4123                     CPL_COMMAND *cmd)          /* first command */
4124{
4125   char *db;               /* data base name */
4126   long from;              /* first MFN */
4127   long to;                /* last MFN */
4128   long count;             /* quantity limit */
4129   BOOLEAN reverse;        /* reverse flag */
4130   long pos;               /* current position */
4131   long relPos = 0L;       /* relative position */
4132
4133   /* Get data base name, if missing: error */
4134   db = exeDB(exeVar,scopeVar);
4135   if (!db) return;
4136
4137   /* Get range limit */
4138   from = exeNumber(exeVar,scopeVar,PARM_FROM,1L,LONG_MAX,1L);
4139   to = exeNumber(exeVar,scopeVar,PARM_TO,from,LONG_MAX,LONG_MAX);
4140   count = exeNumber(exeVar,scopeVar,PARM_COUNT,1L,LONG_MAX,LONG_MAX);
4141   if (exeVar->program->error.code) return;
4142   reverse = (BOOLEAN)(exePrecise(scopeVar->parmList[PARM_REVERSE]) == PRECISE_ON);
4143
4144   /* Set define variables */
4145   scopeVar->defineList[PRECISE_TOTAL].value = eci_last_mfn(&(exeVar->program->error),db);
4146   scopeVar->defineList[PRECISE_FROM].value = from;
4147   scopeVar->defineList[PRECISE_TO].value = to;
4148
4149   /* 14.Aug.2000 Avoid Isis_Key field update for the <extract> */
4150   scopeVar->defineList[PRECISE_KEY].apply = FALSE;
4151
4152   /* Loop range of MFNs */
4153   for (pos = from; pos <= to; pos++) {
4154
4155      /* Check quantity of records limit */
4156      if (relPos++ >= count) break;
4157
4158      /* Read record, check record status */
4159      if (pos > scopeVar->defineList[PRECISE_TOTAL].value) break;
4160      record(scopeVar->idxCurr,db,exePos(reverse,scopeVar->defineList[PRECISE_TOTAL].value,pos));
4161      if (VRECrc(scopeVar->idxCurr) == RCEOF) break;
4162      if (scopeVar->defineList[PRECISE_STATUS].tag)
4163      {
4164         scopeVar->defineList[PRECISE_STATUS].value = VRECrc(scopeVar->idxCurr);
4165         if (VRECgdbw(scopeVar->idxCurr) != 0) scopeVar->defineList[PRECISE_STATUS].value = RCLOCK;
4166         /* 04.Nov.1999 - The record is locked, but the RECrc contains RCNORMAL */
4167      }
4168      else
4169         if (VRECrc(scopeVar->idxCurr) != RCNORMAL) continue;
4170
4171      /* Set define current position */
4172      scopeVar->defineList[PRECISE_CURRENT].value = pos;
4173
4174      /* Call record execution */
4175      exeGo(exeVar,scopeVar,cmd);
4176      if (scopeVar->skip == PRECISE_QUIT) break;
4177   } /* for */
4178
4179} /* exeTaskMfnrange */
4180
4181/* ================================================================= exeLoop */
4182void exeLoop(EXE_VAR *exeVar,          /* execution variables */
4183             SCOPE_VAR *scopeVar,      /* scope variables */
4184             CPL_COMMAND *cmd)         /* current command */
4185{
4186   SCOPE_VAR localScopeVar;      /* local variables for sub-command */
4187   CPL_ATVALUE task;             /* task to be executed */
4188   char *taskText;               /* task text message */
4189
4190   /* Copy scope variables */
4191   memcpy(&localScopeVar,scopeVar,sizeof(SCOPE_VAR));
4192
4193   /* Set local variables */
4194   localScopeVar.idxPrev = scopeVar->idxCurr;
4195   localScopeVar.idxCurr = exeWorkRecord(exeVar);
4196   if (localScopeVar.idxCurr < 0L) {
4197      exeError(exeVar->program,EXE_ERROR_ALLOC,cplElement[cmd->element].text);
4198      return;
4199   }
4200   localScopeVar.father = cmd;
4201
4202   /* Get task attribute, if absent get task parameter */
4203   task = scopeVar->father->attributeList[ATTRIBUTE_TASK].atValue;
4204   taskText = scopeVar->father->attributeList[ATTRIBUTE_TASK].text;
4205   if (!task || task >= ATVALUE_LIST_QTT)
4206      if (scopeVar->parmList[PARM_TASK]) {
4207         task = cplIdentifier(cplAtValue,ATVALUE_LIST_QTT,scopeVar->parmList[PARM_TASK]);
4208         taskText = scopeVar->parmList[PARM_TASK];
4209      }
4210
4211   /* Check default loop */
4212   if (!task)
4213      exeTaskDo(exeVar,&localScopeVar,cmd->sub);
4214   else {
4215      /* Evaluate task attribute */
4216      switch (task) {
4217
4218      case ATVALUE_FULLINV :
4219         /* Database Full invertion */
4220         exeTaskFullInvertion(exeVar,&localScopeVar);
4221         break;
4222
4223      case ATVALUE_IMPORT :
4224         /* Import records */
4225         exeTaskImport(exeVar,&localScopeVar,cmd->sub);
4226         break;
4227
4228      case ATVALUE_INVLOAD :
4229         /* Inverted load */
4230         exeTaskInvertedLoad(exeVar,&localScopeVar,TRUE);
4231         break;
4232
4233      case ATVALUE_KEYRANGE :
4234         /* Range of keys */
4235         exeTaskKeyrange(exeVar,&localScopeVar,cmd->sub);
4236         break;
4237
4238      case ATVALUE_LIST :
4239         /* Loaded list sequence */
4240         exeTaskList(exeVar,&localScopeVar,cmd->sub);
4241         break;
4242
4243      case ATVALUE_MFNRANGE :
4244         /* Range of records */
4245         exeTaskMfnrange(exeVar,&localScopeVar,cmd->sub);
4246         break;
4247
4248      case ATVALUE_MSTSORT :
4249         /* Master sort */
4250         exeTaskMasterSort(exeVar,&localScopeVar,NULL);
4251         break;
4252
4253      case ATVALUE_SEARCH :
4254         /* Search */
4255         exeTaskSearch(exeVar,&localScopeVar,cmd->sub);
4256         break;
4257
4258      case ATVALUE_UPDATE :
4259         /* Update record */
4260         exeTaskUpdate(exeVar,&localScopeVar,cmd->sub);
4261         break;
4262
4263      default :
4264         /* Invalid option */
4265         exeError(exeVar->program,EXE_ERROR_INVALID,taskText);
4266         break;
4267
4268      } /* switch */
4269   }
4270
4271   /* Transfer defines */
4272   exeDefines(exeVar,&localScopeVar,scopeVar->idxCurr);
4273
4274   /* Close scope */
4275   exeScopeClose(&localScopeVar);
4276
4277   /* Garbage collector */
4278   eci_rec_free(localScopeVar.idxCurr);
4279
4280} /* exeLoop */
4281
4282/* =================================================================== exeHL */
4283void exeHL(EXE_VAR *exeVar,         /* execution variables */
4284           SCOPE_VAR *scopeVar,     /* indexes */
4285           CPL_COMMAND *cmd)        /* current command */
4286{
4287   SCOPE_VAR localScopeVar;      /* local variables for sub-command */
4288
4289   /* Copy scope variables */
4290   memcpy(&localScopeVar,scopeVar,sizeof(SCOPE_VAR));
4291
4292   /* Set local variables */
4293   localScopeVar.idxPrev = scopeVar->idxCurr;
4294   localScopeVar.idxCurr = exeWorkRecord(exeVar);
4295   if (localScopeVar.idxCurr < 0L) {
4296      exeError(exeVar->program,EXE_ERROR_ALLOC,cplElement[cmd->element].text);
4297      return;
4298   }
4299   eci_rec_copy(localScopeVar.idxCurr,scopeVar->idxCurr);
4300   localScopeVar.father = cmd;
4301
4302   /* Call sub-command */
4303   exeGo(exeVar,&localScopeVar,cmd->sub);
4304
4305   /* Close scope */
4306   exeScopeClose(&localScopeVar);
4307
4308   /* Garbage collector */
4309   eci_rec_free(localScopeVar.idxCurr);
4310
4311} /* exeHL */
4312
4313/* =================================================================== exeDo */
4314void exeDo(EXE_VAR *exeVar,         /* execution variables */
4315           SCOPE_VAR *scopeVar,     /* indexes */
4316           CPL_COMMAND *cmd)        /* current command */
4317{
4318   SCOPE_VAR localScopeVar;      /* local variables for sub-command */
4319
4320   /* Start scope variables */
4321   exeStartScope(&localScopeVar);
4322
4323   /* Set local variables */
4324   localScopeVar.idxPrev = scopeVar->idxPrev;
4325   localScopeVar.idxRetn = scopeVar->idxRetn;
4326   localScopeVar.idxCurr = scopeVar->idxCurr;
4327   localScopeVar.father = cmd;
4328
4329   /* Call sub-command */
4330   exeGo(exeVar,&localScopeVar,cmd->sub);
4331
4332   /* Close scope */
4333   exeScopeClose(&localScopeVar);
4334
4335   /* Garbage collector */
4336   exeScopeFree(&localScopeVar);
4337
4338} /* exeDo */
4339
4340/* ========================================================== exeStartGlobal */
4341void exeStartGlobal(void)
4342{
4343   int i;      /* auxiliary index */
4344
4345   /* Return cipar flag to no cipar */
4346   dbxcdcip = efc_free(dbxcdcip);
4347
4348   /* Return isisuctab and isisactab to the standard */
4349   for (i = 0; i < 256; i++) isisuctab[i] = exeUctab[i];
4350   memset(isiswctab,0x00,256);
4351   for (i = 0; exeActab[i]; i++) isiswctab[exeActab[i]] = 1;
4352}
4353
4354/* ================================================================ exeGroup */
4355void exeSection(EXE_VAR *exeVar,          /* execution variables */
4356                SCOPE_VAR *scopeVar,      /* indexes */
4357                CPL_COMMAND *cmd)         /* current command */
4358{
4359   SCOPE_VAR localScopeVar;      /* local variables for sub-command */
4360
4361   /* Start scope variables */
4362   exeStartScope(&localScopeVar);
4363
4364   /* Set local variables */
4365   localScopeVar.idxPrev = scopeVar->idxCurr;
4366   localScopeVar.idxRetn = scopeVar->idxRetn;
4367   localScopeVar.idxCurr = exeWorkRecord(exeVar);
4368   if (localScopeVar.idxCurr < 0L) {
4369      exeError(exeVar->program,EXE_ERROR_ALLOC,cplElement[cmd->element].text);
4370      return;
4371   }
4372   localScopeVar.father = cmd;
4373
4374   /* Call sub-command */
4375   exeGo(exeVar,&localScopeVar,cmd->sub);
4376
4377   /* Garbage collector */
4378   eci_rec_free(localScopeVar.idxCurr);
4379
4380   /* Close scope */
4381   exeScopeClose(&localScopeVar);
4382
4383   /* Garbage collector */
4384   eci_rec_free(localScopeVar.idxCurr);
4385
4386   /* Garbage collector */
4387   exeScopeFree(&localScopeVar);
4388
4389   /* Restore IsisScript default */
4390   exeStartGlobal();
4391
4392} /* exeSection */
4393
4394/* ================================================================= exeNext */
4395CPL_COMMAND *exeNext(CPL_COMMAND *cmd)    /* current command */
4396{
4397
4398   /* Check command list */
4399   if (!cmd) return NULL;
4400
4401   /* Return next command */
4402   return cmd->next;
4403
4404} /* exeNext */
4405
4406/* ================================================================ exePrint */
4407void exePrint(EXE_VAR *exeVar,            /* execution variables */
4408              CPL_COMMAND *cmd,           /* current command */
4409              TRACE_PART tracePart)       /* print trace part */
4410{
4411   /* [0.8] Check command parameter */
4412   if (!cmd) return;
4413
4414   /* [4.0] Trace over compiled command is forbidden */
4415   if (cmd->isCompiled) return;
4416
4417   /* Avoid obvious print */
4418   if (cmd->element == ELEMENT_DISPLAY ||
4419       cmd->element == ELEMENT_DISPL) return;
4420
4421   /* Evaluate trace option */
4422   switch (exeVar->trace) {
4423
4424   case PRECISE_ON:
4425      /* Normal trace */
4426      switch (tracePart) {
4427
4428      case TRACE_SEPARATOR:
4429         printf("\n");
4430         break;
4431
4432      case TRACE_CMD:
4433         cplPrintScope(exeVar->scope);
4434         cplPrintCommand(cmd,FALSE);
4435         break;
4436
4437      case TRACE_TEXT:
4438         if (cmd->sub)
4439            if (cmd->sub->altn) printf("%s",((EXE_FORMAT *)cmd->sub->altn)->text);
4440            else
4441               if (!cmd->sub->altn) cplPrintScope(exeVar->scope);
4442         cplPrintCommandClose(cmd,FALSE);
4443         break;
4444
4445      } /* switch */
4446
4447      break;
4448
4449   case PRECISE_BR:
4450      /* HTML style */
4451      switch (tracePart) {
4452
4453      case TRACE_SEPARATOR:
4454         break;
4455
4456      case TRACE_CMD:
4457         printf("<br>");
4458         cplPrintCommand(cmd,TRUE);
4459         break;
4460
4461      case TRACE_TEXT:
4462         if (cmd->sub)
4463            if (cmd->sub->altn) printf("%s",((EXE_FORMAT *)cmd->sub->altn)->text);
4464         cplPrintCommandClose(cmd,TRUE);
4465         break;
4466
4467      } /* switch */
4468
4469      break;
4470
4471   case PRECISE_TABLE:
4472      /* HTML table style */
4473      switch (tracePart) {
4474
4475      case TRACE_SEPARATOR:
4476         break;
4477
4478      case TRACE_CMD:
4479         printf("<table border=\"1\"><tr><td bgcolor=\"#C0C0C0\">");
4480         cplPrintCommand(cmd,TRUE);
4481         printf("</td></tr></table>");
4482         break;
4483
4484      case TRACE_TEXT:
4485         printf("<table border=\"1\"><tr><td bgcolor=\"#C0C0C0\">");
4486         if (cmd->sub)
4487            if (cmd->sub->altn) printf("%s",((EXE_FORMAT *)cmd->sub->altn)->text);
4488         cplPrintCommandClose(cmd,TRUE);
4489         printf("</td></tr></table>");
4490         break;
4491
4492      } /* switch */
4493
4494      break;
4495
4496   } /* switch */
4497
4498} /* exePrint */
4499
4500/* =================================================================== exeGo */
4501void exeGo(EXE_VAR *exeVar,       /* execution variables */
4502           SCOPE_VAR *scopeVar,   /* indexes */
4503           CPL_COMMAND *cmd)      /* current command */
4504{
4505   char *text;          /* auxiliary text buffer */
4506
4507   /* Increase scope, reset skip option, field update define variables */
4508   exeVar->scope++;
4509   scopeVar->skip = PRECISE_OFF;
4510   exeDefines(exeVar,scopeVar,scopeVar->idxCurr);
4511   if (exeVar->program->error.code) return;
4512
4513   /* Print trace */
4514   if (exeVar->trace != PRECISE_OFF) exePrint(exeVar,cmd,TRACE_SEPARATOR);
4515
4516   /* Loop all commands until error or no more commands */
4517   while (cmd) {
4518
4519      /* Print trace */
4520      if (exeVar->trace != PRECISE_OFF) exePrint(exeVar,cmd,TRACE_CMD);
4521
4522      /* Evaluate element type */
4523      switch (cmd->element) {
4524
4525      case ELEMENT_CALL:
4526      case ELEMENT_CGITABLE:
4527      case ELEMENT_DEFINE:
4528      case ELEMENT_EXPORT:
4529      case ELEMENT_EXTRACT:
4530      case ELEMENT_FIELD:
4531      case ELEMENT_FILE:
4532      case ELEMENT_FLOW:
4533      case ELEMENT_LIST:
4534      case ELEMENT_PROC:
4535      case ELEMENT_RETURN:
4536      case ELEMENT_TRACE:
4537      case ELEMENT_WRITE:
4538         /* Command element */
4539         cmd = exeCmd(exeVar,scopeVar,cmd);
4540         break;
4541
4542      case ELEMENT_DISPLAY:
4543      case ELEMENT_DISPL:
4544         /* Display text */
4545         text = exeText(exeVar,scopeVar,scopeVar->idxCurr,cmd);
4546
4547#ifdef XIS_SERVER
4548       if (text) {
4549             writeBuff(text, outBuffer, 1);
4550         }
4551#else
4552         if (text) fprintf(exeVar->output,"%s",text);
4553#endif /* XIS_SERVER */
4554         break;
4555
4556      case ELEMENT_DO:
4557         /* Do a task */
4558         if (cmd->sub) exeDo(exeVar,scopeVar,cmd);
4559         break;
4560
4561      case ELEMENT_HL:
4562         /* Highlight group */
4563         exeHL(exeVar,scopeVar,cmd);
4564         break;
4565
4566      case ELEMENT_INCLUDE:
4567         break;
4568
4569      case ELEMENT_ISISSCRIPT:
4570         /* Start isis script */
4571         exeGo(exeVar,scopeVar,cmd->sub);
4572         break;
4573
4574      case ELEMENT_LOOP:
4575      case ELEMENT_UPDATE:
4576         /* Repeat commands */
4577         exeLoop(exeVar,scopeVar,cmd);
4578         break;
4579
4580      case ELEMENT_PARM:
4581         /* Get parameter */
4582         exeParm(exeVar,scopeVar,cmd);
4583         break;
4584
4585      case ELEMENT_SECTION:
4586         /* Section group */
4587         if (cmd->sub) exeSection(exeVar,scopeVar,cmd);
4588         break;
4589
4590      } /* switch */
4591
4592      /* Check error code */
4593      if (exeVar->program->error.code) break;
4594
4595      /* Print trace */
4596      if (exeVar->trace != PRECISE_OFF) exePrint(exeVar,cmd,TRACE_TEXT);
4597
4598      /* Check flow option */
4599      if (scopeVar->skip == PRECISE_NEXT || scopeVar->skip == PRECISE_QUIT) break;
4600      if (scopeVar->jump) {
4601         cmd = scopeVar->jump;
4602         scopeVar->jump = NULL;
4603         continue;
4604      }
4605
4606      /* Get next command */
4607      cmd = exeNext(cmd);
4608
4609   } /* while */
4610
4611   /* Decrease scope */
4612   exeVar->scope--;
4613
4614} /* exeGo */
4615
4616/* ========================================================= exeStartOptions */
4617void exeStartOptions(void)       /* execution variables */
4618{
4619
4620   /* Set attribute value to parm index table */
4621   memset(&atValueParm,0x00,sizeof(atValueParm));
4622   atValueParm[ATVALUE_ACTAB]       = PARM_ACTAB;
4623   atValueParm[ATVALUE_BUFFERSIZE]  = PARM_BUFFERSIZE;
4624   atValueParm[ATVALUE_CIPAR]       = PARM_CIPAR;
4625   atValueParm[ATVALUE_COUNT]       = PARM_COUNT;
4626   atValueParm[ATVALUE_DB]          = PARM_DB;
4627   atValueParm[ATVALUE_DECOD]       = PARM_DECOD;
4628   atValueParm[ATVALUE_DELIMITER]   = PARM_DELIMITER;
4629   atValueParm[ATVALUE_EXPIRE]      = PARM_EXPIRE;
4630   atValueParm[ATVALUE_EXPRESSION]  = PARM_EXPRESSION;
4631   atValueParm[ATVALUE_FILE]        = PARM_FILE;
4632   atValueParm[ATVALUE_FREQSUM]     = PARM_FREQSUM;
4633   atValueParm[ATVALUE_FROM]        = PARM_FROM;
4634   atValueParm[ATVALUE_FST]         = PARM_FST;
4635   atValueParm[ATVALUE_GIZMO]       = PARM_GIZMO;
4636   atValueParm[ATVALUE_INDEXLIST]   = PARM_INDEXLIST;
4637   atValueParm[ATVALUE_KEY]         = PARM_KEY;
4638   atValueParm[ATVALUE_KEYFIELD]    = PARM_KEYFIELD;
4639   atValueParm[ATVALUE_KEYLENGTH]   = PARM_KEYLENGTH;
4640   atValueParm[ATVALUE_KEYS]        = PARM_KEYS;
4641   atValueParm[ATVALUE_KEYSDB]      = PARM_KEYSDB;
4642   atValueParm[ATVALUE_LOCKID]      = PARM_LOCKID;
4643   atValueParm[ATVALUE_MAXLK]       = PARM_MAXLK;
4644   atValueParm[ATVALUE_MFN]         = PARM_MFN;
4645   atValueParm[ATVALUE_POSTING]     = PARM_POSTING;
4646   atValueParm[ATVALUE_POSTTAG]     = PARM_POSTTAG;
4647   atValueParm[ATVALUE_PREFIX]      = PARM_PREFIX;
4648   atValueParm[ATVALUE_RESET]       = PARM_RESET;
4649   atValueParm[ATVALUE_REVERSE]     = PARM_REVERSE;
4650   atValueParm[ATVALUE_SORT]        = PARM_SORT;
4651   atValueParm[ATVALUE_STW]         = PARM_STW;
4652   atValueParm[ATVALUE_SUFFIX]      = PARM_SUFFIX;
4653   atValueParm[ATVALUE_TASK]        = PARM_TASK;
4654   atValueParm[ATVALUE_TO]          = PARM_TO;
4655   atValueParm[ATVALUE_TYPE]        = PARM_TYPE;
4656   atValueParm[ATVALUE_UCTAB]       = PARM_UCTAB;
4657   /* 27.Nov.2000 */
4658   atValueParm[ATVALUE_PREFIX_HTMLPFT] = PARM_PREFIX_HTMLPFT;
4659   atValueParm[ATVALUE_SUFFIX_HTMLPFT] = PARM_SUFFIX_HTMLPFT;
4660   /* 28.Nov.2000 */
4661   atValueParm[ATVALUE_FIRST_LINE]  = PARM_FIRST_LINE;
4662   /* 22.Feb.2001 */
4663   atValueParm[ATVALUE_ISISXML_STYLE] = PARM_ISISXML_STYLE;
4664   atValueParm[ATVALUE_ISISXML_TABLE] = PARM_ISISXML_TABLE;
4665   /* 05.Apr.2001 */
4666   atValueParm[ATVALUE_LOG] = PARM_LOG;
4667
4668   /* Set precise option list */
4669   preciseList[PRECISE_CURRENT] =   "Isis_Current";
4670   preciseList[PRECISE_ERRORINFO] = "Isis_ErrorInfo";
4671   preciseList[PRECISE_FROM] =      "Isis_From";
4672   preciseList[PRECISE_GETNEW] =    "GetNew";
4673   preciseList[PRECISE_HLINE] =     "HLine";
4674   preciseList[PRECISE_KEYS] =      "Isis_Keys";
4675   preciseList[PRECISE_BR] =        "BR";
4676   preciseList[PRECISE_ISO2709] =   "ISO2709";
4677   preciseList[PRECISE_ISO2709_CRLF] = "ISO2709_CRLF";
4678   preciseList[PRECISE_ITEM] =      "Isis_Item";
4679   preciseList[PRECISE_ITENS] =     "Isis_Itens";
4680   preciseList[PRECISE_ITEMS] =     "Isis_Items";
4681   preciseList[PRECISE_KEY] =       "Isis_Key";
4682   preciseList[PRECISE_LOCK] =      "Isis_Lock";
4683   preciseList[PRECISE_MFN] =       "Isis_MFN";
4684   preciseList[PRECISE_NEW] =       "New";
4685   preciseList[PRECISE_NEXT] =      "Next";
4686   preciseList[PRECISE_OFF] =       "Off";
4687   preciseList[PRECISE_ON] =        "On";
4688   preciseList[PRECISE_POSTING] =   "Isis_Posting";
4689   preciseList[PRECISE_POSTINGS] =  "Isis_Postings";
4690   preciseList[PRECISE_QUIT] =      "Quit";
4691   preciseList[PRECISE_RECSTAT] =   "Isis_RecordStatus";
4692   preciseList[PRECISE_RLINE] =     "RLine";
4693   preciseList[PRECISE_STATUS] =    "Isis_Status";
4694   preciseList[PRECISE_TABLE] =     "Table";
4695   preciseList[PRECISE_TO] =        "Isis_To";
4696   preciseList[PRECISE_TOTAL] =     "Isis_Total";
4697   preciseList[PRECISE_MARC21] =    "MARC21";
4698   preciseList[PRECISE_VALUE] =     "Isis_Value";
4699   preciseList[PRECISE_VLINE] =     "VLine";
4700   preciseList[PRECISE_WDELETE] =   "Delete";
4701   preciseList[PRECISE_WLOCK] =     "Lock";
4702   preciseList[PRECISE_WNOUNLOCK] = "NoUnlock";
4703   preciseList[PRECISE_WUNLOCK] =   "Unlock";
4704
4705    /* 05.Abr.2001 */
4706   preciseList[PRECISE_SETNUMBER] =   "Isis_SetNumber";
4707
4708} /* exeStartOptions */
4709
4710/* ================================================================ exeStart */
4711EXE_ERROR exeStart(EXE_VAR *exeVar,       /* execution variables */
4712                   CPL_STRUCT *program,   /* program structure */
4713                   CGI_PARAM *cgiList)    /* CGI argument list */
4714{
4715
4716/* Reset all variables */
4717    memset(exeVar,0x00,sizeof(EXE_VAR));
4718
4719   /* Set cisis global tables */
4720   exeStartGlobal();
4721
4722   /* Set current program variables */
4723   exeVar->program = program;
4724   exeVar->cgiList = cgiList;
4725   exeVar->output = stdout;
4726   exeVar->scope = -1;
4727   exeVar->trace = PRECISE_OFF;
4728   exeVar->buffSize = EXE_BUFF_SIZE;
4729
4730   /* Set precise option identifiers */
4731   exeStartOptions();
4732
4733   /* Allocate common string buffer area, if error return */
4734   exeVar->buff = exeNew(exeVar,exeVar->buffSize);
4735   if (!exeVar->buff) return EXE_ERROR_ALLOC;
4736
4737   /* Return no error */
4738   return EXE_ERROR_OK;
4739
4740} /* exeStart */
4741
4742/* ============================================================== exeCplFree */
4743void exeCplFree(CPL_COMMAND *first)    /* first command */
4744{
4745   CPL_COMMAND *cmd;       /* current command */
4746   EXE_FORMAT *fmt;        /* format cast */
4747   FST_CODE *fstCode;      /* FST code cast */
4748
4749   /* Garbage collector */
4750   for (cmd = first; cmd; cmd = cmd->next) {
4751      if (cmd->sub) exeCplFree(cmd->sub);
4752      if (cmd->element == ELEMENT_PARM && cmd->attributeList[ATTRIBUTE_NAME].atValue == ATVALUE_FST) {
4753         fstCode = (FST_CODE *)(cmd->altn);
4754         if (fstCode) fst_free(fstCode);
4755      }
4756      if (cmd->element == ELEMENT_PFT || cmd->element == ELEMENT_ISISXML) {
4757         fmt = (EXE_FORMAT *)(cmd->altn);
4758         if (fmt) {
4759            if (fmt->code) fmt_free(fmt->code);
4760            if (fmt->ciXml)
4761            {
4762                cixmlFree(fmt->ciXml);
4763               efc_free(fmt->ciXml);
4764            }
4765            if (fmt->text) efc_free(fmt->text);
4766            efc_free(fmt);
4767         }
4768      }
4769   } /* for */
4770
4771} /* cplFree */
4772
4773/* ================================================================= exeFree */
4774void exeFree(EXE_VAR *exeVar) /* execution variables */
4775{
4776
4777   /* Garbage collection */
4778   efc_free(exeVar->buff);
4779   freq_free(exeVar->freq.head);
4780   if (exeVar->output != stdout) fclose(exeVar->output);
4781} /* exeFree */
4782
4783/* ============================================================= cleanShelves */
4784void cleanShelves() {
4785    int idx;
4786
4787    if (nrecs >= 10) {
4788        for(idx = 0; idx < MAXNREC; idx++) {
4789            if (vrecp[idx]) {
4790                FREE(vrecp[idx]);
4791                vrecp[idx] = NULL;
4792            }
4793        }
4794        nrecs = 0;
4795    }
4796
4797    if (ntrms >= 10) {
4798        for(idx = 0; idx < MAXNTRM; idx++) {
4799            if (vtrmp[idx]) {
4800                FREE(vtrmp[idx]);
4801                vtrmp[idx] = NULL;
4802            }
4803        }
4804        ntrms = 0;
4805    }
4806
4807    if (ndbxs > 10) {
4808        for(idx = 0; idx < MAXNDBX; idx++) {
4809            if (vdbxp[idx]) {
4810                dbxflush(vdbxp[idx]->dbxname);
4811                //mstclose(vdbxp[idx]->dbxname);
4812            }
4813        }
4814        ndbxs = 0;
4815    }
4816}
4817
4818/* ================================================================== exeRun */
4819EXE_ERROR exeRun(CPL_STRUCT *program,     /* program structure */
4820                 CGI_PARAM *cgiList,      /* cgi couple parameter list */
4821                 OUT_BUFFER *out)
4822{
4823   EXE_VAR exeVar;         /* execution variables */
4824   SCOPE_VAR scopeVar;     /* scope variables */
4825
4826   outBuffer = out;
4827
4828   //chrono_start();
4829
4830   /* Start execution variables, if OK execute program instructions */
4831   if (exeStart(&exeVar,program,cgiList) == EXE_ERROR_OK) {
4832      /* Start scope variables */
4833      exeStartScope(&scopeVar);
4834      /* Allocate a record index */
4835      scopeVar.idxCurr = exeWorkRecord(&exeVar);
4836      if (scopeVar.idxCurr >= 0L) {
4837         /* Call program execution, free record index */
4838         exeGo(&exeVar,&scopeVar,program->cmd);
4839         eci_rec_free(scopeVar.idxCurr);
4840      }
4841   }
4842
4843   /* Garbage collector */
4844   /*eci_rec_free(scopeVar.idxCurr); - freed in cleanShelves */
4845   exeScopeFree(&scopeVar);
4846   exeCplFree(program->cmd);
4847   exeFree(&exeVar);
4848
4849   cleanShelves();
4850
4851   //chrono_stop("exeRun");
4852
4853   /* Return error code */
4854   return program->error.code;
4855
4856} /* exeRun */
Note: See TracBrowser for help on using the browser.