codice
From: RoWsRaIrTiEo (non_at_esist.eeee)
Date: 03/19/04
- Next message: RoWsRaIrTiEo : "Esempio"
- Previous message: ArturS: "desperately needed algorithm"
- Next in thread: RoWsRaIrTiEo : "Re: codice"
- Reply: RoWsRaIrTiEo : "Re: codice"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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;
}
- Next message: RoWsRaIrTiEo : "Esempio"
- Previous message: ArturS: "desperately needed algorithm"
- Next in thread: RoWsRaIrTiEo : "Re: codice"
- Reply: RoWsRaIrTiEo : "Re: codice"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|