root/tags/5.4.pre05/cifm2.c

Revision 1, 16.3 kB (checked in by heitor.barbieri, 3 years ago)

Criação do svn para Cisis.

Line 
1 /* file cifm2.c  */
2
3#include <stdio.h>
4#include <ctype.h>
5#include <string.h>
6
7#include "cisis.h"
8#include "cifmt.h"
9
10#if !CICPP
11static char fmtnumb[3*max_str_num+1];
12static  char tmpform[50];
13/*---------------------------------------------------------------------------*/
14extern char *nl_STR;
15extern int nl_LEN;
16#endif /* CICPP */
17
18
19#if CICPP
20int FMTSTRU :: fmt_CRLF (char *v,
21                         int   pos)
22#else /* CICPP */
23#if ANSI
24int fmt_CRLF (char *v,int   pos)
25#else /* ANSI */
26int fmt_CRLF (v,pos)
27char *v;
28int   pos;
29#endif /*ANSI*/
30#endif /* CICPP */
31{
32  char *p;
33
34  if (pos < nl_LEN) return false; /* HB */
35
36  p=(char *) &v[pos-nl_LEN];
37
38  if (strncmp(p,(char *)nl_STR,(size_t) nl_LEN)==0) return true;
39    else return false;
40
41}
42/*--------------------------- Macros ---------------------------------------*/
43/*--------------------------------------------------------------------------*/
44/*           Macro   concatena                                              */
45/*--------------------------------------------------------------------------*/
46
47#define concatena(out,iout,s,init,end)   \
48        for (k=init;k<=end;k++) \
49         {                       \
50         out[iout]=s[k];       \
51         iout++;                                                 \
52         }                                                           \
53          out[iout]=null_char;                                           \
54
55
56/*--------------------------------------------------------------------------*/
57/*               Out_put_str                                                */
58/*--------------------------------------------------------------------------*/
59/*-----------------------------------------------------------------*/
60#if CICPP
61void FMTSTRU :: out_put_str(char out[],
62                            LONGX maxsize,
63                            int *pout,
64                            LONGX lw,
65                            int id1,
66                            int id2,
67                            LONGX *ncc,
68                            char s[])
69#else /* CICPP */
70#if ANSI
71void out_put_str(char out[],
72                 LONGX maxsize,
73                 int *pout,
74                 LONGX lw,
75                 int id1,
76                 int id2,
77                 LONGX *ncc,
78                 char s[])
79#else /*ANSI*/
80void out_put_str(out,maxsize,pout,lw,id1,id2,ncc,s)
81char out[];
82LONGX maxsize;
83int *pout;
84LONGX lw;
85int id1;
86int id2;
87LONGX *ncc;
88char s[];
89#endif /*ANSI*/
90#endif /* CICPP */
91{
92int iout;
93LONGX nextcc;
94int first,len,offset,i;
95int gerou_ind,inicio,fim;
96int copia;
97int t,k;
98
99iout= *pout;
100nextcc= *ncc;
101
102first=true;
103
104len=strlen(s);
105inicio=0;
106fim =len-1;
107if (lw == 0) lw = LONGX_MAX;  /* HB - 20071127 */
108
109while (fim>=inicio)
110 {
111 len=fim-inicio+1;
112 gerou_ind=false;
113 offset=0;
114 if(nextcc >= lw )
115        {
116          new_line(out,iout,maxsize);
117          nextcc=1;
118         }
119 if(nextcc==1)  /* newline*/
120        {
121         if (first==true) offset=id1;
122                else  offset=id2;
123         /* repeat_space(out,iout,offset) */
124         memset(out+iout,' ',offset); iout+=offset;
125         nextcc=nextcc+offset;
126         gerou_ind=true;
127         }  /* nextcc=1*/
128 if ( (iout+len) <= maxsize )
129 {
130  if ( (lw-nextcc) >= len)
131    { /* cabe na linha vai concatenar*/
132     concatena(out,iout,s,inicio,fim);
133     nextcc=nextcc+(fim-inicio+1);
134     inicio=fim+1;
135    }
136    else
137    {
138    /* quebra string */
139    t=(int) (lw-nextcc);
140    /* Se o atual e o proximo Sao brancos precisa achar outra posicao
141       diferente de branco */
142     if (s[inicio+t]==' ' && s[inicio+t+1]==' ')
143       { while (s[inicio+t]== ' '&& t>=0 ) t--; }
144     if (t < 0) i=inicio+(int)(lw-nextcc);                      /* 01/06/93 */
145     else for (i=t+inicio; i > inicio && s[i] != ' '; i--) ;    /* 01/06/93 */
146     copia=true;
147     if(i==inicio)  /* nao consegui quebrar */
148      {
149       if(gerou_ind==true)
150        {
151         /* mesmo comecando numa linha nao cabe=> quebra de qq geito*/
152         i=t+inicio ;
153         copia=true;
154        }
155        else
156        {
157         /* fazer nova tentativa quebrando a linha */
158         new_line(out,iout,maxsize);
159         nextcc=1;
160         copia=false;
161        }  /* else */
162
163        }
164
165    if (copia==true)
166     {
167      concatena(out,iout,s,inicio,i);
168      new_line(out,iout,maxsize);
169      out[iout]=null_char;
170      first=false;
171      nextcc=1;
172          inicio=i+1;
173     } /* copia */
174   } /* lw */
175  } /* iout */
176  else
177  {
178   /* nao cabe na linha */
179
180   if (fmttrace) { /* AOT - 18/03/97 */
181   printf("\n There is no room in the buffer for the text - truncating");
182   printf("\n maxsize=%d,iout=%d,len=%d,fim=%d,inicio=%d",
183            maxsize,iout,len,fim,inicio);
184   }
185   fim=(int ) ( fim-(iout+len- maxsize));
186  }
187
188 }  /* while */
189 *pout=iout;
190 *ncc=nextcc;
191 }
192  /*out_put_str */
193
194
195
196/*--------------------------------------------------------------------------*/
197/*                   upcase_mode                                            */
198/*--------------------------------------------------------------------------*/
199#if CICPP
200void FMTSTRU :: upcase_mode(char *s)
201#else /* CICPP */
202#if ANSI
203void upcase_mode(char *s)
204#else /* ANSI */
205void upcase_mode(s)
206char *s;
207#endif /* ANSI */
208#endif /* CICPP */
209{
210    unsigned char *p;                                   /* AOT 01/04/92 */
211    for(p=(UCHR *)s; *p; p++) *p=isisuctab[*p];         /* AOT 01/04/92 */
212}
213
214
215/*------------------------------------------------------------------------*/
216/*                  sub_field_change                                      */
217/*------------------------------------------------------------------------*/
218#if CICPP
219char * FMTSTRU :: sub_field_change(char *q)
220#else /* CICPP */
221#if ANSI
222char *sub_field_change(char *q)
223#else /*ANSI*/
224char *sub_field_change(q)
225char *q;
226#endif /*ANSI*/
227#endif /* CICPP */
228{
229 char ch ;
230 char *ps,*q1,*p;
231 int end;
232
233p=q;
234ps=strchr(q,'^');
235
236if(ps==nulo) return q;
237
238end=false;
239/* the first occurrence is substituted by spaces skips the "^a" chars */
240if (ps == p) {                                  /* AOT 28/04/92 */
241*ps++=null_char;
242*ps++=' ';
243strcat(q,ps);
244}
245/* other occurrences of subfields area changed according to the following
246   rules:
247   ^a               subst. by ";"
248   ^b through ^i    subst. by ","
249   others                     "."
250*/
251
252while(end==false)
253 {
254 q1=strchr(ps,'^');
255 if(q1==nulo) end=true;
256  else
257    {
258     q1++;
259     ch=toupper(*q1); /* save the next character */
260     *q1=' '; /* the charcter is substituted by space */
261     q1--; /* the ^ is substituted by punctuation */
262     if(ch== 'A') {*q1=';' ;}
263       else { if (ch>='B' && ch <= 'I') {*q1=',' ;}
264                 else {*q1='.';}
265            }
266    }
267 }
268 return p;
269}
270
271/* Rotina: nunmber of lines
272   Nome rotina:numeber_of_lines;
273   Objetivo:Determinar quantas linhas de impressora/terminais foram geradas
274   Entrada: Pointer para uma string terminada por NULL.
275   Saida: retorna no nome da funcao a quantidade de linhas.
276   Algoritmo: Se a string tem tamanho zero, nao vai gerar nenhuma linha.
277              Caso contrario, pelo menos uma linha foi gerada.
278              Percorre de caractere em caractere verificando se aparece a
279              combinacao de caracteres LFCR. Para cada ocorrencia, incre-
280              menta o numero de linhas. Normalmente o numero de linhas
281              e equivalente ao total de crlf + 1 , com excecao do
282              crlf aparecer no final do string.
283*/
284#if CICPP
285LONGX FMTSTRU :: number_of_lines(char *p)
286#else /* CICPP */
287#if ANSI
288LONGX number_of_lines(char *p)
289#else /* ANSI */
290LONGX number_of_lines(p)
291char *p;
292#endif /* ANSI */
293#endif /* CICPP */
294{
295 int i,nl,k;
296 nl=0;
297 i=0;
298 k=strlen(p);
299 if(k!=0)
300  {
301    while (p[i]!=null_char)
302       {
303#if UNIX | WWWISIS
304         if (fmt_CRLF(p,i+1)) nl++;
305#else
306         if (i && fmt_CRLF(p,i+1)) nl++;
307#endif /*UNIX | WWWISIS*/
308         i++;
309        }
310#if COUNTLAST                                    /* aot - 14/08/90 */
311    /* se no fim da linha nao aparece crlf , entao conta mais uma linha */
312    if (!fmt_CRLF(p,k))nl++;
313#endif
314  }
315#if TRACESINDO
316  printf("\n---nl=%d\n",nl);
317#endif
318  return (nl);
319  }
320/*------------------------------------------------------------------------*/
321/*               find_numeric_string                                      */
322/*------------------------------------------------------------------------*/
323
324#if !CICPP
325#define max_numeric_string 12
326char strn[max_numeric_string+1];
327char *ptstr;
328#endif /* CICPP */
329
330#if CICPP
331char * FMTSTRU :: find_numeric_string(char v[],
332                                      int *p)
333#else /* CICPP */
334#if ANSI
335char *find_numeric_string(char v[],
336                          int *p)
337#else /*ANSI*/
338char *find_numeric_string(v,p)
339char v[];
340int *p;
341#endif /*ANSI*/
342#endif /* CICPP */
343{
344 int n,k,fim,ndec;
345 ptstr=strn;
346 n=0;
347 strn[n]=null_char;
348 k= *p;
349 fim=false;
350 /* posiciona no inicio de numero */
351 while  (! (v[k]==null_char || fim==true) ){
352   if (isdigit(v[k]) ) fim=true;
353     else if (v[k]=='-'||v[k]=='+'){
354            if (isdigit(v[k+1]) ) fim=true;
355            strn[n++]=v[k++];
356            strn[n]=null_char;
357          } else k++;
358 }
359 fim=false;
360 ndec=0;
361 while ( fim==false && v[k]!=null_char) {
362  if ( isdigit(v[k]) ||((v[k]=='.') && (ndec<1)) ){
363    if (v[k]=='.') ndec++;
364    if (n>=max_numeric_string){
365      printf("\n***** Number too LONGX - truncated to %d digits",n);
366      *p=k;
367      strn[n]=null_char;
368      return  ptstr ;
369    }
370
371    /* teste_limits(n,max_numeric_string);                             */
372    strn[n++]=v[k++];
373 }else fim=true;
374
375 } /* while */
376 if ( toupper(v[k])=='E') {
377     strn[n++]=v[k++];
378     if (v[k]!=null_char)
379       if (v[k]=='+' || v[k]=='-') strn[n++]=v[k++];
380     fim=false;
381     while (fim==false && v[k]!=null_char)
382      if (isdigit(v[k]))
383        strn[n++]=v[k++];
384      else fim=true;
385 }
386 strn[n]=null_char;
387 *p=k;
388 return (ptstr);
389}
390
391/*--------------------------------------------------------------------------*/
392/*                  fmt_float_numb                                         */
393/*--------------------------------------------------------------------------*/
394/* Objetivo: Transformar um numero real (float) em string na execucao da
395             funcao f.
396   Algoritmo: A Funcao f pode ser chamada de tres maneiras distintas:
397              a) f(valor);
398              b) f(valor,tam_minimo);
399              c) f(valor,tam_minimo,casas_decimais)
400              A formatacao consiste em criar, atraves da variavel tmpform e
401              da funcao sprintf,uma string com um formato que corresponda
402              a chamada atual da funcao. Depois isso a funcao sprintf e
403              usada novamente para realmente formatar o valor nesse formato
404              Foi convencionado que na chamada da funcao que  tam_minimo e/ou
405              casas_decimais = -1, significa omissao de parametro
406   O parametro leftfill contem o caracter 0 ou branco para preencher a
407   esquerda do numero
408*/
409#if CICPP
410char * FMTSTRU :: fmt_float_numb (float_x valor,
411                                  int min,
412                                  int dec,
413                                  char leftfill)
414#else /* CICPP */
415#if ANSI
416char *fmt_float_numb (float_x valor,
417                      int min,
418                      int dec,
419                      char leftfill)
420#else /*ANSI*/
421char *fmt_float_numb (valor,min,dec,leftfill)
422float_x valor;
423int min;
424int dec;
425char leftfill;
426#endif /*ANSI*/
427#endif /* CICPP */
428
429{
430  char v[2];
431  float_x ff;
432   /* Foi usada funcao f com os 3 parametros - A formatacao e' um
433    numero real com ponto decimal
434 */
435 /* Inicialmente fiz a formatacao errada:
436    Quando se deseja faze pad a esquerda com branco, no formato de
437    sprintf nao pode ter nada entre o '%' e o "numero".
438    Quando se deseja fazer pad com zero precisa ter  %0n
439    O vetor v serve para esse objetivo.
440 */
441 v[0]=leftfill;
442 v[1]='\0';
443 if (leftfill==' ')v[0]='\0';
444
445 ff=valor;
446 if (min > 3*max_str_num ) min=3*max_str_num;
447 if (dec-3 >3*max_str_num)dec=3*max_str_num-3;
448
449 if(min!= -1 && dec!= -1){
450#if 0 /* HB 20080901 - veja definicao de float_x */
451   sprintf(tmpform,"%c%s%d%c%d%c",'%',v,min,'.',dec,'f');
452   sprintf(fmtnumb,tmpform,(float )ff);
453#endif
454   sprintf(tmpform,"%c%s%d%c%d%c",'%',v,min,'.',dec,'lf');
455   sprintf(fmtnumb,tmpform,ff);
456 } else
457    /* Foi usada funcao f com 2 parametros (valor,minimo)
458       Neste caso a quantidade de casas decimais equivale ao
459       tamano minimo- - 4 ( os caracteres E+00)
460                       -1 ( o ponto decimal)
461                       -1 ( o sinal do numero)
462    */
463    if(min!= -1 && dec== -1){
464      dec=min-4-1-1;
465      if (dec<0)dec=0;
466      sprintf(tmpform,"%c%c%d%c%d%c",'%',leftfill,min,'.',dec,'E');
467      sprintf(fmtnumb,tmpform,(float )ff);
468   }
469  else {
470     /* Fomato com unico parametro. Neste caso o default usado e'
471        de 9 casas decimais e tamano  minimo de de 16 caracters
472     */
473     min=16;
474     dec=9;
475    sprintf(tmpform,"%c%s%d%c%d%c",'%',v,min,'.',dec+1,'E');
476     sprintf(fmtnumb,tmpform,(float )ff);
477  }
478  return (char *)fmtnumb;
479
480}
481
482
483
484/*--------------------------------------------------------------------------*/
485/*                  ch_add                                                  */
486/*--------------------------------------------------------------------------*/
487/* Objetivo: Transforma o enderecamento relativo gerado por instrucoes do
488             tipo JUMP em enderecos absolutos.
489   Algoritmo: Pesquisa nos campos de LABEL quais as intrucoes em que
490              aparece um label e constroi um vetor onde o indice corresponde
491              ao label e o conteudo contem o endereco da instrucao em que
492              aparece esse label. Suponha que o Programa a ser interpretado
493              contenha as instrucoes abaixo:
494
495                End Instr     Label       Instr      Add      Next
496                ---------     -----       -----      ----     ----
497                        1       -1        Begin       -1       2
498                        2                 Jumpt        1       3
499                        3                 Print_f     1000     4
500                        4        1        U_cond      2000     5
501             Para executar esse programa, o endereco apontado na instrucao
502             2 , (Add=1) indica que deve ser executada a instrucao numero 4.
503             Portanto o endereco (Add=1) devera ser substituido por (add=4)
504             Para esse Trecho o vetor de Rotulos devera ter os seguintes va-
505             lores:
506               R[0]= ...
507               R[1]= 4
508               Os outros dependem do resto do programa.
509             Esse vetor devera ser dinamico e ter tamanho igual ao numero de
510             instrucoes geradas+1.
511             (A posicao 0 nao tem informacao).
512             Todos os enderecos sao copiados para enderecamento dinamico para
513             facilitar o interpretador.
514*/
515
516#if CICPP
517void FMTSTRU :: fmt_chadd(l_code *pgm)
518#else /* CICPP */
519#if ANSI
520void fmt_chadd(l_code *pgm)
521#else /*ANSI*/
522void fmt_chadd(pgm)
523l_code *pgm;
524#endif /*ANSI*/
525#endif /* CICPP */
526{
527 int j;
528 l_code *t;
529 LONGX aux_add;
530 instruction_code  aux_instr;
531 LONGX *rotulos;
532 /* A cabeca de lista do programa gerado contem a quantidade de instrucoes
533    geradas.
534 */
535 j=(int ) pgm->info.lab+1;
536 if (fmttrace) printf("fmt_chadd - %d \n",j);                /* AOT 27/12/91 */
537 /* numero de instrucoes geradas */
538#if CICPP
539 try
540 { rotulos=(LONGX *) new char [j*sizeof(LONGX)]; }
541 catch (BAD_ALLOC)
542 { rotulos=(LONGX *)NULL; }
543#else /* CICPP */
544 rotulos=(LONGX *)ALLOC((ALLOPARM)j*sizeof(LONGX));            /* AOT 30/03/92 */
545#endif /* CICPP */
546
547 if(!rotulos) fatal("fmt_chadd/ALLOC");
548 memset(rotulos,0x00,j*sizeof(LONGX));                        /* AOT 27/12/91 */
549
550 /* constroi enderecos direto */
551 t=(l_code *)pgm->next;
552 for (;t!=nulo;)
553  {
554   t->m_add=t->info.add; /* copia todos os enderecos para endereco dinamico */
555   j= (label ) t->info.lab;
556   if (j>0)              /* se for label valido guarda o endereco */
557      {
558       rotulos[j]=(LONGX )t;
559      }
560   t=(l_code *)t->next;
561  }
562 /* Para as instrucoes que geram enderecos relativos, transforma em endereco
563    dinamico
564 */
565 t=(l_code *)pgm->next;
566 for (;t!=nulo;)
567  {
568   aux_instr=t->info.instr;
569   if ( aux_instr==jumpf ||                     /* date/etc nao entra aqui! */
570        aux_instr==jumpt || aux_instr==jump ||
571        aux_instr==breakins)
572      {
573       aux_add=t->info.add;
574       t->m_add=rotulos[(int )aux_add];
575      }
576   t=(l_code *)t->next;
577  }
578 if (fmttrace) printf("fmt_chadd - success \n");        /* AOT 27/12/91 */
579#if CICPP
580 delete [] (char *)rotulos;
581#else /* CICPP */
582 FREE(rotulos);
583#endif /* CICPP */
584}
585
Note: See TracBrowser for help on using the browser.