codice

From: RoWsRaIrTiEo (non_at_esist.eeee)
Date: 03/19/04


Date: Fri, 19 Mar 2004 18:43:43 GMT


/* NOME DEL FILE: n_asm.c */
/*
   Questo programma ha un diverso tipo di 'getword'
   serve come preprocessore di macro per file .asm
   il suo proposito e' *non abolire*
   le micro-istruzioni dell'allassembly pur trovando
   un modo per *evidenziare* i loop e gli if.

   / o /* sono commenti
   {, }, sono sostituite *con niente* stessa
   cosa (, ) [queste ultime solamente a inizio
   linea dopo eventuali spazi]
   e potrebbero essere usate solo nell'intento di
   *evidenziare* i *loop* e gli *if* rispettivamente.

   Stessa cosa per i simboli '#' e per il '*' che
   potrebbero essere usati per evidenziare i punti di
   uscita dei loop o degli if.

   Per permettere a piu' istruzioni di condividere la
   stessa linea i separatori ';' e '|' vengono usati
   e sostituiti da '\n' nella traduzione.

   Le macro sostituzioni sono evidenti nella funzione
   install_all() comunque l'assembly dovrebbe essere
   un sottoinsieme del linguaggio risultante
   Mi sono ispirato al linguaggio C.

 BUGS
   Non sono supportati
   1) I calcoli *su numeri* che potrebbe fare
      nasm prima della fase di traduzione esempio:
      mov eax, 89 & 99
      anche se "a = 89*9" o "mov eax, 77*7" con il *
      dovrebbe funzionare se il carattere che segue il
      * e' un numero.
   2) I commenti su line che iniziano (dopo eventuali
      spazi) con %
   3) Espressioni come a = b -7 non vengono
      correttamente tradotte poiche' il + o il - sono
      associati al 7; se si scrive una di queste:
      a=b- 7; a= b- 7; a = b - 7; a = b- 7; a=b - 7;
      tutto dovrebbe essere ok;
   4) Le definizioni di macro con l'opzione -l
      (senza tale opzione tutto sembra ok) meglio
      definire le macro usando solo l'assembly normale
      oppure non usare l'opzione -l nelle macro in
      un'altro file, importarlo e usare -l.
   5) Non ho fatto molte prove su testi e programmi
      ci saranno un sacco di errori.

   uso con nasmw:
> n_asm.exe -l file_in file_out.asm
> nasmw file_out.asm

   '-l' serve per visualizzare la linea dell'errore
   Senza l'opzione -l allora l'output e' non usa %line.
   e dovrebbe essere piu' sicuro.

   Declino ogni responsabilita' per qualsiasi danno
   che potrebbe arrecare questo programma e ogni
   garanzia che serva a qualche cosa; Il programma si
   intende libero (free) per l'uso e per il
   cambiamento.

   Oggi 19 Marzo 2004

   R o s a r i o P u l v i r e n t i

   PS. se qualcuno vede gli errori lo
   comunichi, nel NG, Grazie.

*/

#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>

#define R return
#define P printf
#define F for
#define W while
#define UC unsigned char

char *argomento; /* serve per assert_m */
char *nome_file;

char* estrai(char* nome)
{char *a=nome, *b;
 char c;
 if(nome==0) return 0;
 W(1)
   {b=a;
    W( (c=*a) && c!='\\' && c!='/' ) ++a;
    if(c==0) break;
    ++a;
   }
 R b;
}

#define assert_m(x, y) \
if(!(x)) do{ \
            fprintf(stderr, "ERRORE %s: %s\n", argomento, y );\
            allUscita( 0, 0, 0, 0); \
            assert(x); \
           }while(0)

void allUscita(int flag, FILE* f_in, FILE* f_out, char** ch);

