root/tags/5.4.pre05/cifm1.c @ 1

Revision 1, 144.9 kB (checked in by heitor.barbieri, 2 years ago)

Criação do svn para Cisis.

Line 
1/*--------------------------------------------------------------------------*/
2/* File:fmt.c                                                               */
3/*--------------------------------------------------------------------------*/
4
5#define RPIVA 1         /* to fix Borland 4.5 compilation errors - 12/09/95 */
6#define NEST_REP_ALLOWED 0
7#define DEB_REF 0
8#define DEB_VAR 1
9/* Modificacoes:
10   A01 - 25/09/93
11         Problema:
12           Existem algumas situacoes em que o ISIS admite que existam brancos
13           entre elementos de formato e a implementacao CISIS nao permite.
14           Como exemplo:v20 ( 3,3) -> P/ ISIS correto
15                        v20 ( 3,3 )-> P/ ISIS incorreto
16           Para corrigir o problema poderia ser feito um levantamento de
17           todas as situacoes em que branco deveria ser considerado erro.
18           Discutindo com o Adalberto definimos que o CISIS aceitaria os
19           dois casos. Assim a implementacao ficou localizada apenas quando
20           vai selecionar o proximo symbol. Todos os brancos e tabs sao
21           ignorados.
22         Efeitos Colaterais:
23           Outras situacoes serao aceitas pelo CISIS e nao pelo ISIS.
24           Assim nao teremos compatibilidades a nivel de formato.
25           Se isso nao for desejavel, a solucao e fazer um levantamento
26           mais adequado de quais especificacoes devem ter branco.
27           Alem de "espaco" esta sendo ignorado o "tab". Pensei em
28           colocar CR LF . Se houver necessidade basta acrescentar no teste
29   A02 - 26/09/93
30         Problema:
31           Existem aplicacoes em em que e' interessante acessar registros
32           de outras bases de dados via comando REF.
33           Originalmente no ISIS e no CISIS isto nao e' possivel.
34         Solucao:
35           Discuti com Adalberto e fizemos a seguinte alteracao na  sintaxe:
36                   REF(<[nome_da_base]>mfn,...)  onde
37           <[nome_da_base]> e' opcional. Quando presente "[" "]" sao
38           obrigatorios e nome_da_base e' um string.
39         Exemplos:
40           REF ( [\cisis\bases\cds]10,v10,v20);
41           REF (20,v10,v30);
42           No primeiro caso sera executado o formato "v10,v20" para o registro
43           10 da base "\cisis\bases\cds" (Provavelmente diferente da base
44           default passada como parametro para o interpretador).
45           No segundo caso, o formato sera executado para a base default.
46         Implementacao:
47           Nao precisou fazer alteracoes nas estruturas de dados. O nome
48           da base de dados so e necessario na   instrucao READ_MFN.
49           Nessa instrucao o campo M_ADD nao tinha funcao nenhuma.
50           Entao o nome da base fica armazenado nesse campo, da mesma
51           maneira que sao armazenadas as constantes condicionais (U_COND)
52           Assim o tratamento e liberacao de area alocada ja e' feito
53           pelo interpretador.
54         Limitacoes:
55           A implementacao do nome da base poderia ser mais generica.
56           Dentro da sequencia "[...]" em vez de ter um string poderiamos
57           supor que e' um formato.
58           A analise , geracao de codigo, e interpretacao seriam mais
59           complicadas.( Mas nao impossiveis...).
60         Efeitos Colaterais:
61           Um formato que contenha a nova sintaxe do REF nao sera
62           aceito pelo ISIS.
63           Em termos de programas, nao deve haver alteracoes.
64         Observacao:
65           O Adalberto vai me ajudar (na verdade acho que fazer tudo) a
66           implementar a parte de interpretacao. (Nao sei usar direito
67           os RECORDS...)
68   A03 - 29/09/93
69         Problema:
70           Nao foi implementado o "[dbname]" para o LOOKUP.
71           O Adalberto tinha discutido mas nao fiz na A02.
72         Solucao:
73           Nao existe uma coerencia entre o REF e L. O primeiro   :
74           exige uma expressao numerica , pois corresponde ao mfn.
75           O segundo supoe que apos o L vem um formato ISIS que vai
76           gerar uma chave.
77           Apos a implementacao do "[..]" para REF o Adalberto sugeriu
78           que a sintaxe para ambos fosse diferente, algo como;
79                        dbname#chave.
80           Isto fica correto para  L mas nao para REF uma vez que apos
81           o REF e necessario uma expressao numerica  e o dbname nunca seria
82           analisado pelo CISIS.
83         Implementacao:
84           A implementacao ficara igual ao REF. de dados. O nome
85         Limitacoes:
86         Efeitos Colaterais:
87           Um formato que contenha a nova sintaxe do L nao sera
88           aceito pelo ISIS.
89           Em termos de programas, nao deve haver alteracoes.
90         Observacao:
91           O Adalberto vai me ajudar (na verdade acho que fazer tudo) a
92           implementar a parte de interpretacao. (Nao sei usar direito
93           os RECORDS...) (Continua Valido...)
94   A04 - 22/11/93
95         Problema:
96           Implementacao da funcao NP(key).
97           Deve retornar o numero de postings da chave.
98         Solucao:
99           Implementacao igual a do LOOKUP porem em vez de
100           carregar na pilha o MFN, carrega o numero de postings
101           da chave
102  A05 - 25/05/97
103        Problema:
104           Quando um formato fazia referencia a um arquivo e nesse
105           arquivo tivessemos "ifs" ocorria erro.
106           Isso acontece porque na implementacao de referencia a arquivo
107           a funcao get_ch le o proximo caracter do arquivo, em vez
108           de pega-lo no string do formato, e nos casos de "ifs" para
109           descobrir que tipo de expressoes (string ou numerica) sao
110           referenciadas e' necessario fazer um " look-AHEAD" .
111           Depois recomeca a pegar os caracteres a partir do ponto
112           de inicio da expressao. Nesse momento nao temos mais
113           os caracteres que compoe a expressao.
114       Solucao:
115           Alterada a get_ch para armazenar os caracteres do arquivo
116           em um buffer temporario.
117
118  A06 - 15/09/97
119        Problema:
120           Permitir que area para analisar constantes do tipo string
121           possa ter tamanho dinamico. Atualmente e uma area estatica
122           de tamanho 200.
123       Solucao:
124           Fazer com que a variavel str seja alocada dinamicamente.
125           Se durante o uso a area for toda ocupada fazer uma realocacao.
126           Muda-se: str e string_length
127                    str_read para realocar variavel
128  A07 - 05/10/97
129       Problema:
130         a) Existia erro  em relacao microisis -
131            o fmt="...'x',###,%,#,'y',..," e fmt="...'x',###,%,'y',..,"
132            produzem o mesmo resultado: muda de linha entre 'x' e 'y'
133            Na minha implementacao no segundo caso nao produzia nenhuma linha
134         b) Implementar o comando NEWLINE (<FMT>);
135       Solucao:
136         a) Na execucao de % verificar se apos retirar "muda-linha" tem
137            #. Em caso afirmativo, ignora essa instrucao.
138         b) Necessario mudar todas as referencias a crlf no programa, o
139            que implica em alterar varias rotinas.
140
141  A08 - 01/11/99
142       Problema: Compatibilizar sintaxes Cisis e MicroIsis
143                  Vtt[1..]  e  Vtt[1..LAST]
144                  Vtt[1]^a  e Vtt^a[1]
145                 Permitir o uso das duas formas
146       Solucao: Quebrar a rotina field_id para que a analise de subfield seja
147                feita separadamente assim permita verificar se existe indexa
148                cao antes de "^subfield" ou depois "^subfield"
149                Acusara erro se for especificado vtt[1]^a[1]
150
151
152  A09 - 01/11/99
153       Problema: Compatibilizar sintaxes Cisis e MicroIsis
154                  mstname e dbname
155                 Permitir o uso das duas formas
156       Solucao: Criar uma palavra reservada DB que mapeia no mesmo simbolo que
157                 que mstname
158
159  A10 - 01/11/99
160       Problema:  Implementar funcao SS equivalente a funcao Mid
161
162       Solucao:  Sera criada uma nova funcao, porem a execucao do codigo
163                 sera equivalente ao codigo da Mid.
164
165  A11 - 01/11/99
166       Problema:  Compatibilizar funcao date
167
168       Solucao:  date(1) = MM-DD-AAAA  HH:MM:SS
169                 date(2) = MM-DD_AAAA
170                 date(3) = HH:MM:SS
171                 date    =
172                 date(DATEONLY) = dd/mm/aa
173                 date(DATETIME) = dd/mm/aa hh:mm:ss
174
175  A12 - 05/11/99
176       Problema: Compatibilizar refencia ao dname com Microisis
177
178       Solucao:
179
180*/
181#include <stdio.h>
182#include <ctype.h>
183#include <string.h>
184#include "cisis.h"
185#include "cifmt.h"
186/* inicio implementacao [x:y] */
187/* como nao podera ser dado intervalo negativo, quando um campo
188   nao for explicitado com intervalo o default sera colocado como
189   negativo. Na interpretacao sera usado o seguinte criterio:
190   Se lower e upper negativos => nao foi indicado intervalo
191   Para pegar todas as ocorrencias pegar o ABS desses valores
192*/
193/* fim  implementacao [x:y] */
194/* Conferir...- deveria estar na cisis.h */
195#if PC
196#if MSC
197#define REALLOC realloc
198#else /*MSC*/
199#define REALLOC farrealloc
200#endif
201#endif
202
203#define CISIS_REF_DBN   1     /*A12*/
204#define MISIS_REF_DBN   0     /*A12*/
205#define DEB_ATFILE      0
206#define MAX_INT SHRT_MAX                /* +32767 */
207#define MIN_INT SHRT_MIN                /* -32768 */
208#define TRACE_COMP_F    00              /* printf f_d_n in store_field_def() */
209#if !CICPP
210#define MAX_NESTED_REPEAT 15
211#define res_words_length  8            /*21-07-94*/
212#define number_length   30
213/*A12*/
214int separa_nome_base = 0;
215/*A06*/
216unsigned int  string_length=MAX_LITER; /* Valor inicial de tamanho de str */
217#endif /* CICPP */
218/*#define string_length 200*/  /* este parametro deve ser uma variavel */
219                            /* inicializada c/ o lw */
220                            /* Nao e' possivel, pois o lw so vai ser
221                               conhecido em execucao sindo 14/07/97
222                            */
223#if !CICPP
224#define ERRORET         1
225#endif /* CICPP */
226#define apostrofo      '\''
227#define crase          '`'
228#define aspa           '\"'
229#define exclamacao     '!'
230#define atsign         '@'
231#define virgula        ','
232#define tab            '\t'
233/*Existe ambiguidade no uso de numeros pelo isis. Na especificacao de
234  extracao de campos V54.5 , 54.5 NAO pode ser interpretado com numero real.
235  Assim, precisamos saber na getsymbol se devemos parar quando separamos
236  um numero inteiro.
237  Quando classe_numero_procurado=PARSEINTNUMB, estamos querendo pegar
238  o proximo numero inteiro apenas. Caso contrario, podemos pegar qualquer
239  numero
240*/
241#define PARSEINTNUMB      1
242#if !CICPP
243static int classe_numero_procurado=0;
244#define MXOPNFMTFILES 16
245#define CUR_FMT_FILE  opn_fmtfiles[nopn_fmtfiles]
246static int opn_fmtfiles[MXOPNFMTFILES];
247static int nopn_fmtfiles= -1;
248#ifndef MAXPATH
249#define MAXPATH CIMPL
250#endif
251static char fmtfile[MAXPATH+1];
252/*fmt_ref_dbname,*/
253typedef char  alfa[res_words_length+1];
254/* Atencao: Os extremos (firstsym e zzzsym)do enumerado
255            abaixo NAO  podem ser modificados e nem mudados de posicao.
256            Eles sao usados para e criar vetores .
257*/
258typedef enum symbol_names {
259   firstsym,
260   csym,     xsym,     dsym,     nsym,     vsym,     ifsym,    fisym,
261   thensym,  elsesym,  orsym,    andsym,   notsym,   mfnsym,   mplsym,
262   mpusym,   mhlsym,   mhusym,   mdlsym,   mdusym,   fsym,     s_sym,
263   getenv_sym, putenv_sym,
264   refsym,   asym,     psym,     ravrsym,  valsym,   lsym,     lwsym,
265   rupxsym,
266   rupdsym,  systsym,  coresym,  maxmfnsym, datemktimesym,
267   rsumsym,  rminsym,  rmaxsym,
268   fmtsym,   usym,     isym,
269   abrcolch, fchcolch,
270   comma,    slash,    ponto,
271   number_sigx,
272   number_sign,percent,  lparen,   rparen,   flecha,   times,    plus,
273   minus,    doispontos, eql,    neq,      lss,      leq,      gtr,
274   geq,      space,    u_litsym, c_litsym, esc_strsym,number,  nullsym,
275   s_fieldsym,r_litsym,
276   long_number,float_number,
277   noccsym,  npsym,
278   ioccsym, continuesym,breaksym,
279   sizesym, typesym,
280   mstsym, datesym, date1sym, date2sym,
281   selsym, casesym, elsecasym, endselsym,
282   instrsym,
283   leftsym, datexsym,
284   rightsym,
285   midsym,
286   catsym,
287   replacsym,
288#if CI_XMLELEM
289   xmlelemsym,
290#endif
291   nl_sym,
292   lastsym,
293   intvarsym,
294   strvarsym,
295   whilesym,
296   occsym,
297   attribsym,
298   dbsym,
299   ss_sym,
300   np2sym,
301   citypesym,
302   textsym,    /*A12*/
303  zzzsym }  symbol;
304#endif /* CICPP */
305/*
306   Vetor sym_to_instruction
307   Usado para converter simbolo em instrucao para facilitar a geracao de
308   codigo
309*/
310#if !CICPP
311static instruction_code sym_to_instruction[zzzsym+9];
312static char  *pfmt ;     /* aponta para o formato de entrada  */
313static char ch = space_char;  /* last character read */
314static symbol sym;     /* last symbol read */
315static symbol field_fmt_sym;
316static int num ;       /* value of last integer number read */
317/*f01*/
318static LONGX long_num;
319static char float_num_str[number_length+1];
320/*f01*/
321static alfa fmttoken ;        /* word being read */
322/*A06*/
323static char *str;
324static int indvar;  /* Indice de variaveis numericas  vvv */
325
326/* static char str[string_length];*/  /*mudado para dinamico */
327static char sub_field_value = 0; /* value of last sub_field_read */
328static symbol ssym[128] /* AOT/HB 24/05/2000 - CodeGuard */
329= {
330zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
331zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
332zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
333zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
334zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
335zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
336zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
337zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
338
339zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
340zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
341zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
342zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
343zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
344zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
345zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym,
346zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym, zzzsym
347}
348;
349static int source_index=0;       /* index of the source string */
350static int last_source_index=0;
351LONGX fmt_error=0;
352#if ERRORET
353LONGX fmt_errof=0;
354#endif
355#define length_word_buff 256+50+50+50
356static char  *word_names[zzzsym+9];
357static int next_word_buff;
358static char word_buff[length_word_buff];
359static l_code   *head_code ;    /* points to the beginning of the intermediate
360                            code. Used only as the linked list head
361                         */
362static l_code   *last_instr;   /* points to the last instruction generate */
363static l_code   *p_nulo=nulo;                                   /* AOT 06/04/92 */
364static LONGX field_address;
365static LONGX address;
366static label next_label;    /* stores the last generated label */
367static int formatting;       /* if true , the heading commands for formatting
368                         a field have already been generated */
369static l_code  actual_inst;  /* To be used to store a temporary instruction */
370/*char *inst_cnv[100]; */ /* to convert instr_codes from enumerate to string*/
371#if PRINT_CODE
372 char *inst_cnv[zzzzzz+10];  /*repf*/
373                        /* to convert instr_codes from enumerate to string*/
374#endif
375 static int  repeatable;       /* =true means we are processing repeatable
376format */
377static int n_instructions;   /* keep the number of instructions generated */
378/* endereco n_fields; */
379
380/* static int function_in_process; */
381/* static int if_expr_in_process; */
382/* static int first_function_in_expression; */
383#endif /* CICPP */
384/*repf*/
385#define  is_not_rep     0       /* Nao esta processando grupo repetitivo  */
386#define  is_rep         1       /* Processando grupo repetitivo           */
387#define  is_ref         2       /* Processando funco ref                  */
388#if !CICPP
389typedef struct repeat_groups{
390    int repeatable;
391    int last_format;
392}REPEAT_GROUPS;
393static  REPEAT_GROUPS  vet_repeat[MAX_NESTED_REPEAT];
394static  int     top_repeat=0;
395/* static  int n_ref=0; */ /*  qtade de refs aninhados - not used */
396static  int last_format=is_not_rep;
397/*---------- break------------------------------------------------------*/
398#define MAX_STACK_BREAKS 100   /* Numero maximo de breaks permitido */
399static l_code *stack_breaks[MAX_STACK_BREAKS];
400static int top_stack_breaks ;
401#endif /* CICPP */
402/*A05*/
403/*-----------------------------------------------------------------------*/
404/* Variaveis para resolver problema de IFs em @files                      */
405/*-------- --------------------------------------------------------------*/
406/* Deve ser dinamico */
407#define MAX_buff_look_ahead 160
408#if !CICPP
409int pf_look_ahead= -1;
410int pi_look_ahead=0;
411char *buff_look_ahead=NULL;
412int LOOKING_AHEAD=0;
413#endif /* CICPP */
414/*-----------------------------------------------------------------------*/
415/* Prototype */
416/*-------- --------------------------------------------------------------*/
417#if !CICPP
418#if ANSI
419void fmt_finaliza_fmt(int pt_break);
420char  *store_inst_names(char *str);
421void  ignora_espacejamento (void);
422void parse_fmtfile(void);
423int parse_microisis_dbname(void);
424int  parse_date(void);
425static int cabe_proximo_digito(int x);
426static symbol  analisa_numero(char pstr_num[]);
427static symbol  analisa_short_int(char pstr_num[]);
428static int     analisa_mfn(void);
429#else
430void fmt_finaliza_fmt();
431char  *store_inst_names();
432void  ignora_espacejamento();
433void parse_fmtfile();
434int parse_microisis_dbname();
435int pase_date();
436static int cabe_proximo_digito();
437static symbol  analisa_numero();
438static symbol  analisa_short_int();
439static int     analisa_mfn();
440#endif
441#endif /* CICPP */
442
443/*--------------------------------------------------------------------------*/
444/*                   cabe_proximo_digito                                   */
445/*--------------------------------------------------------------------------*/
446/* Verifica se o numero que esta sendo separado do formato de entrada
447   tem tamanho dentro do definido
448*/
449#if CICPP
450int FMTSTRU :: cabe_proximo_digito(int x)
451#else /* CICPP */
452#if ANSI
453static int cabe_proximo_digito(int x)
454#else /*ANSI*/
455static int cabe_proximo_digito(x)
456int x;
457#endif /*ANSI*/
458#endif /* CICPP */
459{
460 if (x > number_length) erro(6000);
461 return x;
462}
463/*--------------------------------------------------------------------------*/
464/*                   analisa_numero                                         */
465/*--------------------------------------------------------------------------*/
466#if CICPP
467FMTSTRU :: symbol  FMTSTRU :: analisa_short_int(char pstr_num[])
468#else /* CICPP */
469#if ANSI
470static symbol  analisa_short_int(char pstr_num[])
471#else /*ANSI*/
472static symbol  analisa_short_int(pstr_num)
473char pstr_num[];
474#endif /*ANSI*/
475#endif /* CICPP */
476{
477  symbol symb;
478  char keep_ch;
479  int keep_source_index;
480  int nn;
481  keep_ch=ch;
482  keep_source_index=source_index;
483  nn=0;
484  symb=(enum symbol_names)dummy;
485  while (isdigit(ch)){
486    symb=number;
487    pstr_num[cabe_proximo_digito(nn)]=ch;
488    nn++;
489    get_ch();
490  }
491  pstr_num[cabe_proximo_digito(nn)]='\0';
492  if (symb==dummy) { /* restaura Contexto*/
493      ch=keep_ch;
494      source_index=keep_source_index;
495  }else{
496      long_num=atol(pstr_num);
497      if (long_num>=(LONGX) MIN_INT && long_num<=(LONGX)MAX_INT){
498         num=(int)long_num;
499         symb=number;
500       }else erro(7000);
501   }
502  return symb;
503}
504/*--------------------------------------------------------------------------*/
505/*                   analisa_numero                                         */
506/*--------------------------------------------------------------------------*/
507#if CICPP
508FMTSTRU :: symbol  FMTSTRU :: analisa_numero(char pstr_num[])
509#else /* CICPP */
510#if ANSI
511static symbol  analisa_numero(char pstr_num[])
512#else /*ANSI*/
513static symbol  analisa_numero(pstr_num)
514char pstr_num[];
515#endif /*ANSI*/
516#endif /* CICPP */
517{
518#define TRUE 1
519#define FALSE 0
520  symbol symb;
521  int tem_num;
522  char keep_ch;
523  int keep_source_index;
524  int nn;
525  keep_ch=ch;
526  keep_source_index=source_index;
527  nn=0;
528  symb=(enum symbol_names)dummy;
529  while (isdigit(ch)){
530        symb=long_number;
531        pstr_num[cabe_proximo_digito(nn)]=ch;
532        nn++;
533        get_ch();
534  }
535  if (ch=='.') {
536      pstr_num[cabe_proximo_digito(nn)]=ch;
537      nn++;
538      symb=float_number;
539      get_ch();
540  }
541  while(isdigit(ch) ){
542      pstr_num[cabe_proximo_digito(nn)]=ch;
543      nn++;
544      get_ch();
545  }
546  if ( (ch=='E') || (ch=='e'))  { /* exponencial*/
547      pstr_num[cabe_proximo_digito(nn)]=ch;
548      nn++;
549      symb=float_number;
550      get_ch();
551      tem_num=FALSE;
552      if ((ch=='+')||(ch=='-')) {
553        pstr_num[cabe_proximo_digito(nn)]=ch;
554        nn++;
555        get_ch();
556      }
557      while (isdigit(ch))  {
558        pstr_num[cabe_proximo_digito(nn)]=ch;
559        nn++;
560        tem_num=TRUE;
561        get_ch();
562      }
563      if(tem_num==FALSE){
564       printf("\n Numero invalido");
565       exit(1);
566      }
567  } /* Exponecial*/
568    pstr_num[cabe_proximo_digito(nn)]='\0';
569    if (symb==dummy) { /* restaura Contexto*/
570      ch=keep_ch;
571      source_index=keep_source_index;
572    }else
573       /* Incialmente forca inteiro p/ser long. Depois,se for o caso,
574          transforma em int
575       */
576      if (symb ==long_number){
577         long_num=atol(pstr_num);
578         if (long_num>=(LONGX) MIN_INT && long_num<=(LONGX)MAX_INT){
579            num=(int)long_num;
580            symb=number;
581         }
582       }
583  return symb;
584}
585/*repf*/
586/*--------------------------------------------------------------------------*/
587/* fmt_pop_breaks                                                           */
588/*--------------------------------------------------------------------------*/
589#if CICPP
590 label FMTSTRU :: fmt_pop_breaks(int pt_stack_breaks)
591#else /* CICPP */
592#if ANSI
593 label fmt_pop_breaks(int pt_stack_breaks)
594#else /* ANSI */
595 label fmt_pop_breaks(pt_stack_breaks)
596 int pt_stack_breaks;
597#endif /* ANSI */
598#endif /* CICPP */
599 { label lab;
600   l_code *idx;
601   lab= -1;
602   if (pt_stack_breaks<=top_stack_breaks){
603     lab=gen_next_label();
604     for (;pt_stack_breaks<=top_stack_breaks;top_stack_breaks--) {
605      idx = stack_breaks[top_stack_breaks];
606      /* altera o desvio da  instrucao que foi deixada para tras */
607      idx->info.add=lab;
608     }
609   }
610  return lab;
611 }
612
613/*--------------------------------------------------------------------------*/
614/* fmt_push_breaks                                                            */
615/*--------------------------------------------------------------------------*/
616#if CICPP
617 void FMTSTRU :: fmt_push_breaks(l_code *idx)
618#else /* CICPP */
619#if ANSI
620 void  fmt_push_breaks(l_code *idx)
621#else /* ANSI */
622 void  fmt_push_breaks(idx)
623 l_code *idx;
624#endif /* ANSI */
625#endif /* CICPP */
626 {
627   if (top_stack_breaks>=MAX_STACK_BREAKS-1){
628     erro(333);
629   }
630   top_stack_breaks++;
631   stack_breaks[top_stack_breaks]=idx;
632 }
633
634/*--------------------------------------------------------------------------*/
635/* fmt_pop_repeat                                                           */
636/*--------------------------------------------------------------------------*/
637#if CICPP
638void FMTSTRU :: fmt_pop_repeat (void)
639#else /* CICPP */
640void fmt_pop_repeat ()
641#endif /* CICPP */
642{
643if (top_repeat <= 0) {
644   fatal("\n Underflow - vetrepeat ");
645  }
646  repeatable=vet_repeat[top_repeat].repeatable;
647  last_format=vet_repeat[top_repeat].last_format;
648  top_repeat--;
649}
650/*--------------------------------------------------------------------------*/
651/* fmt_push_repeat                                                          */
652/*--------------------------------------------------------------------------*/
653#if CICPP
654void FMTSTRU :: fmt_push_repeat (void)
655#else /* CICPP */
656void fmt_push_repeat ()
657#endif /* CICPP */
658{
659if (top_repeat >= MAX_NESTED_REPEAT) {
660   fatal("\n Overflow - vetrepeat ");
661  }
662 top_repeat++;
663 vet_repeat[top_repeat].repeatable=repeatable;
664 vet_repeat[top_repeat].last_format=last_format;
665}
666/*--------------------------------------------------------------------------*/
667/* store_res_word                                                           */
668/*--------------------------------------------------------------------------*/
669#if CICPP
670char  * FMTSTRU :: store_res_word(char *str)
671#else /* CICPP */
672#if ANSI
673char  *store_res_word(char *str)
674#else /* ANSI */
675char  *store_res_word(str)
676char *str;
677#endif /* ANSI */
678#endif /* CICPP */
679{
680  char *temp;
681  int len;
682  len=strlen(str);
683  if (next_word_buff +len >= length_word_buff )
684      fatal("No room to store word_definitions/length_word_buff");
685  temp = &word_buff[next_word_buff];
686  strcpy(temp,str);
687  next_word_buff=next_word_buff + len +1;
688  return temp;
689}
690/*--------------------------------------------------------------------------*/
691/* store_inst_names                                                         */
692/*--------------------------------------------------------------------------*/
693#if PRINT_CODE
694#if !CICPP
695#define inst_name_size 5000
696 static char inst_name[inst_name_size];
697 static int inst_next;
698#endif /* CICPP */
699
700#if CICPP
701char  * FMTSTRU :: store_inst_names(char *str)
702#else /* CICPP */
703#if ANSI
704char  *store_inst_names(char *str)
705#else /* ANSI */
706char  *store_inst_names(str)
707char *str;
708#endif /* ANSI */
709#endif /* CICPP */
710{
711  char *temp;
712  int len;
713  len=strlen(str);
714  if (inst_next + len +1 >= inst_name_size )
715      fatal("No room to store inst_names/inst_name_size");
716  temp = &inst_name[inst_next];
717  strcpy(temp,str);
718  inst_next=inst_next + len +1;
719  return temp;
720}
721#endif /*PRINT_CODE*/
722/*--------------------------------------------------------------------------*/
723/*                   get_ch                                                 */
724/*--------------------------------------------------------------------------*/
725/* Ler o proximo caracter da entrada ou de arquivo
726   1-Se a entrada for de arquivo utilizando @file podemos ter 2 casos:
727     a) Se no formato apareceu um IF, varios caracteres podem ter sido
728        lidos a frente para determinar o tipo de expressao sem, na verdade,
729        terem sido consumidos. Neste caso eles estao armazenados no
730        buff_look_ahead.
731    b) Enquanto nao decide qual tipo de expressao do IF devera ser considerada
732       os caracters sao armazenados em buff_look_ahead
733    c) LOOKING_AHEAD = 1 . Esta sendo analizada uma expressa em IF e o
734       os caracteres devem ser armazenados buf_look_ahead
735       LOOKING_AHEAD = 0 . Nao esta sendo analizada nenhuma expressao
736  2-Se nao tem referencia a arquivo, pega o proximo caracter do string
737*/
738
739#if CICPP
740void FMTSTRU :: get_ch (void)
741#else /* CICPP */
742void get_ch ()
743#endif /* CICPP */
744{
745 /*A05*/
746    /* Se tem arquivo aberto , Le entrada de arquivo */
747  if (pi_look_ahead<=pf_look_ahead  && LOOKING_AHEAD!=1) {
748        ch=buff_look_ahead[pi_look_ahead];
749        pi_look_ahead++;
750  }else {
751    if (!(nopn_fmtfiles > -1)){ /* le do fmt de entrada */
752       ch = pfmt[source_index];
753       if (ch != null_char )source_index++;
754    }else { /*le de arquivo */
755       if (CIREAD(CUR_FMT_FILE,&ch,sizeof(ch)) <= 0) {
756          CLOSE(CUR_FMT_FILE);
757          CUR_FMT_FILE= -1;
758          nopn_fmtfiles--;
759          ch=0x1A;
760       };
761   }
762 }
763
764  if (ch == 0x1A) {     /* 13-12-96, 22-01-97 - Control Z */
765      ch=' ';    /* Troquei pra espaco  26-05-97*/
766     /* sym=comma;  tirei porque nao funcionava quando terminava em
767                    incondicional. A rotina str-read separava o string
768                    e  voltava na getsymbol  com symbolo de coma.
769                     26-05-97 */
770  }
771            /* Se estiver analizando expressoes booleanas guarda
772                 o formato */
773
774  if (LOOKING_AHEAD){
775     if (pf_look_ahead<MAX_buff_look_ahead) {
776        pf_look_ahead++;
777        buff_look_ahead[pf_look_ahead]=ch;
778     }else  fatal("If expression too long/cifm1/LOOKING_AHEAD" );
779  }
780} /* get_ch */
781/*--------------------------------------------------------------------------*/
782/*                   erro                                                   */
783/*--------------------------------------------------------------------------*/
784#if CICPP
785void FMTSTRU :: erro (int nerr)
786#else /* CICPP */
787#if ANSI
788void erro (int nerr)
789#else /* ANSI */
790void erro (nerr)
791int nerr;
792#endif /* ANSI */
793#endif /* CICPP */
794{
795/* AOT 02/01/91 */
796#if !ERRORET
797char *p;
798#endif
799/* AOT 07/01/91 */
800/* fatal("Not enough memory for formatting"); */
801/* AOT 02/01/91 */
802#if ERRORET
803if (!fmt_error) {
804    fmt_error=nerr;
805    fmt_errof=last_source_index-1;
806}
807#else
808p=s+last_source_index-1;
809fprintf(stderr,"%.78s\n^^ %d",p,nerr);
810fatal("format error");
811#endif
812} /* erro */
813/*--------------------------------------------------------------------------*/
814/*                   parse_fmtfile                                     */
815/*--------------------------------------------------------------------------*/
816#if CICPP
817void FMTSTRU :: parse_fmtfile(void)
818#else /* CICPP */
819void parse_fmtfile()
820#endif /* CICPP */
821{ int i;
822  int xx;
823  i=0;
824  get_ch();
825  while ( (ch!=virgula) && (ch!=space_char) && (ch!=null_char) &&
826          (ch!=tab) && (ch!=lf) && (ch!=cr)     ) {
827   fmtfile[i++]=ch;
828   get_ch();
829   if (i >= MAXPATH) erro(12300);                       /* AOT 28/12/94 */
830  }
831  fmtfile[i]=null_char;
832#if DEB_ATFILE
833  printf("\Selecionou file=%s",fmtfile);
834#endif
835  if (i==0) erro(12301);                                /* AOT 28/12/94 */
836#if APPENDEXTENSION                                     /* AOT 28/12/94 */
837  if (strstr(fmtfile,".")==NULL)strcat(fmtfile,".pft");
838#endif
839#if DEB_ATFILE
840  printf("\Nome do arquivo Selecionado=%s",fmtfile);
841#endif
842  /* abre o arquivo e guarda na pilha */
843  nopn_fmtfiles++;
844  if (nopn_fmtfiles >  MXOPNFMTFILES -1 ) erro(12302);  /* AOT 28/12/94 */
845  dbxopt_fatal=0; xx=dbxopen(NULL,fmtfile,NULL);        /* AOT 13/12/96 */
846  if (xx < 0) erro(12303);                              /* AOT 28/12/94 */
847  opn_fmtfiles[nopn_fmtfiles]=xx;
848}
849/*--------------------------------------------------------------------------*/
850/*                   str_read                                               */
851/*--------------------------------------------------------------------------*/
852#if CICPP
853void FMTSTRU :: str_read (char end_ch)
854#else /* CICPP */
855#if ANSI
856void str_read (char end_ch)
857#else /* ANSI */
858void str_read (end_ch)
859char end_ch;
860#endif /* ANSI */
861#endif /* CICPP */
862{
863  int i = 0;
864  char *tmp;
865  get_ch ();
866  while ((i<string_length) && ((ch != end_ch) && (ch != 0)) )
867  { str[i]=ch;
868    i++;
869    get_ch ();
870    if (i==string_length) {
871      str[string_length]=null_char;
872      string_length=string_length+(INCR_LITER) ;
873#if CICPP
874     /*-
875      nao sei qual o comando para realocar em c++ -*/
876     try
877      { tmp=(char *) new char [string_length+1]; }
878        catch (BAD_ALLOC)
879        { tmp=(char *) NULL; string_length= 0; /* HB - string_length e' unsigned e nao pode ser -1 */
880              fatal("cifm1/str_read/realloc");
881             /* Nao deixa alocar nada */ }
882        strcpy(tmp,str);
883        delete [] (char *)str;
884        str=tmp;
885#else /* CICPP */
886 /*      str=(char *) REALLOC (str,(ALLOPARM) sizeof(char)*(string_length+1));*/
887         tmp=(char *) ALLOC( (ALLOPARM) sizeof(char)*(string_length+1));
888
889         if (tmp != NULL) {
890             strcpy(tmp,str);
891             FREE(str);
892             str=tmp;
893           }else fatal("cifm1/str_read/realloc");
894#endif /* CICPP */
895   }
896  }
897
898  str[i] = null_char;
899  if ((ch !=null_char) && (ch != end_ch))
900   {while ((ch != end_ch) && (ch !=null_char)) get_ch ();
901    if (ch == null_char) erro (1);
902   }
903  get_ch ();
904 } /* str_read */
905/*--------------------------------------------------------------------------*/
906#if CICPP
907void   FMTSTRU :: ignora_espacejamento(void)
908#else /* CICPP */
909void   ignora_espacejamento()
910#endif /* CICPP */
911{
912  while ( ch==space_char || ch==lf || ch==tab || ch==cr )
913         get_ch();
914}
915 /*A01*/
916/*--------------------------------------------------------------------------*/
917/*                   getsymbol                                              */
918/*--------------------------------------------------------------------------*/
919#if CICPP
920void FMTSTRU :: getsymbol (void)
921#else /* CICPP */
922void getsymbol ()
923#endif /* CICPP */
924{
925 int ih;                     /* nowrn (int) - AOT, 22/01/2006 */
926 int k;
927 symbol ks;
928 sym = (enum symbol_names)0;
929 num = 0;
930 str[0] = null_char;
931 fmttoken[0] = null_char;
932 /*A01*/
933  ignora_espacejamento();
934 /*A01*/
935 last_source_index=source_index;
936
937#if BEFORE990429
938#else
939/* Tem dois erros: 1) ssym deveria ter 256 elementos
940                   2) memset(ssym,zzzsym,128*sizeof(symbol));
941   AOT/HB
942*/
943 ih=(int)ch;                  /* nowrn (int) - AOT, 22/01/2006 */
944 if (ih < 0 || ih > 127)   {  /* nowrn (int) - AOT, 22/01/2006 */   /*if (ch < 0 || ch > 127) */
945     erro (3);
946     get_ch ();
947     return;
948 }
949#endif
950
951 /*A05*/
952 while (ssym[ch] == slash) {
953    int achou;
954    sym=ssym[ch];
955    get_ch();
956    if (ssym[ch] != times)  return;
957    achou=false;
958    /* ignora comentario */
959    for (;!achou && ch != null_char ;){
960           get_ch();
961           if (ssym[ch] == times){
962              get_ch();
963              if (ssym[ch]==slash){
964                achou=true;
965                get_ch();
966                ignora_espacejamento();
967              }
968           }
969    }/*for*/
970    if (!achou) fatal("cifm1/end_comment");
971 }
972
973 if (ssym[ch] == doispontos) {
974  sym=doispontos;
975  get_ch(); /* Verifica o proximo char par a verif atribuicao */
976  if (ssym[ch] == eql){
977            get_ch(); /*  elimina proximo char */
978            sym = attribsym ;
979  }
980  return;
981 }
982 /*A12  */
983 if (separa_nome_base == 1) {
984   k=0;
985   while (isalnum(ch)) {
986     if (k < number_length) float_num_str[k++]=ch;
987     get_ch();
988   }
989   float_num_str[k]=null_char;
990   if (k>0)sym=textsym;
991   return;
992 }
993
994
995 if (ch == atsign){
996#if DEB_ATFILE
997   printf("\n ASchou @");
998#endif
999   parse_fmtfile();
1000   ch=','; /* 31-10-96 */
1001   /* get_ch(); */ /*temporario */
1002 }
1003
1004 if (isalpha (ch))
1005  { k = 0;
1006    while ( (k < res_words_length) && isalpha (ch))  /*vvv*/
1007     { fmttoken[k] = toupper (ch);
1008       k++;
1009       get_ch ();
1010     } /* while */
1011    fmttoken[k] = null_char;
1012
1013   /* Vefifica se 'e expressao */
1014    if ( (k==1) && (fmttoken[0]=='E' || fmttoken[0]=='S')) {
1015        /* supoe que 'e variavel */
1016        sym = intvarsym;
1017        if (fmttoken[0] == 'S') sym = strvarsym;
1018        /* verifica se realmente 'e variavel */
1019        if (isdigit(ch)){
1020           /* e' variavel. pega indice */
1021           indvar =  (int) ch - (int) '0' ;
1022           get_ch();
1023           return;
1024        }
1025    }
1026
1027#if RPIVA
1028#if BEFORE981231
1029    for (ks = firstsym+1; ks < zzzsym; ks++)
1030#else
1031    for (ks = (enum symbol_names)(firstsym+1); ks < zzzsym; ks = (enum symbol_names)((int)ks+1))
1032#endif /* BEFORE981231 */
1033        {
1034        if (word_names[ks])
1035            if (strcmp(fmttoken,word_names[ks]) == 0) break;
1036        }
1037    if (ks < zzzsym) sym = ks;
1038        else erro (2);
1039#else
1040    ks = firstsym+1;
1041    while (( ks < zzzsym ) && ( strcmp (fmttoken, word_names[ks])) )
1042        ks++;
1043    if (! strcmp(fmttoken,word_names[ks])) sym = ks;
1044     else erro (2);
1045#endif
1046    return;
1047   }
1048     /* if isalpha (ch) */
1049     /* tenta separar um numero. Se nao conseguir ,o apontador para
1050         string sendo analisada nao e' modificado
1051      */
1052    /* Dependendo do numero procurado, chama rotina para separar
1053       int ou long/float
1054    */
1055 if (classe_numero_procurado==PARSEINTNUMB)
1056    sym=analisa_short_int(float_num_str);
1057  else
1058    sym=analisa_numero(float_num_str);
1059 if (sym==number || sym==long_number || sym==float_number){
1060  return;
1061 }
1062/*f01*/
1063 if (( ch == apostrofo) || ( ch == crase) ){
1064   sym = u_litsym;
1065   str_read (ch);
1066 } /* if ch = aspa or ch = crase */
1067  else
1068    if ( ch == aspa ){
1069      sym = c_litsym;
1070      str_read (ch);
1071    } else
1072       if (ch == exclamacao){
1073         sym = esc_strsym;
1074         get_ch();
1075         str_read (ch);
1076       }else
1077         if (ch == less_char){
1078            get_ch ();
1079            if (ch == equal_char){
1080               sym = leq;
1081               get_ch ();
1082            } else
1083               if (ch == greater_char){
1084                 sym = neq;
1085                 get_ch ();
1086                }else sym = lss;
1087         }else
1088           if (ch == greater_char){
1089              get_ch ();
1090              if (ch == equal_char){
1091                 sym = geq;
1092                 get_ch ();
1093              } else sym = gtr;
1094           } else
1095              if (ch == null_char)
1096                sym = nullsym;
1097                else
1098                 if (ch == '|'){
1099                   sym = r_litsym;
1100                   str_read(ch);
1101                  } else
1102                     if (ch== SFLDCHR){
1103                        get_ch ();
1104                        sym = s_fieldsym;
1105                        sub_field_value = ch;
1106                        get_ch ();
1107                     }else {
1108                       sym = ssym[ch];
1109#if RPIVA
1110                       if (sym==zzzsym) erro (3);
1111#else
1112                       if (sym==1000) erro (3);
1113#endif
1114                         get_ch ();
1115                     }
1116} /* getsymbol */
1117/*--------------------------------------------------------------------------*/
1118/*                   initialize                                             */
1119/*--------------------------------------------------------------------------*/
1120#if CICPP
1121void FMTSTRU :: initialize (void)
1122#else /* CICPP */
1123void initialize ()
1124#endif /* CICPP */
1125{
1126symbol  k ;
1127source_index = 0;
1128last_source_index=0;
1129#if BEFORE981231
1130for (k=firstsym;k<=zzzsym;k++)word_names[k]=nulo;
1131#else
1132for (k=firstsym;k<=zzzsym;k=(enum symbol_names)((int)k+1))word_names[k]=nulo;
1133#endif /* BEFORE981231 */
1134ch = space_char;
1135/*A05*/
1136#if CICPP
1137  try
1138  { buff_look_ahead=(char *) new char [MAX_buff_look_ahead]; }
1139  catch (BAD_ALLOC)
1140  { buff_look_ahead=(char *) NULL; }
1141#else /* CICPP */
1142  buff_look_ahead=(char *) ALLOC((ALLOPARM)MAX_buff_look_ahead);
1143#endif /* CICPP */
1144
1145/* A06 - Alocar area de analise de strings */
1146#if CICPP
1147  /*-
1148    verificar se esta correto -*/
1149  try
1150  { str=(char *) new char [string_length+1]; }
1151  catch (BAD_ALLOC)
1152  {
1153    str=(char *) NULL; string_length= 0; /* Nao deixa alocar nada */ /* HB - string_length e' unsigned e nao pode ser -1 */
1154    fatal("cifm1/initialize/realloc");
1155  }
1156#else /* CICPP */
1157/*Conferir... */
1158  str=(char *) ALLOC((ALLOPARM)(sizeof(char)*(string_length+1)));
1159#endif /* CICPP */
1160
1161word_names[csym] =store_res_word("C");
1162word_names[xsym] =store_res_word("X");
1163word_names[dsym] =store_res_word("D");
1164word_names[nsym] =store_res_word("N");
1165word_names[vsym] =store_res_word("V");
1166word_names[ifsym]=store_res_word("IF");
1167word_names[fisym]=store_res_word("FI");
1168word_names[thensym]=store_res_word("THEN");
1169word_names[elsesym]=store_res_word("ELSE");
1170word_names[orsym]=store_res_word("OR");
1171word_names[andsym]=store_res_word("AND");
1172word_names[notsym]=store_res_word("NOT");
1173word_names[mfnsym]=store_res_word("MFN");
1174word_names[coresym]=store_res_word("CORE");
1175word_names[maxmfnsym]=store_res_word("MAXMFN");
1176word_names[datemktimesym]=store_res_word("SECONDS");
1177word_names[mplsym]=store_res_word("MPL");
1178word_names[mpusym]=store_res_word("MPU");
1179word_names[mhlsym]=store_res_word("MHL");
1180word_names[mhusym]=store_res_word("MHU");
1181word_names[mdlsym]=store_res_word("MDL");
1182word_names[mdusym]=store_res_word("MDU");
1183word_names[fsym]=store_res_word("F");
1184word_names[s_sym]=store_res_word("S");
1185word_names[getenv_sym]=store_res_word("GETENV");
1186word_names[putenv_sym]=store_res_word("PUTENV");
1187word_names[refsym]=store_res_word("REF");
1188word_names[asym]=store_res_word("A");
1189word_names[psym]=store_res_word("P");
1190word_names[instrsym]=store_res_word("INSTR");
1191word_names[leftsym]=store_res_word("LEFT");
1192word_names[datexsym]=store_res_word("DATEX");
1193word_names[rightsym]=store_res_word("RIGHT");
1194word_names[replacsym]=store_res_word("REPLACE");
1195#if CI_XMLELEM
1196word_names[xmlelemsym]=store_res_word("XMLELEM");
1197#endif
1198word_names[midsym]=store_res_word("MID");
1199word_names[rupxsym]=store_res_word("PROCX");
1200word_names[rupdsym]=store_res_word("PROC");
1201word_names[systsym]=store_res_word("SYSTEM");
1202word_names[rsumsym]=store_res_word("RSUM");
1203word_names[rminsym]=store_res_word("RMIN");
1204word_names[rmaxsym]=store_res_word("RMAX");
1205word_names[ravrsym]=store_res_word("RAVR");
1206word_names[valsym]=store_res_word("VAL");
1207word_names[lsym]=store_res_word("L");
1208word_names[fmtsym]=store_res_word("FMT");
1209word_names[usym]=store_res_word("U");
1210word_names[isym]=store_res_word("I");
1211word_names[lwsym]=store_res_word("LW");
1212word_names[noccsym]=store_res_word("NOCC");
1213word_names[ioccsym]=store_res_word("IOCC");
1214word_names[continuesym]=store_res_word("CONTINUE");
1215word_names[breaksym]=store_res_word("BREAK");
1216word_names[sizesym]=store_res_word("SIZE");
1217word_names[typesym]=store_res_word("TYPE");
1218word_names[catsym]=store_res_word("CAT");
1219word_names[nl_sym]=store_res_word("NEWLINE");
1220word_names[mstsym]=store_res_word("MSTNAME");
1221word_names[datesym]=store_res_word("DATE");
1222word_names[date1sym]=store_res_word("DATETIME");    /*28-12-94*/
1223word_names[date2sym]=store_res_word("DATEONLY");    /*28-12-94*/
1224word_names[lastsym]=store_res_word("LAST");
1225word_names[npsym]=store_res_word("NPOST");    /*21-07-94*/
1226word_names[np2sym]=store_res_word("NPST");
1227word_names[selsym]=store_res_word("SELECT");
1228/* ---> mesmo que select word_names[selsym]=store_res_word("SWITCH"); */
1229word_names[casesym]=store_res_word("CASE");
1230word_names[elsecasym]=store_res_word("ELSECASE");
1231word_names[endselsym]=store_res_word("ENDSEL");
1232word_names[whilesym]=store_res_word("WHILE");
1233word_names[occsym]=store_res_word("OCC");
1234word_names[dbsym]=store_res_word("DB"); /*A09*/
1235word_names[ss_sym]=store_res_word("SS"); /*A10*/
1236word_names[citypesym]=store_res_word("CITYPE");
1237
1238/* ---> mesmo que endsel word_names[endselsym]=store_res_word("ENDSW"); */
1239
1240#if DEB_ATFILE
1241for (k=firstsym;k<=zzzsym;k++){
1242 printf("\n word_names[%d]=%s",k,word_names[k]);
1243}
1244#endif
1245#if RPIVA
1246/*memset(ssym,zzzsym,128*sizeof(symbol)); AOT/HB - 29/04/99 */
1247#if BEFORE20000524
1248for (k=(enum symbol_names)0;k<=(enum symbol_names)127;k=(enum symbol_names)(k + 1)) ssym[k]=zzzsym;
1249#else
1250/* initializado na declara�, no bra�*/
1251#endif
1252#else
1253for (k=0;k<=127;k++) ssym[k]=1000;
1254#endif
1255ssym[','] = comma;                     ssym['/'] = slash;
1256ssym['_'] = number_sigx;
1257ssym['#'] = number_sign;               ssym['%'] = percent;
1258ssym['('] = lparen;                    ssym[')'] = rparen;
1259ssym['^'] = flecha;                    ssym['*'] = times;
1260ssym['+'] = plus;                      ssym[':'] = doispontos;
1261ssym['='] = eql;                       ssym[' '] = space;
1262ssym['-'] = minus;                     ssym['.'] = ponto;
1263ssym['['] = abrcolch;                  ssym[']'] = fchcolch;
1264ssym['@'] = (enum symbol_names)atsign;
1265/* aloca cabeca de lista e inicializa pointer para ultima instrucao */
1266head_code=alloc_pgm_node ();
1267head_code->next=(LONGX )p_nulo;
1268head_code->info.lab=0;
1269head_code->info.instr=dummy;
1270head_code->info.add=0;
1271head_code->m_add=0L;
1272last_instr=head_code;
1273get_ch ();
1274} /* initialize */
1275
1276/* ----------------------------- cifm1h.c --------------------------- */
1277/* Esta sendo usado o  simbolo *repf* para identificar as alteracoes
1278   efetuadas para permitir que possa ser usado um grupo repetitivo
1279   dentro de um ref que aparece em grupo repetitivo
1280   15/06/92
1281*/
1282#define REF_NEW_CONCEPT 0
1283/*AOT prototypes -------------------------------------------------------*/
1284#if !CICPP
1285#if ANSI
1286void fmt_push_breaks(l_code *idx);
1287label fmt_pop_breaks(int pt_stack_breaks);
1288int  parse_datex_function(void);
1289int  parse_f_function(void);
1290int parse_look_np_function(instruction_code first_instr,
1291                           instruction_code last_instr);
1292int  parse_ref_function(instruction_code beg_inst,
1293                        instruction_code end_inst);
1294int  parse_instr_function(instruction_code beg_inst,
1295                        instruction_code end_inst);
1296int  math_factor_function(instruction_code first_instr,
1297                          instruction_code last_instr);
1298void  field_indent(int *ind1,int *ind2);
1299void field_substr (int *off,int *len);
1300static int parse_int_number(void);
1301int field_tag(void);
1302int subfield_id(char *sbf);
1303int field_occs(int *f,int *l);
1304void generate_end_function1(void);
1305l_code *fmtel800(label *lb0,label *lb1);
1306void  fmtel805(l_code *idx,label lab);
1307void  fmtel810(int repeatable,label lab0,label lab1);
1308int verifica_ref_dbname(int cisis_sintaxe);
1309int parse_ss(void);
1310int parse_left_right_mid(instruction_code begin,instruction_code end);
1311int parse_replace(instruction_code begin,instruction_code end);
1312#if CI_XMLELEM
1313int parse_xmlelem(instruction_code begin,instruction_code end);
1314#endif
1315int function_code_generator(instruction_code begin,instruction_code end);
1316int c_fmt (void);
1317int c_fmt_separator(void);
1318int factor (void);
1319int field_fmt (void);
1320int fmt_elem (void);
1321int mode_parameter (void);
1322int num_expr (void);
1323int r_prelit (void);
1324int separator (void);
1325int spacing_string (void);
1326static int string_expr (void);
1327int termo(void);
1328label gen_next_label(void);
1329void boolean_expr (void);
1330void boolean_factor (void);
1331void boolean_term (void);
1332void field (void);
1333void get_ignore_space (void);
1334void isis_fmt (void);
1335static void relation (void);
1336void rep_isis_fmt (void);
1337void semantic_initialize(void);
1338void suffix (void);
1339#else
1340void fmt_push_breaks();
1341label fmt_pop_breaks();
1342int  parse_datex_function();
1343int  parse_f_function();
1344int  parse_ref_function();
1345int parse_look_np_function();
1346int  parse_instr_function();
1347int  math_factor_function();
1348void  field_indent();
1349void field_substr ();
1350static int parse_int_number();
1351int field_tag();
1352int subfield_id();
1353int field_occs();
1354void generate_end_function1();
1355void  fmtel805();
1356l_code *fmtel800();
1357void  fmtel810();
1358int verifica_ref_dbname();
1359int parse_ss();
1360int parse_left_right_mid();
1361int parse_replace();
1362#if CI_XMLELEM
1363int parse_xmlelem();
1364#endif
1365int function_code_generator();
1366int c_fmt ();
1367int c_fmt_separator();
1368int factor ();
1369int field_fmt ();
1370int fmt_elem ();
1371int mode_parameter ();
1372int num_expr ();
1373int r_prelit ();
1374int separator ();
1375int spacing_string ();
1376static int string_expr ();
1377int termo();
1378label gen_next_label();
1379void boolean_expr ();
1380void boolean_factor ();
1381void boolean_term ();
1382void field ();
1383void get_ignore_space ();
1384void isis_fmt ();
1385static void relation ();
1386void rep_isis_fmt ();
1387void semantic_initialize();
1388void suffix ();
1389#endif
1390#endif /* CICPP */
1391/*AOT ------------------------------------------------------------------*/
1392#if !CICPP
1393int first_time=1;
1394#endif /* CICPP */
1395/* -----------------------------------------------------------------------*/
1396/*                         parse_int_number                               */
1397/*------------------------------------------------------------------------*/
1398#if CICPP
1399int FMTSTRU :: parse_int_number(void)
1400#else /* CICPP */
1401static int parse_int_number()
1402#endif /* CICPP */
1403{int valor;
1404 classe_numero_procurado=PARSEINTNUMB;
1405 getsymbol();
1406 if(sym != number) erro(8);
1407 valor=num;
1408 getsymbol();
1409 classe_numero_procurado= -PARSEINTNUMB;/* Cuidado com ordem! */
1410 return valor;
1411}
1412/*--------------------------------------------------------------------------*/
1413/*                   parse_date                                             */
1414/*--------------------------------------------------------------------------*/
1415#if CICPP
1416int FMTSTRU :: parse_date(void)
1417#else /* CICPP */
1418int parse_date(void)
1419#endif /* CICPP */
1420{ int dateparm,find;
1421  dateparm=DATEFUNC; /* default */
1422  get_ignore_space();
1423  if (sym == lparen) {
1424    get_ignore_space();
1425    switch(sym) {
1426     case date1sym:
1427          dateparm=DATETIME;
1428          break;
1429     case date2sym:
1430          dateparm=DATEONLY;
1431          break;
1432     case number:
1433          dateparm= num;
1434          break;
1435     default :
1436          erro(1234);
1437     }
1438     get_ignore_space();
1439     if (sym != rparen) erro(1234);
1440     get_ignore_space();
1441  }
1442  find = gen(-1,load_date,dateparm,p_nulo);
1443  return(find);
1444
1445}
1446
1447/* -----------------------------------------------------------------------*/
1448/*                         Analisa_MFN                                    */
1449/*------------------------------------------------------------------------*/
1450#if CICPP
1451int   FMTSTRU :: analisa_mfn (void)
1452#else /* CICPP */
1453static int   analisa_mfn ()
1454#endif /* CICPP */
1455{
1456  int indent;
1457  get_ignore_space();
1458  indent=6;
1459  if (sym == lparen){
1460        indent=parse_int_number();
1461        if (sym != rparen) erro(7);
1462        get_ignore_space();
1463  }
1464  return indent;
1465}
1466
1467/*--------------------------------------------------------------------------*/
1468/*                   parse_datex_function                                   */
1469/*--------------------------------------------------------------------------*/
1470#if CICPP
1471int FMTSTRU :: parse_datex_function(void)
1472#else /* CICPP */
1473int parse_datex_function(void)
1474#endif /* CICPP */
1475{ int find;
1476  get_ignore_space();
1477  gen(-1,datex_beg,-1,p_nulo);
1478  if (sym != lparen) erro (8021);
1479  get_ignore_space();
1480  if (!num_expr()) erro (8818);
1481
1482 get_ignore_space();
1483 find = gen(-1,datex_end,-1,p_nulo);
1484 return find;
1485}
1486/*-----------------------------------------------------------------------*/
1487/*                  parse_f_function                                     */
1488/*-----------------------------------------------------------------------*/
1489#if CICPP
1490int FMTSTRU :: parse_f_function(void)
1491#else /* CICPP */
1492int parse_f_function()
1493#endif /* CICPP */
1494{
1495   int find;
1496   find=0;
1497/*    function_in_process++; */
1498   get_ignore_space();
1499   gen(-1,f_beg,-1,p_nulo);
1500   if (sym != lparen) erro (21);
1501   get_ignore_space();
1502   if (!num_expr()) erro (818);
1503   if (sym != comma){
1504     if (sym !=rparen) erro(22);
1505     gen(-1,load_number,-1,p_nulo); /* minimum width */
1506     find=gen(-1,load_number,-1,p_nulo); /* decimal places */
1507/*      find=1; */
1508   }else{
1509     get_ignore_space();
1510     if (!num_expr())erro(118);
1511     if (sym != comma){
1512       if(sym !=rparen) erro(22);
1513       find = gen(-1,load_number,-1,p_nulo); /* decimal places */
1514/*        find=1; */
1515     }else{
1516       get_ignore_space();
1517       if (!num_expr()) erro (218);
1518         else if (sym != rparen) erro (7);
1519                else {
1520/*                find = 1;  */
1521               }
1522      }
1523   }
1524/*  function_in_process--; */
1525 get_ignore_space();
1526 find = gen(-1,f_end,-1,p_nulo);  /* Gerou corretamente */
1527/* generate_end_function1();*/
1528 return find;
1529}
1530/*-----------------------------------------------------------------------*/
1531/*                  parse_ref_function                                   */
1532/*-----------------------------------------------------------------------*/
1533#if CICPP
1534int  FMTSTRU :: parse_ref_function(instruction_code beg_inst,
1535                                    instruction_code end_inst)
1536#else /* CICPP */
1537#if ANSI
1538int  parse_ref_function(instruction_code beg_inst,instruction_code end_inst)
1539#else /* ANSI */
1540int  parse_ref_function(beg_inst,end_inst)
1541instruction_code beg_inst,end_inst;
1542#endif /* ANSI */
1543#endif /* CICPP */
1544{
1545#if REF_NEW_CONCEPT
1546  label lab0,lab1;
1547#endif
1548  LONGX fmt_existe_dbname;
1549  int find;
1550  int sintaxe_dbn;
1551  find=0;
1552/*   function_in_process++; */
1553  fmt_push_repeat();  /*repf*/
1554#if REF_NEW_CONCEPT
1555  repeatable=true;  /*repf*/
1556  last_format=is_ref; /*repf*/
1557  gen(-1,beg_init_rep,-1,p_nulo); /*repf*/
1558  lab0=gen_next_label();
1559  lab1=gen_next_label();
1560  gen(lab0,begin_rep_gr,-1,p_nulo);
1561#if !FMT_OPTIMIZE
1562  gen(-1,set_false_rep,-1,p_nulo);
1563#endif
1564#else
1565#endif
1566  gen(-1,beg_inst,-1,p_nulo);
1567  get_ignore_space();
1568  sintaxe_dbn=parse_microisis_dbname();
1569/*--------*/
1570
1571  if (sym !=lparen) erro (21);
1572    else {
1573      get_ignore_space();
1574      /*A02*/
1575      fmt_existe_dbname=verifica_ref_dbname(sintaxe_dbn);
1576      /*A02*/
1577      if (!num_expr()) erro (20);
1578        else {
1579          gen(-1,read_mfn,fmt_existe_dbname,p_nulo);/*A02*/
1580          if (sym != comma) erro (22);
1581             else {
1582              getsymbol();
1583#if REF_NEW_CONCEPT
1584              fmt_push_repeat();
1585              repeatable=false;  /*repf*/
1586              last_format=is_ref; /*repf*/
1587              gen(-1,beg_init_not_rep,-1,p_nulo);
1588#else
1589              repeatable=false;   /*repf*/
1590              last_format=is_ref; /*repf*/
1591              gen(-1,beg_init_not_rep,-1,p_nulo); /*repf*/
1592#endif
1593              isis_fmt();
1594              if (sym != rparen) erro (7);
1595                 else {
1596                   get_ignore_space();
1597                   find = 1;
1598#if REF_NEW_CONCEPT
1599                   gen(-1,end_init_not_rep,-1,p_nulo); /*repf*/
1600                   fmt_pop_repeat();
1601                   gen(-1,end_inst,-1,p_nulo);
1602                   gen(-1,test_rep,-1,p_nulo);
1603                   gen(-1,jumpt,lab0,p_nulo);
1604                   gen(lab1,end_rep_gr,-1,p_nulo); /* ninguem deve apontar
1605                                                para ele */
1606                   gen(-1,end_init_rep,-1,p_nulo);/*repf*/
1607                   fmt_pop_repeat(); /*repf*/
1608#else
1609                   gen(-1,end_init_not_rep,-1,p_nulo);/*repf*/
1610                   gen(-1,end_inst,-1,p_nulo);
1611                   fmt_pop_repeat(); /*repf*/
1612#endif
1613                }
1614            }
1615         }
1616   }
1617/*     function_in_process--; */
1618 return find;
1619}
1620/*-----------------------------------------------------------------------*/
1621/*                  fmtel800                                             */
1622/*-----------------------------------------------------------------------*/
1623#if CICPP
1624l_code * FMTSTRU :: fmtel800(label *lb0,
1625                             label *lb1)
1626#else /* CICPP */
1627#if ANSI
1628l_code *fmtel800(label *lb0,label *lb1)
1629#else /* ANSI */
1630l_code *fmtel800(lb0,lb1)
1631label *lb0;
1632label *lb1;
1633#endif /* ANSI */
1634#endif /* CICPP */
1635{ label l0,l1;
1636  l_code *idx;
1637  /* generate instructions to print and teste Vfields*/
1638  /* explicar e inicializar completamente */
1639   formatting=true;
1640   l0=gen_next_label();
1641   l1=gen_next_label();
1642   gen(l0,begin,-1,p_nulo);
1643   if(repeatable==false) gen(-1,set_false_rep,-1,p_nulo);
1644   idx=alloc_pgm_node();
1645   last_instr->next =(LONGX )idx;
1646   last_instr = alloc_pgm_node( );
1647   idx->next = (LONGX )last_instr;
1648   last_instr->next=0L;
1649   /* 12-03-99 Completa instrucao assumindo que nao aparecera field
1650               selector e sera ignorada. Caso aparece field selector
1651               as instrucoes serao alteradas
1652   */
1653 idx->info.lab= -1;
1654 idx->info.instr=ign_cond;
1655 idx->info.add= -1;
1656 last_instr->info.lab= -1;
1657 last_instr->info.instr=ign_cond;
1658 last_instr->info.add= -1;
1659
1660
1661   *lb0=l0;
1662   *lb1=l1;
1663   return idx;
1664}
1665/*-----------------------------------------------------------------------*/
1666/*             Fmtel810                                             */
1667/*-----------------------------------------------------------------------*/
1668#if CICPP
1669void  FMTSTRU :: fmtel810(int repeatable,
1670                          label lab0,
1671                          label lab1)
1672#else /* CICPP */
1673#if ANSI
1674void  fmtel810(int repeatable, label lab0,label lab1)
1675#else /* ANSI */
1676void  fmtel810(repeatable,lab0,lab1)
1677int repeatable;
1678label lab0;
1679label lab1;
1680#endif /* ANSI */
1681#endif /* CICPP */
1682{
1683/* generate instructions to print and teste Vfields*/
1684if (repeatable==false){
1685  gen(-1,test_rep,-1,p_nulo);
1686  gen(-1,jumpt,lab0,p_nulo);
1687  gen(lab1,end, -1,p_nulo);
1688 }else {
1689  gen(lab1,end,-1,p_nulo);
1690 }
1691}
1692/*-----------------------------------------------------------------------*/
1693/*                  Fmtel805                                             */
1694/*-----------------------------------------------------------------------*/
1695#if CICPP
1696void  FMTSTRU :: fmtel805(l_code *idx,
1697                          label lab)
1698#else /* CICPP */
1699#if ANSI
1700void  fmtel805(l_code *idx,label lab)
1701#else /* ANSI */
1702void  fmtel805(idx,lab)
1703l_code *idx;
1704label lab;
1705#endif /* ANSI */
1706#endif /* CICPP */
1707{
1708 switch (field_fmt_sym)
1709 { case vsym : gen(-1,print_field,field_address,p_nulo);
1710               break;
1711   case isym : gen(-1,input_fld,field_address,p_nulo);
1712                    break;
1713   case usym : gen(-1,update_fld,field_address,p_nulo);
1714                    break;
1715 }
1716/* completa instrucoes deixadas para tras */
1717gen(-1,test_occ,field_address,idx);
1718idx=(l_code *)idx->next;
1719gen(-1,jumpf,lab,idx);
1720}
1721/*-----------------------------------------------------------------------*/
1722/*            Macro verif_numeric_relational_op                          */
1723/*-----------------------------------------------------------------------*/
1724#define verif_numeric_relational_op                                      \
1725 (sym==neq || sym==lss || sym==gtr || sym==leq || sym==geq ||            \
1726  sym==eql)?true:false                                                   \
1727/*-----------------------------------------------------------------------*/
1728/*            Macro verif_string_relational_op                           */
1729/*-----------------------------------------------------------------------*/
1730#define verif_string_relational_op                                       \
1731 (sym==doispontos)?true:false                                            \
1732/*-----------------------------------------------------------------------*/
1733/*            Macro verif_numeric_string_relational_op                   */
1734/*-----------------------------------------------------------------------*/
1735#define verif_numeric_string_relational_op                               \
1736 (verif_numeric_relational_op==true) ||                                  \
1737 ( verif_string_relational_op==true)?true:false                          \
1738 /*A02 */
1739/*-------------------------------------------------------------------------*/
1740/*                   verifica_ref_dbname                                   */
1741/*-------------------------------------------------------------------------*/
1742#if CICPP
1743int FMTSTRU :: verifica_ref_dbname(int sintaxe)
1744#else /* CICPP */
1745#if ANSI
1746int verifica_ref_dbname(int sintaxe)
1747#else /*ANSI*/
1748int verifica_ref_dbname(sintaxe)
1749int sintaxe;
1750#endif /*ANSI*/
1751#endif /* CICPP */
1752{ int find;
1753  /* Pega o proximo symbol para verificar se e especificacao
1754   de dbn.
1755  */
1756  find=0;
1757  if (sintaxe == MISIS_REF_DBN) return(1); /*A12*/
1758  if (sym==abrcolch){
1759     getsymbol();
1760     gen(-1,dbname_beg,-1,p_nulo);
1761     isis_fmt();
1762     if (sym!=fchcolch)erro(5000);
1763       else {
1764        gen(-1,dbname_end,-1,p_nulo);
1765        getsymbol();
1766        find=1;
1767     }
1768  }
1769  return find ;
1770}
1771 /*A02 */
1772#if PRINT_CODE
1773/*--------------------------------------------------------------------------*/
1774/*                  translate_instruction                                  */
1775/*--------------------------------------------------------------------------*/
1776#if !CICPP
1777static char *pnome;
1778static char nome[15];
1779#endif /* CICPP */
1780
1781#if CICPP
1782char * FMTSTRU :: translate_instruction(instruction_code i)
1783#else /* CICPP */
1784#if ANSI
1785char *translate_instruction(instruction_code i)
1786#else /*ANSI*/
1787char *translate_instruction(i)
1788instruction_code i;
1789#endif /*ANSI*/
1790#endif /* CICPP */
1791{
1792  int k,j;
1793  pnome = &nome[0];
1794  strcpy(pnome,inst_cnv[i]);
1795  j=strlen(pnome);
1796  for (k=j;k<15;){nome[k++]=' ';}
1797  nome[14]='\0';
1798 return pnome;
1799 }
1800/*--------------------------------------------------------------------------*/
1801/*                  print_inter_din                                        */
1802/*--------------------------------------------------------------------------*/
1803#if CICPP
1804void FMTSTRU :: print_inter_din(char *fmt,
1805                                l_code *head)
1806#else /* CICPP */
1807void print_inter_din(char *fmt,l_code *head)
1808#endif /* CICPP */
1809{
1810  FILE *code;
1811  int i;
1812  int x;
1813  l_code  *t;
1814  field_definition_node *ff;
1815  char *string,nome[15];
1816  LONGX aa;
1817   i=0;
1818   if (  (code=fopen("code_din.lst","w")  )==NULL)
1819    {
1820      printf ("\n Nao da pra gravar intermediario ");
1821      exit(0);
1822     }
1823  fprintf(code,"\n-------------------------------------------------------");
1824 /* O formato nao sera normalmente para ser gravado.
1825   Este if e som para nao dar WARNING!
1826 */
1827 if(i!=0)   fprintf(code,"\nfmt=%s",fmt);
1828  t=(l_code *)head->next; /* deve ser o primeiro no e nao contem informacao */
1829  i=0;
1830fprintf(code,"\n");
1831fprintf(code,"\n End_Abs   |Seq  |Label  | Instrucao     |");
1832fprintf(code,"Desv/Str/Fld|  Desv_Abs   |   Next_inst         Fld/String");
1833fprintf(code,"\n ----------+-----+-------+---------------+");
1834fprintf(code,"------------+-------------+-----------------------------------");
1835for (;t!=nulo;){
1836  i++;
1837  fprintf(code, "\n %ld",(LONGX) t);
1838  fprintf(code,"|%5.0d",i);
1839  x=(int)t->info.lab;
1840  if (x<0){
1841    fprintf(code,"|  ");
1842    x=0;
1843  }else  fprintf(code,"|  ");
1844  fprintf(code,"%5.0d",x);
1845  strcpy(nome,translate_instruction(t->info.instr));
1846  fprintf (code,"| %s",nome /*translate_instruction(t->info.instr)*/ );
1847  aa=(LONGX )t->info.add;
1848  if(aa<0) aa=0L;
1849  fprintf(code,"|%12.0ld",aa);
1850  aa=(LONGX)t->m_add;
1851  fprintf(code,"| %12.0ld",aa);
1852  fprintf(code,"| %12.0ld",(LONGX) t->next);
1853  if (t->info.instr ==load_field_all || t->info.instr==test_occ ||
1854      t->info.instr==print_field ||t->info.instr==load_field_occ ||
1855      t->info.instr==noccins ||
1856      t->info.instr==s_end /*substr em S */ ){
1857     ff=(field_definition_node *)t->info.add;
1858     fprintf (code,
1859         "     (tag=%d,subf=%c,ind1=%d,ind2=%d,off=%d,len=%d,low=%d,upp=%d)",
1860                       ff->tag,ff->sub_field,ff->indent1,
1861                       ff->indent2 ,ff->offset,ff->length,
1862                       ff->lower,ff->upper);
1863  }
1864  if (t->info.instr==u_cond || t->info.instr==pre_cond ||
1865      t->info.instr==suf_cond ||
1866          t->info.instr==pre_r_lit || t->info.instr==pre_r_lit_plus ||
1867          t->info.instr==suf_r_lit || t->info.instr==suf_r_lit_plus ||
1868          t->info.instr==suf_cond_null || t->info.instr==load_string ||
1869          t->info.instr==escape_seq || t->info.instr==load_float){
1870    string =(char *)t->info.add;
1871    fprintf(code,"        (%s)",string);
1872  }
1873  t=(l_code *)t->next;
1874 }
1875 fclose(code);
1876}
1877#endif
1878/*--------------------------------------------------------------------------*/
1879/*                   semantic_initialize                                    */
1880/*--------------------------------------------------------------------------*/
1881#if CICPP
1882void FMTSTRU :: semantic_initialize(void)
1883#else /* CICPP */
1884void semantic_initialize()
1885#endif /* CICPP */
1886 {
1887  int i=0;
1888  n_instructions=0;
1889  next_label=1;
1890  formatting=false;
1891  repeatable=false;
1892  last_format=is_not_rep;
1893  top_stack_breaks= -1;
1894
1895/*  n_repeatable=0;   *repf*/
1896#if PRINT_CODE
1897  inst_next=0;
1898  inst_cnv[dummy]=store_inst_names("Dummy");
1899  inst_cnv[jumpf]=store_inst_names("Jumpf");
1900  inst_cnv[jumpt]=store_inst_names("Jumpt");
1901  inst_cnv[jump]=store_inst_names("Jump");
1902  inst_cnv[ign_cond]=store_inst_names("Ign_Cond");
1903  inst_cnv[pre_cond]=store_inst_names("Pre_Cond");
1904  inst_cnv[pre_r_lit]=store_inst_names("Pre_R_Lit");
1905  inst_cnv[pre_r_lit_plus]=store_inst_names("Pre_R_Lit_Plus");
1906  inst_cnv[suf_cond]=store_inst_names("Suf_Cond");
1907  inst_cnv[suf_cond_null]=store_inst_names("Suf_Cond_Null");
1908  inst_cnv[suf_r_lit]=store_inst_names("Suf_R_Lit");
1909  inst_cnv[suf_r_lit_plus]=store_inst_names("Suf_R_Lit_Plus");
1910  inst_cnv[set_true_rep]=store_inst_names("Set_True_Rep");
1911  inst_cnv[set_false_rep]=store_inst_names("Set_False_Rep");
1912  inst_cnv[test_rep]=store_inst_names("Test_Rep");
1913  inst_cnv[beg_init_not_rep]=store_inst_names("Beg_Init_N_Rep");  /*repf*/
1914  inst_cnv[end_init_not_rep]=store_inst_names("End_Init_N_Rep");  /*repf*/
1915  inst_cnv[beg_init_rep]=store_inst_names("Beg_Init_Rep");      /*repf*/
1916  inst_cnv[end_init_rep]=store_inst_names("End_Init_Rep");      /*repf*/
1917  inst_cnv[begin_rep_gr]=store_inst_names("Begin_Rep_Gr");
1918  inst_cnv[end_rep_gr]=store_inst_names("End_Rep_Gr");
1919  inst_cnv[begin]=store_inst_names("Begin");
1920  inst_cnv[end]=store_inst_names("End");
1921  inst_cnv[test_occ]=store_inst_names("Test_Occ");
1922  inst_cnv[print_field]=store_inst_names("Print_Field");
1923  inst_cnv[d_dummy]=store_inst_names("D_Dummy");
1924  inst_cnv[n_dummy]=store_inst_names("N_Dummy");
1925  inst_cnv[load_field_all]=store_inst_names("Load_Field_All");
1926  inst_cnv[load_field_occ]=store_inst_names("Load_Field_Occ");
1927  inst_cnv[load_number]=store_inst_names("Load_Number");
1928  inst_cnv[load_float]=store_inst_names("Load_Float");
1929  inst_cnv[load_mfn]=store_inst_names("Load_MFN");
1930  inst_cnv[load_core]=store_inst_names("Load_CORE");
1931  inst_cnv[load_maxmfn]=store_inst_names("Load_MAXMFN");
1932  inst_cnv[date_mktime_beg]=store_inst_names("MkTime_Beg");
1933  inst_cnv[date_mktime_end]=store_inst_names("MkTime_End");
1934  inst_cnv[load_string]=store_inst_names("Load_String");
1935  inst_cnv[val_end]=store_inst_names("Val_End");
1936  inst_cnv[x_spac]=store_inst_names("X_Spac");
1937  inst_cnv[c_spac]=store_inst_names("C_Spac");
1938  inst_cnv[slash_spac]=store_inst_names("Slash_Spac");
1939  inst_cnv[n_sign_spac]=store_inst_names("N_Sign_Spac");
1940  inst_cnv[n_sigx_spac]=store_inst_names("n_sigx_spac");
1941  inst_cnv[percent_spac]=store_inst_names("Percent_Spac");
1942  inst_cnv[mpl_par]=store_inst_names("Mpl_Par");
1943  inst_cnv[mpu_par]=store_inst_names("Mpu_Par");
1944  inst_cnv[mhl_par]=store_inst_names("Mhl_Par");
1945  inst_cnv[mhu_par]=store_inst_names("Mhu_Par");
1946  inst_cnv[mdl_par]=store_inst_names("Mdl_Par");
1947  inst_cnv[mdu_par]=store_inst_names("Mdu_Par");
1948  inst_cnv[escape_seq]=store_inst_names("Escape_Seq");
1949  inst_cnv[u_cond]=store_inst_names("U_Cond");
1950  inst_cnv[print_mfn]=store_inst_names("Print_Mfn");
1951  inst_cnv[print_core]=store_inst_names("Print_Core");
1952  inst_cnv[print_maxmfn]=store_inst_names("Print_MaxMfn");
1953  inst_cnv[absent]=store_inst_names("Absent");
1954  inst_cnv[present]=store_inst_names("Present");
1955  inst_cnv[contains]=store_inst_names("Contains");
1956  inst_cnv[neq_op]=store_inst_names("Neq_Op");
1957  inst_cnv[lss_op]=store_inst_names("Lss_Op");
1958  inst_cnv[gtr_op]=store_inst_names("Gtr_Op");
1959  inst_cnv[leq_op]=store_inst_names("Leq_Op");
1960  inst_cnv[geq_op]=store_inst_names("Geq_Op");
1961  inst_cnv[eql_op]=store_inst_names("Eql_Op");
1962  inst_cnv[or_op]=store_inst_names("Or_Op");
1963  inst_cnv[and_op]=store_inst_names("And_Op");
1964  inst_cnv[not_op]=store_inst_names("Not_Op");
1965  inst_cnv[plus_op]=store_inst_names("Plus_Op");
1966  inst_cnv[minus_op]=store_inst_names("Minus_Op");
1967  inst_cnv[times_op]=store_inst_names("Times_Op");
1968  inst_cnv[divide_op]=store_inst_names("Divide_Op");
1969  inst_cnv[init_if]=store_inst_names("Init_If");
1970  inst_cnv[end_then]=store_inst_names("End_Then");
1971  inst_cnv[fi]=store_inst_names("Fi");
1972  inst_cnv[beg_init_not_rep]=store_inst_names("Beg_Init_N_Rep");
1973  inst_cnv[end_init_not_rep]=store_inst_names("End_Init_N_Rep");
1974  inst_cnv[beg_init_rep]=store_inst_names("Beg_Init_Rep");
1975  inst_cnv[end_init_rep]=store_inst_names("End_Init_Rep");
1976  inst_cnv[end_else]=store_inst_names("End_Else");
1977  inst_cnv[val_beg]=store_inst_names("Val_Beg");
1978  inst_cnv[rupx_beg]=store_inst_names("Rupx_Beg");
1979  inst_cnv[rupx_end]=store_inst_names("Rupx_End");
1980  inst_cnv[rupd_beg]=store_inst_names("Rupd_Beg");
1981  inst_cnv[rupd_end]=store_inst_names("Rupd_End");
1982  inst_cnv[syst_beg]=store_inst_names("Syst_Beg");
1983  inst_cnv[syst_end]=store_inst_names("Syst_End");
1984  inst_cnv[rsum_beg]=store_inst_names("Rsum_Beg");
1985  inst_cnv[rsum_end]=store_inst_names("Rsum_End");
1986  inst_cnv[rmax_beg]=store_inst_names("Rmax_Beg");
1987  inst_cnv[rmax_end]=store_inst_names("Rmax_End");
1988  inst_cnv[rmin_beg]=store_inst_names("Rmin_Beg");
1989  inst_cnv[rmin_end]=store_inst_names("Rmin_End");
1990  inst_cnv[ravr_beg]=store_inst_names("Ravr_Beg");
1991  inst_cnv[ravr_end]=store_inst_names("Ravr_End");
1992  inst_cnv[l_beg]=store_inst_names("L_Beg");
1993  inst_cnv[l_end]=store_inst_names("L_End");
1994  inst_cnv[instr_beg]=store_inst_names("Instr_Beg");
1995  inst_cnv[instr_end]=store_inst_names("Instr_End");
1996  inst_cnv[left_beg]=store_inst_names("Left_Beg");
1997  inst_cnv[left_end]=store_inst_names("Left_End");
1998  inst_cnv[datex_beg]=store_inst_names("Datex_Beg");
1999  inst_cnv[datex_end]=store_inst_names("Datex_End");
2000  inst_cnv[right_beg]=store_inst_names("Right_Beg");
2001  inst_cnv[right_end]=store_inst_names("Right_End");
2002  inst_cnv[mid_beg]=store_inst_names("Mid_Beg");
2003  inst_cnv[mid_end]=store_inst_names("Mid_End");
2004  inst_cnv[s_beg]=store_inst_names("S_Beg");
2005  inst_cnv[s_end]=store_inst_names("S_End");
2006  inst_cnv[getenv_beg]=store_inst_names("Getenv_Beg");
2007  inst_cnv[getenv_end]=store_inst_names("Getenv_End");
2008  inst_cnv[putenv_beg]=store_inst_names("Putenv_Beg");
2009  inst_cnv[putenv_end]=store_inst_names("Putenv_End");
2010  inst_cnv[fmt_end]=store_inst_names("Fmt_End");
2011  inst_cnv[fmt_beg]=store_inst_names("Fmt_Beg");
2012  inst_cnv[prt_str_f]=store_inst_names("Prt_Str_F");
2013/*  inst_cnv[load_str_f]=store_inst_names("Load_Str_F");*/
2014  inst_cnv[str_cat]=store_inst_names("Str_Cat");
2015  inst_cnv[ref_beg]=store_inst_names("Ref_Beg");
2016  inst_cnv[ref_end]=store_inst_names("Ref_End");
2017  inst_cnv[refu_beg]=store_inst_names("Refu_Beg");
2018  inst_cnv[refu_end]=store_inst_names("Refu_End");
2019  inst_cnv[read_mfn]=store_inst_names("Read_Mfn");
2020  inst_cnv[f_beg]=store_inst_names("F_Beg");
2021  inst_cnv[f_end]=store_inst_names("F_End");
2022  inst_cnv[update_fld]=store_inst_names("Update_Fld");
2023  inst_cnv[input_fld]=store_inst_names("Input_Fld");
2024  inst_cnv[lw_beg]=store_inst_names("Lw_Beg");
2025  inst_cnv[lw_end]=store_inst_names("Lw_End");
2026  inst_cnv[dbname_beg]=store_inst_names("Dbname_Beg");
2027  inst_cnv[dbname_end]=store_inst_names("Dbname_End");
2028  inst_cnv[np_beg]=store_inst_names("Npost_Beg");
2029  inst_cnv[np_end]=store_inst_names("Npost_End");
2030  inst_cnv[noccins]=store_inst_names("Nocc");
2031  inst_cnv[ioccins]=store_inst_names("Iocc");
2032  inst_cnv[continueins]=store_inst_names("Continue");
2033  inst_cnv[breakins]=store_inst_names("Break");
2034  inst_cnv[size_beg]=store_inst_names("Size_Beg");
2035  inst_cnv[size_end]=store_inst_names("Size_End");
2036  inst_cnv[type_beg]=store_inst_names("Type_Beg");
2037  inst_cnv[type_end]=store_inst_names("Type_End");
2038  inst_cnv[cat_beg]=store_inst_names("Cat_Beg");
2039  inst_cnv[cat_end]=store_inst_names("Cat_End");
2040  inst_cnv[nl_beg]=store_inst_names("Nl_Beg");
2041  inst_cnv[nl_end]=store_inst_names("Nl_End");
2042  inst_cnv[load_mstnam]=store_inst_names("Load_MstNam");
2043/*   inst_cnv[print_mstnam]=store_inst_names("Print_MstNam"); */
2044  inst_cnv[load_date]=store_inst_names("Load_Date");
2045  inst_cnv[duptop]=store_inst_names("Dup");
2046  inst_cnv[end_select]=store_inst_names("End_Select");
2047
2048  inst_cnv[replac_beg]=store_inst_names("Replace_Beg");
2049  inst_cnv[replac_end]=store_inst_names("Replace_End");
2050#if CI_XMLELEM
2051  inst_cnv[xmlelem_beg]=store_inst_names("XmlElem_Beg");
2052  inst_cnv[xmlelem_end]=store_inst_names("XmlElem_End");
2053#endif
2054  inst_cnv[while_beg]=store_inst_names("While_Beg");
2055  inst_cnv[while_end]=store_inst_names("While_End");
2056  inst_cnv[occins]=store_inst_names("Occ");
2057  inst_cnv[eattrib_beg]=store_inst_names("Eatrrib_Beg");
2058  inst_cnv[eattrib_end]=store_inst_names("Eatrrib_End");
2059  inst_cnv[sattrib_beg]=store_inst_names("Satrrib_Beg");
2060  inst_cnv[sattrib_end]=store_inst_names("Satrrib_End");
2061  inst_cnv[intvvalue]=store_inst_names("IntVValue");
2062  inst_cnv[strvvalue]=store_inst_names("StrVValue");
2063
2064
2065
2066/*   inst_cnv[print_date]=store_inst_names("Print_Date"); */
2067  inst_cnv[zzzzzz]=store_inst_names("zzzzzz");
2068#endif
2069  /* Inicialmente assume-se que todos os symbolos nao tem instrucao
2070         correspondente
2071  */
2072  for (i=firstsym;i<=zzzsym;i++){sym_to_instruction[i]= (enum ins)-1;}
2073  sym_to_instruction[csym ]=c_spac;
2074  sym_to_instruction[xsym ]=x_spac;
2075  sym_to_instruction[dsym ]=jumpf;
2076  sym_to_instruction[nsym ]=jumpt;
2077  sym_to_instruction[vsym ]= (enum ins)-1;
2078  sym_to_instruction[ifsym]= (enum ins)-1;
2079  sym_to_instruction[fisym]= (enum ins)-1;
2080  sym_to_instruction[thensym]= (enum ins)-1;
2081  sym_to_instruction[elsesym]= (enum ins)-1;
2082  sym_to_instruction[orsym ]=or_op;
2083  sym_to_instruction[andsym]=and_op;
2084  sym_to_instruction[notsym]=not_op;
2085  sym_to_instruction[mfnsym]=print_mfn;
2086  sym_to_instruction[coresym]=print_core;
2087  sym_to_instruction[maxmfnsym]=print_maxmfn;
2088  sym_to_instruction[datemktimesym]=date_mktime_beg;
2089  sym_to_instruction[mplsym]=mpl_par;
2090  sym_to_instruction[mpusym]=mpu_par;
2091  sym_to_instruction[mhlsym]=mhl_par;
2092  sym_to_instruction[mhusym]=mhu_par;
2093  sym_to_instruction[mdusym]=mdu_par;
2094  sym_to_instruction[mdlsym]=mdl_par;
2095  sym_to_instruction[comma ]= (enum ins)-1;
2096  sym_to_instruction[slash ]=divide_op;
2097  sym_to_instruction[number_sign]=n_sign_spac;
2098  sym_to_instruction[number_sigx]=n_sigx_spac;
2099  sym_to_instruction[percent]=percent_spac;
2100  sym_to_instruction[lparen ]= (enum ins)-1;
2101  sym_to_instruction[rparen ]= (enum ins)-1;
2102  sym_to_instruction[flecha ]= (enum ins)-1;
2103  sym_to_instruction[times]=times_op;
2104  sym_to_instruction[plus ]=plus_op;
2105  sym_to_instruction[minus]=minus_op;
2106  sym_to_instruction[doispontos]=contains;
2107  sym_to_instruction[eql]=eql_op;
2108  sym_to_instruction[neq]=neq_op;
2109  sym_to_instruction[lss]=lss_op;
2110  sym_to_instruction[leq]=leq_op;
2111  sym_to_instruction[gtr]=gtr_op;
2112  sym_to_instruction[geq]=geq_op;
2113  sym_to_instruction[space   ]= (enum ins)-1;
2114  sym_to_instruction[u_litsym]=u_cond;
2115  sym_to_instruction[c_litsym]= (enum ins)-1;
2116  sym_to_instruction[esc_strsym]=escape_seq;
2117  sym_to_instruction[number]= (enum ins)-1;
2118  sym_to_instruction[nullsym]= (enum ins)-1;
2119  sym_to_instruction[asym]=absent;
2120  sym_to_instruction[psym]=present;
2121  sym_to_instruction[s_fieldsym]= (enum ins)-1;
2122  sym_to_instruction[r_litsym]= (enum ins)-1;
2123  sym_to_instruction[fsym]=f_beg;
2124  sym_to_instruction[s_sym]=s_beg;
2125  sym_to_instruction[instrsym]=instr_beg;
2126  sym_to_instruction[leftsym]=left_beg;
2127  sym_to_instruction[datexsym]=datex_beg;
2128  sym_to_instruction[replacsym]=replac_beg;
2129#if CI_XMLELEM
2130  sym_to_instruction[xmlelemsym]=xmlelem_beg;
2131#endif
2132  sym_to_instruction[midsym]=mid_beg;
2133  sym_to_instruction[getenv_sym]=getenv_beg;
2134  sym_to_instruction[putenv_sym]=putenv_beg;
2135  sym_to_instruction[refsym]=ref_beg;
2136  sym_to_instruction[rupxsym]=rupx_beg;
2137  sym_to_instruction[rupdsym]=rupd_beg;
2138  sym_to_instruction[systsym]=syst_beg;
2139  sym_to_instruction[rsumsym]=rsum_beg;
2140  sym_to_instruction[rminsym]=rmin_beg;
2141  sym_to_instruction[rmaxsym]=rmax_beg;
2142  sym_to_instruction[ravrsym]=ravr_beg;
2143  sym_to_instruction[valsym]=val_beg;
2144  sym_to_instruction[lsym]=l_beg;
2145  sym_to_instruction[ponto]= (enum ins)-1;
2146  sym_to_instruction[fmtsym]=fmt_beg;
2147  sym_to_instruction[usym]=update_fld;
2148  sym_to_instruction[isym]=input_fld;
2149  sym_to_instruction[lwsym]=lw_beg;
2150  sym_to_instruction[abrcolch]=dbname_beg;
2151  sym_to_instruction[fchcolch]=dbname_end;
2152  sym_to_instruction[noccsym]=noccins;
2153  sym_to_instruction[ioccsym]=ioccins;
2154  sym_to_instruction[continuesym]=continueins;
2155  sym_to_instruction[breaksym]=breakins;
2156  sym_to_instruction[npsym]=np_beg;
2157  sym_to_instruction[sizesym]=size_beg;
2158  sym_to_instruction[typesym]=type_beg;
2159  sym_to_instruction[catsym]=cat_beg;
2160  sym_to_instruction[nl_sym]=nl_beg;
2161/*   sym_to_instruction[mstsym]=print_mstnam; */
2162/*   sym_to_instruction[datesym]=print_date; */
2163  sym_to_instruction[whilesym]=while_beg;
2164  sym_to_instruction[occsym]=occins;
2165  sym_to_instruction[ss_sym]=ss_beg;
2166  sym_to_instruction[citypesym]=citype_beg;
2167
2168
2169  sym_to_instruction[zzzsym]=zzzzzz;
2170
2171}
2172/*--------------------------------------------------------------------------*/
2173/*                   semantic_error                                         */
2174/*--------------------------------------------------------------------------*/
2175#if CICPP
2176void FMTSTRU :: semantic_error(char *msg)
2177#else /* CICPP */
2178#if ANSI
2179void semantic_error(char *msg)
2180#else /*ANSI*/
2181void semantic_error(msg)
2182char *msg;
2183#endif /*ANSI*/
2184#endif /* CICPP */
2185{
2186    if (msg) fprintf(stderr,"*** %s\n",msg);
2187    fatal("fmt_gener/semantic_error");
2188}
2189/*--------------------------------------------------------------------------*/
2190/*                   store_field_def                                        */
2191/*--------------------------------------------------------------------------*/
2192#if CICPP
2193LONGX FMTSTRU :: store_field_def(int tag,
2194                                char subfield,
2195                                int ind1,
2196                                int ind2,
2197                                int off,
2198                                int len,
2199                                int low,
2200                                int upp)
2201#else /* CICPP */
2202#if ANSI
2203LONGX store_field_def(int tag,
2204                     char subfield,
2205                     int ind1,
2206                     int ind2,
2207                     int off,
2208                     int len,
2209                     int low,
2210                     int upp)
2211#else /*ANSI*/
2212LONGX store_field_def(tag,subfield,ind1,ind2,off,len,low,upp)
2213int tag;
2214char subfield;
2215int ind1;
2216int ind2;
2217int off;
2218int len;
2219int low;
2220int upp;
2221#endif /*ANSI*/
2222#endif /* CICPP */
2223   {
2224     LONGX ret;
2225     field_definition_node *tmp;
2226     tmp = alloc_field_definition_node ();
2227     tmp->tag=tag;
2228     tmp->sub_field=subfield;
2229     tmp->indent1=ind1;
2230     tmp->indent2=ind2;
2231     tmp->offset=off;
2232     tmp->length=len;
2233     tmp->lower=low;
2234     tmp->upper=upp;
2235     tmp->max_occ=0;
2236     tmp->last_occ=0;
2237#if TRACE_COMP_F
2238     if (fmttrace)
2239printf(
2240"#%d[tag=%d,subf=%c,id1=%d,id2=%d,off=%d,len=%d,low=%d,upp=%d,max=%d,last=%d\n",
2241             0,
2242             tmp->tag,
2243             tmp->sub_field,
2244             tmp->indent1,
2245             tmp->indent2,
2246             tmp->offset,
2247             tmp->length,
2248             tmp->lower,
2249             tmp->upper,
2250             tmp->max_occ,
2251             tmp->last_occ);
2252#endif /* TRACE_COMP_F */
2253     ret = (LONGX) tmp;
2254     return ret;
2255    }
2256/*-------------------------------------------------------------------------*/
2257/*                   gen                                                   */
2258/*-------------------------------------------------------------------------*/
2259/*   Gen (lab,inst,add,index);                                             */
2260/*                                                                         */
2261/* Gera uma instrucao do codigo intermediario                              */
2262/* Lab   < 0   instrucao nao tem label                                     */
2263/* add   < 0   instrucao nao tem operandos                                 */
2264/* add   > 0 dependendo do codigo da instrucao pode apontar par a :        */
2265/*                                                                         */
2266/*           a) uma constante real ou  string                              */
2267/*           b) os parametros da definicao de um format_fields             */
2268/*           c) desvio para uma outra instrucao                            */
2269/*           d) Em vez de apontar, ser o valor de uma constante numerica do*/
2270/*              do tipo LONGX                                               */
2271/* index    Endereco onde  deve ser armazenada a instrucao                 */
2272/*          = p_nulo    proxima posicao livre                              */
2273/*          otherwise  instrucao armazenada na posicao apontada por index  */
2274/* Retorna 1 se conseguiu gerar instrucao                                  */
2275/*-------------------------------------------------------------------------*/
2276#if CICPP
2277int FMTSTRU :: gen(label   lab,
2278                   instruction_code instr,
2279                   LONGX    add,
2280                   l_code *index)
2281#else /* CICPP */
2282#if ANSI
2283int gen(label   lab,
2284        instruction_code instr,
2285        LONGX    add,
2286        l_code *index)
2287#else /*ANSI*/
2288int gen(lab,instr,add,index)
2289label lab;
2290instruction_code instr;
2291LONGX add;
2292l_code *index;
2293#endif /*ANSI*/
2294#endif /* CICPP */
2295{
2296 l_code  *i;
2297 i=index;
2298 /* Verifica se e necessario gerar uma nova instrucao ou se uma instrucao
2299    deve ser complementada
2300 */
2301#if FMT_OPTIMIZE
2302 if (index == nulo && lab== -1 ){
2303   /* verifica se ainstrucao e uma pseudo instrucao. Neste caso ela podera
2304      ser desconsiderada e a nova instrucao e colocada em cima
2305   */
2306     if ( last_instr->info.instr==end ||
2307          last_instr->info.instr==begin ||
2308          last_instr->info.instr==init_if ||
2309          last_instr->info.instr==end_then ){
2310      last_instr->info.instr=instr;
2311      last_instr->info.add=add;
2312      return 1;
2313     }
2314   /* Existem instrucoes que nao precisam ser geradas */
2315    if (instr==end_else) return 1;
2316 }
2317#endif
2318 if (index == nulo) {
2319   i=alloc_pgm_node( );
2320  }
2321 i->info.lab=lab;
2322 i->info.instr=instr;
2323 i->info.add=add;
2324 /* Se gerar uma nova instrucao a ultima instrucao devera ser atualizada e o
2325    apontador da ultima devera se alterado
2326 */
2327 if(index == nulo)
2328  { i->next = 0L; /*nulo;*/            /* AOT, 22/01/2006 */
2329    last_instr->next = (LONGX) i;
2330    last_instr=i;
2331  }
2332 n_instructions++;
2333 return 1;
2334}
2335/*--------------------------------------------------------------------------*/
2336/*                   gen_next_label                                         */
2337/*--------------------------------------------------------------------------*/
2338#if CICPP
2339label FMTSTRU :: gen_next_label(void)
2340#else /* CICPP */
2341label gen_next_label()
2342#endif /* CICPP */
2343{
2344 return next_label++;
2345}
2346/* ---------------------------------------------------------------------*/
2347/*--------------------------------------------------------------------------*/
2348/*                   change_pre_cond_by_u_cond                              */
2349/*--------------------------------------------------------------------------*/
2350#if CICPP
2351void FMTSTRU :: change_pre_cond_by_u_cond(l_code *first,
2352                                           l_code *last)
2353#else /* CICPP */
2354#if ANSI
2355void change_pre_cond_by_u_cond(l_code *first,
2356                               l_code *last)
2357#else /*ANSI*/
2358void change_pre_cond_by_u_cond(first,last)
2359l_code *first;
2360l_code *last;
2361#endif /*ANSI*/
2362#endif /* CICPP */
2363{
2364 int acabou;
2365 acabou=false;
2366for (;acabou==false;)
2367{
2368if (first==last) acabou=true;
2369if (first->info.instr==pre_cond )
2370 {
2371  first->info.instr= u_cond;
2372  }
2373 first=(l_code *)first->next;
2374 }
2375}
2376/*--------------------------------------------------------------------------*/
2377/*                   parse_left_right_mid                                       */
2378/*--------------------------------------------------------------------------*/
2379#if CICPP
2380int FMTSTRU :: parse_left_right_mid(instruction_code begin,
2381                                    instruction_code end)
2382#else /* CICPP */
2383#if ANSI
2384int parse_left_right_mid(instruction_code begin,
2385                         instruction_code end)
2386#else /*ANSI*/
2387int parse_left_right_mid(begin,end)
2388instruction_code begin;
2389instruction_code end;
2390#endif /*ANSI*/
2391#endif /* CICPP */
2392{
2393 int find=0;
2394 gen(-1,begin,-1,p_nulo);
2395 get_ignore_space();
2396 if (sym != lparen ) erro (400);
2397  get_ignore_space();
2398  if (!string_expr()) erro(401);
2399  if (sym != comma) erro (402);
2400  get_ignore_space();
2401  if (!num_expr()) erro(403);
2402  if (begin == mid_beg) {
2403     if (sym != comma) erro (402);
2404     get_ignore_space();
2405     if (!num_expr()) erro(405);
2406  }
2407  if (sym != rparen) erro(404);
2408  get_ignore_space();
2409  gen(-1,end,-1,p_nulo);
2410  find=1;
2411  return find;
2412}
2413/*--------------------------------------------------------------------------*/
2414/*                   parse_ss                                               */
2415/*--------------------------------------------------------------------------*/
2416#if CICPP
2417int FMTSTRU :: parse_ss(void)
2418#else /* CICPP */
2419#if ANSI
2420int parse_ss(void)
2421#else /*ANSI*/
2422int parse_ss()
2423#endif /* ANSI */
2424#endif /* CICPP */
2425{
2426  gen(-1,ss_beg,-1,p_nulo);
2427  get_ignore_space();
2428  if (sym != lparen ) erro (500);
2429  get_ignore_space();
2430  if (!num_expr()) erro(501);
2431  if (sym != comma) erro (502);
2432  get_ignore_space();
2433  if (!num_expr()) erro(503);
2434  if (sym != comma) erro (502);
2435  get_ignore_space();
2436  if (!string_expr()) erro(505);
2437  if (sym != rparen) erro(404);
2438  get_ignore_space();
2439  gen(-1,ss_end,-1,p_nulo);
2440  return (1);
2441}
2442/*--------------------------------------------------------------------------*/
2443/*                   parse_replace                                           */
2444/*--------------------------------------------------------------------------*/
2445#if CICPP
2446int FMTSTRU :: parse_replace(instruction_code begin,
2447                             instruction_code end)
2448#else /* CICPP */
2449#if ANSI
2450int parse_replace(instruction_code begin,
2451                         instruction_code end)
2452#else /*ANSI*/
2453int parse_replace(begin,end)
2454instruction_code begin;
2455instruction_code end;
2456#endif /*ANSI*/
2457#endif /* CICPP */
2458{
2459 int find=0;
2460 gen(-1,begin,-1,p_nulo);
2461 get_ignore_space();
2462 if (sym != lparen ) erro (450);
2463 get_ignore_space();
2464 if (!string_expr()) erro(451);
2465 if (sym != comma) erro (452);
2466 get_ignore_space();
2467 if (!string_expr()) erro(453);
2468 if (sym != comma) erro (454);
2469 get_ignore_space();
2470 if (!string_expr()) erro(455);
2471 if (sym != rparen) erro(456);
2472 get_ignore_space();
2473  gen(-1,end,-1,p_nulo);
2474  find=1;
2475  return find;
2476}
2477#if CI_XMLELEM
2478/*--------------------------------------------------------------------------*/
2479/*                   parse_xmlelem                                           */
2480/*--------------------------------------------------------------------------*/
2481#if CICPP
2482int FMTSTRU :: parse_xmlelem(instruction_code begin,
2483                             instruction_code end)
2484#else /* CICPP */
2485#if ANSI
2486int parse_xmlelem(instruction_code begin,
2487                         instruction_code end)
2488#else /*ANSI*/
2489int parse_xmlelem(begin,end)
2490instruction_code begin;
2491instruction_code end;
2492#endif /*ANSI*/
2493#endif /* CICPP */
2494{
2495 /* sintaxe: XMLELEM(data,elemname,occ,attrname,conventity)     */
2496 int find=0;
2497
2498 gen(-1,begin,-1,p_nulo);
2499 get_ignore_space();
2500
2501 if (sym != lparen ) {
2502         erro (1450);
2503 } else {
2504        get_ignore_space();
2505        if (!string_expr()) {
2506                erro(1451);
2507        } else if (sym != comma) {
2508                erro (1452);
2509        } else {
2510                get_ignore_space();
2511                if (!string_expr()) {
2512                        erro(1453);
2513                } else if (sym != comma) {
2514                        erro (1454);
2515                } else {
2516                        get_ignore_space();
2517                        if (!num_expr()) {
2518                                erro(1455);
2519                        } else if (sym != comma) {
2520                                erro (1456);
2521                        } else {
2522                                get_ignore_space();
2523                                if (!string_expr()) {
2524                                        erro(1457);
2525                } else if (sym != comma) {
2526                                erro (1458);
2527                        } else {
2528                                get_ignore_space();
2529                                if (!num_expr()) {
2530                                        erro(1459);
2531                                    } else if (sym != rparen) {
2532                                            erro(1460);
2533                                    } else {
2534                                            get_ignore_space();
2535                                            gen(-1,end,-1,p_nulo);
2536                                            find=1;
2537                    }
2538                                }
2539                        }
2540                }
2541        }
2542 }
2543
2544 /*
2545 int find=0;
2546 gen(-1,begin,-1,p_nulo);
2547 get_ignore_space();
2548 if (sym != lparen ) erro (1450);
2549 get_ignore_space();
2550 if (!string_expr()) erro(1451);
2551 if (sym != comma) erro (1452);
2552 get_ignore_space();
2553 if (!string_expr()) erro(1453);
2554 if (sym != comma) erro (1454);
2555 get_ignore_space();
2556 if (!num_expr()) erro(1455);
2557 if (sym != comma) erro (1456);
2558 get_ignore_space();
2559 if (!string_expr()) erro(1457);
2560 if (sym != rparen) erro(1458);
2561 get_ignore_space();
2562 gen(-1,end,-1,p_nulo);
2563 find=1;
2564*/
2565
2566  return find;
2567}
2568#endif /* CI_XMLELEM */
2569/*--------------------------------------------------------------------------*/
2570/*                   function_code_generator                                */
2571/*--------------------------------------------------------------------------*/
2572#if CICPP
2573int FMTSTRU :: function_code_generator(instruction_code begin,
2574                                       instruction_code end)
2575#else /* CICPP */
2576#if ANSI
2577int function_code_generator(instruction_code begin,
2578                            instruction_code end)
2579#else /*ANSI*/
2580int function_code_generator(begin,end)
2581instruction_code begin;
2582instruction_code end;
2583#endif /*ANSI*/
2584#endif /* CICPP */
2585{
2586int  find=0;
2587/*substr em S */
2588 int off,len;
2589 static LONGX field_address;
2590 /* So precisa para S  */
2591/*substr em S */
2592 /* substring na funcao S - daria para colocar em outras desta classe */
2593
2594gen(-1,begin,-1,p_nulo);
2595getsymbol();
2596if(sym!=lparen) erro(54);
2597 getsymbol( );
2598 isis_fmt();
2599 if (sym!=rparen) erro(55);
2600 classe_numero_procurado=PARSEINTNUMB;
2601 getsymbol();
2602 classe_numero_procurado= -PARSEINTNUMB;
2603 field_address= -1L;
2604 if (begin==s_beg) {
2605      field_substr(&off,&len);
2606      field_address=store_field_def(0,0,0,0,off,len,0,0);
2607 }
2608 gen(-1,end,field_address,p_nulo);
2609 find=1;
2610 return (find);
2611}
2612/*--------------------------------------------------------------------------*/
2613/*                   c_fmt_separator                                        */
2614/*--------------------------------------------------------------------------*/
2615#if CICPP
2616int FMTSTRU :: c_fmt_separator(void)
2617#else /* CICPP */
2618int c_fmt_separator()
2619#endif /* CICPP */
2620{
2621int find=0;
2622if ( sym==space || sym==comma)
2623{
2624  getsymbol( );
2625  find=1;
2626}
2627return find;
2628}
2629/*--------------------------------------------------------------------------*/
2630/*                   field_occs                                             */
2631/*--------------------------------------------------------------------------*/
2632#if CICPP
2633int FMTSTRU :: field_occs(int *fst,
2634                          int *last)
2635#else /* CICPP */
2636#if ANSI
2637int field_occs(int *fst,
2638               int *last)
2639#else /*ANSI*/
2640int field_occs(fst,last)
2641int *fst;
2642int *last;
2643#endif /*ANSI*/
2644#endif /* CICPP */
2645{ int find;
2646
2647  find=0;
2648  *fst= NO_MIN_OCC;
2649  *last= NO_MAX_OCC;
2650
2651  if (sym ==abrcolch){
2652     find=1;
2653     classe_numero_procurado=PARSEINTNUMB;
2654     get_ignore_space();
2655     if (sym == lastsym) {
2656        num=LASTVAL;
2657        sym=number;
2658     }
2659    if(sym != number) erro(8);
2660    *fst=(int) num;
2661    *last=(int) num; /* supoe que nao tem limite superior */
2662     get_ignore_space();
2663     if (sym == ponto) {
2664       getsymbol();
2665       if (sym != ponto) erro(123);
2666       get_ignore_space();
2667       if (sym == lastsym){
2668         num=LASTVAL;
2669         sym=number;
2670       }
2671       if( sym !=number) {
2672           if (sym == fchcolch) {
2673                 num=LASTVAL;
2674                 *last=(int) num;
2675           }
2676           else erro(8);
2677       }
2678       else {
2679           *last=(int) num;
2680           get_ignore_space();
2681       }
2682     }
2683    if (sym != fchcolch) erro(81);
2684    get_ignore_space();
2685    classe_numero_procurado= -PARSEINTNUMB;
2686  }
2687  return (find);
2688}
2689/*-------------------------------------------------------------------------*/
2690/* A08              field_tag                                           */
2691/*--------------------------------------------------------------------------*/
2692#if CICPP
2693int FMTSTRU :: field_tag(void)
2694#else /* CICPP */
2695#if ANSI
2696int field_tag(void)
2697
2698#else /*ANSI*/
2699int field_tag()
2700#endif /*ANSI*/
2701#endif /* CICPP */
2702{
2703
2704  return(parse_int_number());
2705}
2706
2707/*--------------------------------------------------------------------------*/
2708/* A08               subfield_id                                      */
2709/*--------------------------------------------------------------------------*/
2710#if CICPP
2711int FMTSTRU :: subfield_id(char *sbf)
2712#else /* CICPP */
2713#if ANSI
2714int subfield_id(char *sbf)
2715#else /*ANSI*/
2716int subfield_id(sbf)
2717char *sbf;
2718#endif /*ANSI*/
2719#endif /* CICPP */
2720{
2721  char subfield;
2722  subfield=space_char;
2723  if (sym == s_fieldsym){
2724     classe_numero_procurado=PARSEINTNUMB; /* 05-01-95 permitir v2^a.6 porque
2725                                              o getsymbol analisa .6 como float
2726                                           */
2727     subfield=sub_field_value;
2728     getsymbol();
2729     classe_numero_procurado= -PARSEINTNUMB; /* 05-01-95 permitir v2^a.6 porque
2730                                              o getsymbol analisa .6 como float
2731                                             */
2732  }
2733  *sbf=subfield;
2734  return (1);
2735}
2736/*--------------------------------------------------------------------------*/
2737/*                   isis_fmt                                               */
2738/*--------------------------------------------------------------------------*/
2739#if CICPP
2740int FMTSTRU :: dummy_id (l_code *idx,
2741                         label   lab1)
2742#else /* CICPP */
2743#if ANSI
2744int dummy_id (l_code *idx,
2745              label   lab1)
2746#else /*ANSI*/
2747int dummy_id (idx,lab1)
2748l_code *idx;
2749label lab1;
2750#endif /*ANSI*/
2751#endif /* CICPP */
2752{
2753  instruction_code inst ;
2754  int tag;
2755  char subfield;
2756  int find = 0;
2757  if ( (sym == dsym) || (sym == nsym)){
2758      inst=sym_to_instruction[sym];
2759      tag=field_tag();
2760      find=subfield_id(&subfield);
2761      field_address =
2762        store_field_def(tag,subfield,0,0,-1,-1,NO_MIN_OCC,NO_MAX_OCC);
2763      /* store instructions behind */
2764      gen(-1,test_occ,field_address,idx);
2765      /* The jump instruction depends on dummy field
2766        if d_dummy the "condition"  is printed if field is present; thus
2767        a "jumpf"  has to be generated .
2768       If a n_dummy the "condition is printed if field not present; thus
2769        a jumpt has to be generated
2770      */
2771      idx=(l_code *)idx->next;
2772      gen(-1,inst,lab1,idx);
2773      formatting=false;
2774      /* for Ntag, after the test_occ generated, a jumpt is generated
2775         meaning     that the conditional fields don't have to be
2776         printed if present .
2777         Otherwise the conditional literals have to be printed when
2778         the field is not present. As pre_cond fields are printed if
2779         and only if the is presented, the pre_cond generated has  to
2780         be changed to u_cond fields.
2781      */
2782      if(inst==jumpt ) change_pre_cond_by_u_cond(idx,last_instr);
2783      /* terminates generation */
2784      gen(lab1,end,-1,p_nulo);
2785    }
2786  return find;
2787} /* dummy_id */
2788/*--------------------------------------------------------------------------*/
2789/*                   r_prelit                                               */
2790/*--------------------------------------------------------------------------*/
2791#if CICPP
2792int FMTSTRU :: r_prelit (void)
2793#else /* CICPP */
2794int r_prelit ()
2795#endif /* CICPP */
2796{
2797int find = 0;
2798if (sym == r_litsym){
2799  address=store_str_const(str);
2800  actual_inst.info.lab= -1;
2801  actual_inst.info.instr=pre_r_lit;
2802  actual_inst.info.add=address;
2803  getsymbol();
2804  find = 1;
2805  if (sym == plus){
2806         /* change the instruction code */
2807         actual_inst.info.instr=pre_r_lit_plus;
2808         getsymbol();
2809  }
2810}
2811/*
2812 codigo sera gerado por quem chamou
2813*/
2814return find;
2815}/* r_prelit */
2816/*--------------------------------------------------------------------------*/
2817/*                   suffix                                                 */
2818/*--------------------------------------------------------------------------*/
2819#if CICPP
2820void FMTSTRU :: suffix (void)
2821#else /* CICPP */
2822void suffix ()
2823#endif /* CICPP */
2824{
2825 actual_inst.info.instr=dummy;
2826 if (sym == plus ){
2827   actual_inst.info.instr=suf_r_lit_plus;
2828   getsymbol();
2829   if (sym != r_litsym) { address=0L; /* AOT/HB - 26/04/99
2830                                         Sindo: ver se deve inicializar
2831                                         mais genericamente.
2832                                         E' necessario para fmt_free nao
2833                                         fazer delete/free do literal
2834                                         que nao foi store_str_const'ed.
2835                                         Teste com formatos (errados) que
2836                                         terminam por ... V70+
2837                                      */
2838                          erro (9);
2839                        }
2840          else{
2841                address=store_str_const(str);
2842                getsymbol();
2843          }
2844  }else
2845        if (sym == r_litsym){
2846          address=store_str_const(str);
2847          actual_inst.info.instr=suf_r_lit;
2848          getsymbol();
2849        }
2850 if (actual_inst.info.instr !=dummy){
2851   gen(-1,actual_inst.info.instr,address,p_nulo);
2852 }
2853 if (sym == c_litsym){
2854   address=store_str_const(str);
2855   gen(-1,suf_cond,address,p_nulo);
2856   /* falta ver se e str null para gera suf_cond_null */
2857   getsymbol();
2858  }
2859}/*  suffix */
2860/*--------------------------------------------------------------------------*/
2861/*                   field                                                  */
2862/*--------------------------------------------------------------------------*/
2863#if CICPP
2864void FMTSTRU :: field (void)
2865#else /* CICPP */
2866void field ()
2867#endif /* CICPP */
2868{
2869 int tag,off,len;
2870 int low,upp;
2871 char subfield;
2872 int tem_occs;   /*A08 Marca se ja foi analisado indexacao */
2873 tag=0;
2874 subfield=' ';
2875 tag=field_tag();                /*A08*/
2876 tem_occs = field_occs(&low,&upp);  /*A08*/
2877 subfield_id(&subfield);      /*A08*/
2878       /*So permite indexacao se ainda nao apareceu */
2879 if (tem_occs != 1)  field_occs(&low,&upp);   /*A08 */
2880 field_substr(&off,&len);
2881 field_address=store_field_def(tag,subfield,0,0,off,len,low,upp);
2882} /* field */
2883/*--------------------------------------------------------------------------*/
2884/*                   field_substr                                           */
2885/*--------------------------------------------------------------------------*/
2886#if CICPP
2887void FMTSTRU :: field_substr (int *off,
2888                               int *len)
2889#else /* CICPP */
2890#if ANSI
2891void field_substr (int *off,
2892                   int *len)
2893#else /*ANSI*/
2894void field_substr (off,len)
2895int *off;
2896int *len;
2897#endif /*ANSI*/
2898#endif /* CICPP */
2899{
2900 *off= -1;
2901 *len= -1;
2902 if (sym == times || sym == ponto){
2903    *off=0;
2904    if (sym == times ){
2905      *off=parse_int_number();
2906    }
2907   *len=SHRT_MAX;
2908   if (sym == ponto) {
2909      *len=parse_int_number();
2910   }
2911 }
2912} /* field_substr */
2913/*--------------------------------------------------------------------------*/
2914/*                   field_indent                                           */
2915/*--------------------------------------------------------------------------*/
2916#if CICPP
2917void  FMTSTRU :: field_indent(int *ind1,
2918                              int *ind2)
2919#else /* CICPP */
2920#if ANSI
2921void  field_indent(int *ind1,
2922                   int *ind2)
2923#else /*ANSI*/
2924void  field_indent(ind1,ind2)
2925int *ind1;
2926int *ind2;
2927#endif /*ANSI*/
2928#endif /* CICPP */
2929{
2930  *ind1=0;
2931  *ind2=0;
2932   if (sym == lparen){ /* indentation */
2933      *ind1=parse_int_number();
2934      if (sym == comma) {
2935          *ind2=parse_int_number();
2936      }
2937      if (sym != rparen) erro (7);
2938        else  getsymbol();
2939   } /*lparen */
2940}
2941/*--------------------------------------------------------------------------*/
2942/*                   field_fmt                                              */
2943/*--------------------------------------------------------------------------*/
2944#if CICPP
2945int FMTSTRU :: field_fmt (void)
2946#else /* CICPP */
2947int field_fmt ()
2948#endif /* CICPP */
2949{
2950 int find = 0;
2951 /* local variables */
2952 int tag,ind1,ind2,off,len,low,upp;
2953 char subfield;
2954 int tem_occs;  /*A08*/
2955 tag=0;
2956 subfield=' ';
2957 off= -1;
2958 len= -1;
2959 if (sym == vsym || sym == isym || sym ==usym){
2960   field_fmt_sym=sym;
2961   tag = field_tag();              /*A08*/
2962   tem_occs = field_occs(&low,&upp);
2963   find = subfield_id(&subfield);  /*A08*/
2964      /*So permite indexacao se ainda nao foi analizada */
2965   if (tem_occs !=1 ) field_occs(&low,&upp);  /*A08*/
2966   field_substr(&off,&len);
2967   field_indent(&ind1,&ind2);
2968   /* store field specification  in the field table */
2969   field_address=store_field_def(tag,subfield,ind1,ind2,off,len,low,upp);
2970 }
2971 return find;
2972} /* field_fmt */
2973/*--------------------------------------------------------------------------*/
2974/*                   mode_parameter                                         */
2975/*--------------------------------------------------------------------------*/
2976#if CICPP
2977int FMTSTRU :: mode_parameter (void)
2978#else /* CICPP */
2979int mode_parameter ()
2980#endif /* CICPP */
2981{
2982int find = 0;
2983instruction_code t;
2984switch (sym)
2985{
2986 case mplsym:
2987 case mpusym:
2988 case mhlsym:
2989 case mhusym:
2990 case mdlsym:
2991 case mdusym:
2992     t=sym_to_instruction[sym];
2993     find = 1;
2994     gen(-1,t,-1,p_nulo);
2995     getsymbol();
2996     break;
2997 }  /* switch */
2998return find;
2999} /* mode_parameter */
3000/*--------------------------------------------------------------------------*/
3001/*                   c_fmt                                                  */
3002/*--------------------------------------------------------------------------*/
3003#if CICPP
3004int FMTSTRU :: c_fmt (void)
3005#else /* CICPP */
3006int c_fmt ()
3007#endif /* CICPP */
3008{
3009int find = 0;
3010if (sym == esc_strsym){
3011  find = 1;
3012  /* acho que nao precisa */
3013  address=store_str_const(str);
3014  gen(-1,escape_seq,address,p_nulo);
3015  getsymbol();
3016 }
3017 else if (spacing_string())  find = 1;
3018        else if (mode_parameter()) find = 1;
3019return find;
3020}/* c_fmt */
3021/*--------------------------------------------------------------------------*/
3022/*                  get_ignore_space                                        */
3023/*--------------------------------------------------------------------------*/
3024#if CICPP
3025void FMTSTRU :: get_ignore_space (void)
3026#else /* CICPP */
3027void get_ignore_space ()
3028#endif /* CICPP */
3029{
3030 getsymbol();
3031} /* get_ignore_space */
3032/*--------------------------------------------------------------------------*/
3033/*                   rep_isis_fmt                                           */
3034/*--------------------------------------------------------------------------*/
3035#if CICPP
3036void FMTSTRU <