int catstr(char* a, char* b, int i)
{char *h=a;
 int k;

 if(i<=0 || a==NULL || b==NULL)
     {
      i=0;
      goto lab;
     }
 W(*h!='\0') ++h;
 k = h-a;
 i = i>k ? i-k: 0;
 W(i!=0)
    {*h++=*b++;
     if(*b=='\0') break;
     --i;
    }
 *h='\0';
 lab:
 assert_m(i!=0, "catstr: Stringa troppo lunga o argomenti nulli");
 R h-a;
}

#define HASHSIZE 307

struct nlist{
 struct nlist* next;
 char* name;
 char* defn;
};

static struct nlist* hashtab[HASHSIZE];

/*hash: calcola il valore di hashing della stringa s*/
unsigned hash(char* s)
{unsigned hashval;

 if(s==NULL) R 0;
 F(hashval=0;*s!='\0';++s)
     hashval=*s+31*hashval;
 R hashval%HASHSIZE;
}

/*lookup: cerca s in hashtab*/
struct nlist* lookup(char* s)
{struct nlist *np;

 if(s==NULL) R NULL;
 F(np=hashtab[hash(s)];np!=NULL;np=np->next)
   if(strcmp(s,np->name)==0)
                  R np; /* trovata */
 R NULL; /*non trovata*/
}

/* dupstr: fa una copia di s */
char* dupstr(char* s)
{char *p;

 if(s==NULL) return NULL;
 p=malloc(strlen(s)+1); /* +1 per '\0' */
 if(p!=NULL)
    strcpy( p, s );
 return p;
}

void free_node(struct nlist* a)
{if(a==NULL) R;
 if(a->name!=NULL) free(a->name);
 if(a->defn!=NULL) free(a->defn);
 free(a);
}

void free_tab(void)
{unsigned i;
 struct nlist *p, *q;

 F(i=0;i<HASHSIZE;++i)
   F(p=hashtab[i];p!=NULL; p=q)
       {q=p->next;
        free_node(p);
       }
}

/*undef: rimuove un nodo dalla tabella*/
int undef(char* name)
{struct nlist *pp, *p;
 unsigned hsv;

 if(name==NULL) R -1;
 hsv=hash(name);
 F(p=hashtab[hsv], pp=NULL;p!=NULL;pp=p, p=p->next)
   if(strcmp(name,p->name)==0)
         {if(pp==NULL)
                hashtab[hsv]=p->next; /*il primo */
          else pp->next=p->next;
          free_node(p);
          R 0;
         }
 R 1;
}

/*instal: inserisce il nome (name, defn) in hashtab*/
struct nlist* install(char* name, char* defn)
{struct nlist *np;
 unsigned hashval;

 if((np=lookup(name))==NULL) /*non trovata*/
  {np=malloc(sizeof(*np));
   if(np==NULL) R NULL;
   if((np->name=dupstr(name))==NULL)
              {free(np);
               R NULL;
              }
   if((np->defn=dupstr(defn))==NULL)
              {free(np->name);
               free(np);
               R NULL;
              }
   hashval=hash(name);
   np->next=hashtab[hashval];
   hashtab[hashval]=np;/*mette il nuovo nodo davanti a tutti*/
  }
 else
     {free(np->defn); /*annulla il precedente defn P*/
      np->defn=NULL;
      if((np->defn=dupstr(defn))==NULL)
              {undef(name);
               R NULL;
              }
     }
 return np;
}

void installl(char* name, char* defn)
{struct nlist *np;

 assert_m(name!=NULL && defn!=NULL, "di memoria");

 np=install(name, defn);
 assert_m(np!=NULL, "di memoria");
}

int is_punct(int c)
{
 if( c=='<' || c=='>' || c=='+' || c=='-' || c=='&' ||
     c=='^' || c=='!' || c=='=' || c=='?' ||
     c=='|' || c=='(' ||c==')' ) R 1;
 R 0;
}

char* gword(char* buf, char** c, int cont)
{char *b=buf, *a;
 int ip;
 
 a="gword: Buffers nulli o argomenti errati";
label:
 assert_m(buf!=NULL && c!=NULL && cont>0, a);
 a=*c;
 W( *a!=0 && isspace(*a))
             ++a;
 ip= is_punct(*a) || *a=='[' ? 1: 0;
 if(*a && --cont>0)
   F(*b++=*a++; --cont>0 && *a!=0; *b++=*a++)
      {
       if(isspace(*a)) break;
       if( ip && (!is_punct(*a) || (*a=='|' && a[1]!='=')) )
                         break;
       if( !ip && !isalnum(*a) && *a!='_' )
                         break;
      }
 if(cont<=0)
   {a="gword: Linea troppo lunga"; goto label;}
 *b=0; *c=a;
 R buf;
}

/* Nota che non ritorna s ma ritorna NULL o un puntatore
   all'ultimo carattere
                                                        */
char* fgets_p(char* s, size_t n, FILE* iop)
{int c;
 char *cs=s;
 int getch(FILE* pnt);
 void ungetch(char c);

 assert_m( s!=0 && iop!=0 && n>0, "fgets: argomenti errati" );
 
 W( --n>0 && (c=getch(iop)) != EOF )
             if( (*cs++=c) == '\n') break;
           /* P("c==%d cs-s=%d \n", (int) c, (int) (cs-s) ); */
 if(c!='\n' && c!=EOF)
     {F( --cs; s!=cs && *cs!=';' && !(*cs=='|' && cs[1]!='=') ; --cs)
             ungetch(*cs);
      assert_m(cs!=s, "fgets: linea troppo lunga");
                    /* linea piu' lunga di un token */
      ++cs;
     }
 *cs='\0';

 return ( c==EOF && cs==s ) ? NULL : --cs;
}

int macro_s(char* bufr, int cont, char* buf, char** t_buf, int
num)
{char *c, *a=buf, *b=bufr, fqt[(sizeof(int)*CHAR_BIT+2)/3+1];
 int i=0, led=0, led1=1, k=7;
 
 c="macro_s: Argomenti errati";
label:
 assert_m(bufr!=NULL&& buf!=NULL&& t_buf!=NULL&& cont>0&& num>i &&
k>=0, c);

 W( *a!=0 && cont>0 )
       {W( *a!=0 && isspace(*a) ) ++a;

        if(is_punct(*a)) led=1;

        W( *a!=0 && cont>0 && is_punct(*a) &&
           !( (*a=='+'||*a=='-') && isdigit(a[1]) )
         ) /* in +8 -3 il + o il - non sono punti */
                 {--cont; *bufr++ = *a++;
                  if(led1) {if(a>buf+2 && isspace(a[-2]) )
                                  a[-2]=0;
                            else a[-1]=0;
                            led1=0;
                           }
                 }
        led1=1;
        W( *a!=0 && isspace(*a) ) ++a;

        if(led==1 && cont>0 )
             {--cont; *bufr++=' '; led=0;}

        if( *a!=0 && !isspace(*a) && cont>0 &&
              ( !is_punct(*a) || ( (*a=='+' || *a=='-') &&
isdigit(a[1]) )
              )
          )
                   {--cont;
                    *bufr++ = '#';
                    if( cont>0 )
                        k=sprintf( fqt, "%u", ++i);
                    if(k <= 0 || cont<=0) break;
                    if( k<cont )
                       {c=fqt;
                        W(*c!=0 && cont>0 )
                             {--cont ;
                              *bufr++ = *c++;
                             }
                       }
                    else {cont=0; break; }

                    if(i>num) break;
                    else t_buf[i]=a;
                          
                    W( (*a!=0 && !is_punct(*a)) || *a=='+' || *a=='-'
)
                            {if(*a=='\'')
                                  W(*++a!=0 && *a!='\'' );
                             else if(*a=='\"')
                                  W(*++a!=0 && *a!='\"');
                             else if(*a=='[' )
                                  W(*a!=0 && *a!=']' ) ++a;
                             if( *a=='+' || *a=='-' )
                                       {if( isdigit( a[1] ) )
                                                  ++a;
                                        else break;
                                       }
                             if(*a!='\0') ++a;
                            }
                    *bufr++=' ';
                   }
       }
 if(!(cont>0 && num>i && k>=0))
     { c="macro_s: Troppe parole o linea troppo lunga"; goto label;}
 if( bufr>b+1 && isspace(bufr[-1]) ) bufr[-1]='\0';
 else *bufr='\0';
 t_buf[++i]=NULL;
 R bufr-b;
}

/* #1 + #2 = #3 -> #3 + #2 = #1 */
int macro_sinv(char* wor, int dim, char* bufr, char* buf, char**
ch, int num)
{char *a=bufr, *w=wor, *c;
 int i=0;
 
 c="macro_sinv: argomenti errati o nulli";
 label:
 assert_m( wor!=0 && buf!=0 && bufr!=0 && ch!=0 && dim>0, c );
 W( dim>0 )
  {W(*a!=0 && *a!='#' && dim>0)
          { *w++=*a++; --dim;} /* #4 ## #r #EOL */
   if( *a=='#' && dim>0 )
      {if( isdigit(a[1]) )
            {i=atoi(++a);
             W(isdigit(*a)) ++a;
             if(i>=num) break;
             c=ch[i];
             W(*c!=0 && dim>0 )
                 {*w++=*c++; --dim;}
            }
       else {*w++=*a++; --dim;}
      }
    if(*a==0) break;
   }
 *w=0;
 if(i>=num || dim<=0)
     { dim=0; c="Linea troppo lunga o troppe parole"; goto label; }
 R w-wor;
}

int get_token(char** org, char** end)
{char *endd, k, *b, m, led_2=0, led_1=0;
 assert_m( end!=NULL, "inserimento di un null come stringa" );
 *org = endd = *end;
 F( ; (k=*endd)!='\0' ; endd++ )
     {
      if(k=='\'' && led_2==0 ) led_1= led_1==0 ? 1: 0;
      if(k=='\"' && led_1==0 ) led_2= led_2==0 ? 1: 0;
      if( k=='\n' )
              break;
      else if( k==':' && (isspace(endd[1]) || endd[1]=='\0')
                       && led_1==0 && led_2==0
              ) break;
     }
 if(k==':') ++endd;
 if(*endd!='\0')
       {*endd='\0'; *end=++endd;}
 else *end=endd;
 if(k=='\0' && **org!='\0' ) k='\n';
 /* P(" *end - *org=%d ", (int) (*end - *org)); */
 R (int) k;
}

/* word, buffer, b devono avere dimensione bsize */
int
micro_s(char* b, int bsize, char* word, char** comm, char*
buffer)
{char c, inq=0, *h, m, *a=b, *e, led, zen=0;
 struct nlist *np;
 
 e="micro_s: argomenti nulli o errati";
 la:
 assert_m( b && word && bsize>0, e );
 *comm=0; led=1;
 F( ; (c=*word)!='\0' && bsize>0; ++word)
      {if(isspace(c)) { *b++=c; --bsize; continue; }
       else if(c==';' || (c=='|' && word[1]!='=' ) )
         {h=word; zen=1;
          W((m=*h)!='\0')
              {if(!(isspace(m) && m!='\n') && m!=';' && m!='|' )
                   break; /* m=' ' => isspace(' ') && ' '!='\n' VERA
*/
               ++h;
              }
          if(*h!='/' || (*h=='%' && !isdigit(h[1])) )
                   {*b++='\n'; --bsize;}
          if (*h=='\0') break ;
          else if(*h=='\n' ) word=h ;
          else word=--h;
          continue;
         }
       else if(c=='/') /* %, / commenti */
                 { *b++='\n'; --bsize; *comm=word; break; }
       else if(c=='%' && !isdigit(word[1]))
                 { *b++='\n'; --bsize; *comm=word; break; }
       else if( led && (c=='s' || c=='S')
       && ( !strncmp(word, "SECTION", 7) || !strncmp(word, "section",
7) )
              ) { *b++='\n'; --bsize;
                  *comm=word; break;
                }
       else if(c=='\'')
            {*b++=c; --bsize; ++word;
             F(h=word; (m=*h)!='\0' && m!='\'' && bsize>0 ; ++h)
                   {*b++=*h; --bsize;}
             if(m=='\0' || bsize<=0) break;
             else {*b++=m; --bsize; word=h; continue; }
            }
       else if(c=='\"')
            {*b++=c; --bsize; ++word;
             F(h=word; (m=*h)!='\0' && m!='\"' && bsize>0 ; ++h)
                   {*b++=*h; --bsize;}
             if(m=='\0' || bsize<=0) break;
             else {*b++=m; --bsize; word=h; continue; }
            } /* "#" e "*" ->"" */
       else if(c=='#' || c=='{' || c=='}' ||
                (led && c==')') || (led && c=='(') || /* 1mo carattere
( o ) */
                  ( c=='*' && inq==0 && !isdigit(word[1]) ) /*
elimina il carattere */
              ) continue;
       else {
             led=0;
             if(c=='[') inq=1;
             else if(c==']') inq=0;
             h=word;
             gword(buffer, &h, bsize);
             if( !(is_punct(c) && inq==1) && (np=lookup(buffer))!=NULL
)
                   F(e=np->defn; *e && bsize>0 ; )
                             {*b++=*e++; --bsize;}
             else F(e=buffer ; *e && bsize>0 ; )
                             {*b++=*e++; --bsize;}
             if(word!=h) word=--h;
            }
      }
 if(bsize<=0) {e="Linea troppo lunga"; goto la; }
 *b='\0';
 if(zen==0) *buffer=0; /* salvo il fatto che trovo ; e | */
 else {*buffer=1; buffer[1]=0;}
 return b-a;
}

void install_all(void)
{installl( "a" , "eax"); installl( "b" , "ebx");
 installl( "c" , "ecx"); installl( "d" , "edx");
 installl( "e" , "esi"); installl( "i" , "edi");
 installl( "#1 = #2" , "mov #1, #2");
 installl( "#1 += #2", "add #1, #2");
 installl( "#1 -= #2", "sub #1, #2");
 installl( "#1 ()" , "call #1");
 installl( "w2", "dword"); installl( "ww", "word");
 installl( "bb", "byte"); installl( "w4", "qword");

 installl( "#1 <<= #2" , "shl #1, #2");
 installl( "#1 >>= #2" , "shr #1, #2");
 installl( "#1 <<<= #2" , "rcl #1, #2");
 installl( "#1 >>>= #2" , "rcr #1, #2");
 installl( "#1 && #2" , "test #1, #2");
 installl( "#1 &&= #2" , "lea #1, #2");
 installl( "#1 &= #2" , "and #1, #2");
 installl( "#1 |= #2" , "or #1, #2");
 installl( "#1 ^= #2" , "xor #1, #2");
 installl( "#1 << #2" , "cmp #1, #2");
  
 installl( "< #1" , "push #1");
 installl( "> #1" , "pop #1");
 installl( "< #1 < #2" , "push #1 \npush #2 ");
 installl( "> #1 > #2" , "pop #1 \npop #2 ");
 installl( "< #1 < #2 < #3" , "push #1 \npush #2 \npush #3 ");
 installl( "> #1 > #2 > #3" , "pop #1 \npop #2 \npop #3 ");
 installl( "< #1 < #2 < #3 < #4", "push #1 \npush #2 \npush #3
\npush #4");
 installl( "> #1 > #2 > #3 > #4", "pop #1 \npop #2 \npop #3
\npop #4");
 installl( "< #1 < #2 < #3 < #4 < #5" ,
       "push #1 \npush #2 \npush #3 \npush #4 \npush #5");
 installl( "> #1 > #2 > #3 > #4 > #5" ,
       "pop #1 \npop #2 \npop #3 \npop #4 \npop #5");
 installl( "< #1 < #2 < #3 < #4 < #5 < #6" ,
       "push #1 \npush #2 \npush #3 \npush #4 \npush #5 \npush
#6");
 installl( "> #1 > #2 > #3 > #4 > #5 > #6" ,
       "pop #1 \npop #2 \npop #3 \npop #4 \npop #5 \npop
#6");
 installl( "< #1 < #2 < #3 < #4 < #5 < #6 < %7" ,
    "push #1 \npush #2 \npush #3 \npush #4 \npush #5 \npush #6
\npush #7");
 installl( "> %1 > #2 > #3 > #4 > #5 > %6 > %7" ,
    "pop #1 \npop #2 \npop #3 \npop #4 \npop #5 \npop #6
\npop #7");
 
 installl( "++" , "inc ");
 installl( "--" , "dec "); installl( "div" , "div ");
 
 installl( "#1 <> #2", "cmp #1, #2 ");
 installl( "#1 < #2 ? #3" , "cmp #1, #2 \njb #3 ");
 installl( "#1 > #2 ? #3" , "cmp #1, #2 \nja #3 ");
 installl( "#1 <= #2 ? #3", "cmp #1, #2 \njbe #3 ");
 installl( "#1 >= #2 ? #3", "cmp #1, #2 \njae #3 ");
 installl( "#1 == #2 ? #3", "cmp #1, #2 \nje #3 ");
 installl( "#1 != #2 ? #3", "cmp #1, #2 \njne #3 ");
 installl( "#1 = #2 + #3", "mov #1, #2 \nadd #1, #3 ");
 installl( "#1 = #2 - #3", "mov #1, #2 \nsub #1, #3 ");
                     /* label: istruzione = istruzione \0 commento
*/
}

#define MAXW 2048 /* Massima lunghezza linea trattabile */
#define MAXP 512 /* Massimo numero di parole per linea */

int main(int x, char** a)
{int c, linea, led;
 char word[MAXW], **ch, *in, *out, *nl;
 struct nlist *np;
 FILE *f_in, *f_out;

 if(x!=0 && a!=0 && a[0]!=0) argomento=a[0]; /* per assert_m */
 else argomento="prog";
 
 if( !(x==3) && !( x==4 && a[1][0]=='-' && a[1][1]=='l' ) )
  {P("USO:\n>nome_prog [-l] nome_file_in nome_file_out\n"); R
0;}
 if(x==4) { in=a[2]; out=a[3]; led=1; }
 else { in=a[1]; out=a[2]; led=0; }

 nome_file=estrai(in);

 if( (ch=malloc(MAXP * sizeof *ch) )== NULL)
        { P("Scarsa memoria! Esco\n"); R 0; }

 if(strcmp(in, "stdin")!=0)
   {if((f_in=fopen(in,"r"))==NULL)
      {printf("\n ERRORE, impossibile leggere il file %s\n", a[1]);
       free(ch);
       return 0;
      }
   }
 else f_in=stdin;

 if(strcmp(out, "stdout")!=0)
   {if((f_out=fopen(out,"w"))==NULL)
      {printf("\n ERRORE, impossibile scrivere il file %s\n", a[2]);
       fclose(f_in); free(ch);
       return 0;
      }
   }
 else f_out=stdout;

 allUscita(1, f_in, f_out, ch); install_all();
 linea=1;
 while( (nl=fgets_p(word, sizeof word, f_in)) != NULL )
    {char buf[MAXW], bufr[MAXW], word1[MAXW], *b, *bf, *comm, *u, *v,
*h, za;
     int i, j, t, alias_nl;
 
     micro_s(buf, MAXW, word, &comm, bufr);

     b=buf; bf=NULL; j=0;
     W( ( i=get_token(&bf, &b) ) != '\0')
        {char fmt[7+11+32+10];

         alias_nl= *bufr!=0 ? 1: 0;
         macro_s(bufr, sizeof bufr, bf, ch, MAXP);

         if((np=lookup(bufr))!=NULL)
                  strncpy(bufr, np->defn, MAXW);
          if(led && linea<10000000 &&
             (np!=0 || alias_nl!=0 ) /*macro_s o micro_s cambiano
qualcosa*/
           ) {t = sprintf(fmt, "%%line %u %.30s\n", linea-1,
nome_file); }
         else if(linea>=10000000)
             { assert_m(linea>=10000000, "File troppo lungo" ); }
             /* Per la macro assert_m gli if *non* sono sicuri */
         else { *fmt='\0'; t=0; }

         if( i!=':' && ( comm==NULL || *bufr!='\0') )
                {t += catstr(fmt, " ", MAXW-t); }
 
         label:
         if(t>=MAXW) P("Lunghezza linea attuale> t = %d\n", t );
         assert_m(MAXW>t, "Linea troppo lunga");
         macro_sinv(word1, (sizeof word1)-t, bufr, bf, ch, MAXP);

         v=word1; h=bufr;
         W(1)
           {u = fmt;
            W( ++t<MAXW && (*h++=*u++) );
            --h; --t;
            W( ++t<MAXW && ( za=(*h++=*v++) ) && za!='\n');
            if( za!='\n' || t>=MAXW )
                 {--h; *h++='\n'; *h='\0'; break;}
           }
         if(t>= MAXW) goto label;
         if( !(j==0 && comm!=NULL) )
                    fputs(bufr, f_out);
         else /* commenti /, %, section */
              {--h; --t;
               u = *comm=='/' && *bufr!=0 ? " ;" : /*
commento dopo un comando */
                   *comm=='/' && *bufr==0 ? ";" : /*
commento in inizio linea */
                   *comm=='%' ? "%" : ""; /* % o
altrimenti */
               W( ++t<MAXW && (*h++=*u++) );
               --h; /* se t<MAXW --h->'\0' */
               u= *comm=='%'||(*comm=='/' && comm[1]!='*') ? comm+1 :
                  *comm=='/' && comm[1]=='*' ? comm+2 :
comm;
               W( ++t<MAXW && (*h++=*u++) );
               if(t>= MAXW) goto label;
               fputs(bufr, f_out);
              }
         ++j; /* j=0 allora metto il commento altrimenti niente */
        }
     if( *nl=='\n' ) ++linea;
    }
fine:
 fclose(f_in);
 fclose(f_out);
 free_tab();
 free(ch);
 R 0;
}

void allUscita(int flag, FILE* f_in, FILE* f_out, char** ch)
{static FILE *f_inn=0, *f_outt=0;
 static char **chh=0;
 if(flag==1) /* Aggiorna */
   {f_inn=f_in; f_outt=f_out; chh=ch;}
 else {free(chh);
       if(f_inn!=0 ) fclose(f_inn);
       if(f_outt!=0) fclose(f_outt);
       free_tab();
      }
}

#define BUFSIZE 128

char buf[BUFSIZE];
int bufp= 0;

int getch(FILE* pnt)
{static int led = EOF+1;
 R (bufp>0) ? buf[--bufp] :
     led!=EOF ? led=fgetc(pnt) : EOF;
}

void ungetch(char c)
{if( bufp >= BUFSIZE )
      {assert_m(bufp<BUFSIZE, "ungetch: troppi caratteri");}
 else buf[bufp++]=c;
}



Relevant Pages