/* * Fonctions d'acces aux fichiers * (c)1991 par Denis GOUNELLE */ #include "aroff.h" #include "pile.h" extern struct TeteListe TMac ; extern struct Macro *CurrentMacro ; extern struct String *CurrentString ; extern unsigned char OutputBuf[], Arg[] ; extern struct InputFile *CurrentInputFile ; extern long InputMode, OutputLen, TmpLineLen, ArgLen, Flg, EmptyToWrite ; /***********************************************************************/ static long GetFromMac() { register unsigned long c ; register struct Macro *m ; m = CurrentMacro ; if ( (m->m_NextL) && (m->m_NextC >= m->m_NextL->ml_Len) ) { m->m_NextC = 0 ; m->m_NextL = (struct MLine *)m->m_NextL->ml_Node.el_Suivant ; return( '\n' ) ; } if ( m->m_NextL ) { c = m->m_NextL->ml_Text[m->m_NextC] ; m->m_NextC++ ; return( c ) ; } return( EOF ) ; } /***********************************************************************/ long GetChar() { char *p ; struct InputFile *f ; register unsigned long c ; register struct Macro *m ; register struct String *s ; _restart: if ( InputMode & IM_EXMACRO ) { for (;;) { c = GetFromMac() ; if ( c != EOF ) return( c ) ; BCLR( Flg , F_TRAP ) ; InputMode = Pop( TE_INMODE , 1 ) ; if ( InputMode & IM_STRING ) { s = (struct String *)Pop( TE_STRING , 1 ) ; CurrentString = s ; } if (! (InputMode & IM_EXMACRO)) break ; m = (struct Macro *)Pop( TE_MACRO , 1 ) ; CurrentMacro = m ; if ( m->m_Flag & MF_TRAP ) BSET( Flg , F_TRAP ) ; if ( m->m_Flag & MF_WAIT ) { BCLR( m->m_Flag , MF_WAIT ) ; p = (char *)Pop( TE_OUTLINE , 1 ) ; c = Pop( TE_TOWRITE , 0 ) ; if ( c != -1 ) EmptyToWrite = c ; LigneSuiv( p ) ; free( p ) ; } } while (! (Flg & F_TRAP)) { p = (char *)Pop( TE_OUTLINE , 0 ) ; if ( (! p) || (p == (char *)-1) ) break ; c = Pop( TE_TOWRITE , 0 ) ; if ( c != -1 ) EmptyToWrite = c ; LigneSuiv( p ) ; free( p ) ; } if ( Flg & F_TRAP ) goto _restart ; BCLR( InputMode , IM_EXMACRO ) ; CurrentMacro = NULL ; } if ( InputMode & IM_STRING ) { s = CurrentString ; if ( s->s_pos >= s->s_len ) { free( s ) ; InputMode = Pop( TE_INMODE , 1 ) ; if ( InputMode & IM_STRING ) { s = (struct String *)Pop( TE_STRING , 1 ) ; CurrentString = s ; } else if ( InputMode & IM_EXMACRO ) { m = (struct Macro *)Pop( TE_MACRO , 1 ) ; CurrentMacro = m ; } goto _restart ; } c = s->s_val[s->s_pos] ; s->s_pos++ ; return( c ) ; } f = CurrentInputFile ; /* si fin du tampon, lit LGMAXBUF octets dans le fichier */ if ( f->if_NextC >= f->if_BufLen ) { if ( f->if_Flag & IFF_LOADED ) return( EOF ) ; f->if_NextC = 0 ; f->if_BufLen = read( f->if_Desc , f->if_Buf , LGMAXBUF ) ; if (f->if_BufLen == -1 ) Fatal( ERR_READ ) ; if (! f->if_BufLen) return( EOF ) ; } /* lecture normale */ c = f->if_Buf[f->if_NextC] ; f->if_NextC++ ; return( c ) ; } /***********************************************************************/ long PutChar( c ) unsigned char c ; { register struct MLine *l ; if ( InputMode & IM_RDMACRO ) { if ( c == '\n' ) CurrentMacro->m_NextL = NULL ; l = CurrentMacro->m_NextL ; if ( ! l ) { l = (struct MLine *)myalloc( sizeof(struct MLine) , 1 ) ; InsereQueue( &(CurrentMacro->m_Def) , l ) ; CurrentMacro->m_NextL = l ; CurrentMacro->m_NextC = 0 ; } if ( c == '\n' ) return( 0 ) ; if ( l->ml_Len >= LGMAXSTR ) Fatal( ERR_OVERFLOW ) ; l->ml_Text[l->ml_Len] = c ; l->ml_Len++ ; return( 0 ) ; } if ( InputMode & IM_RDARGS ) { if ( ArgLen >= LGMAXSTR ) Fatal( ERR_OVERFLOW ) ; Arg[ArgLen] = c ; ArgLen++ ; return( 0 ) ; } if ( OutputLen >= LGMAXBUF ) Fatal( ERR_OVERFLOW ) ; OutputBuf[OutputLen] = c ; OutputLen++ ; return( OutputLen > TmpLineLen ) ; } /***********************************************************************/ struct InputFile *NewFile( name ) char *name ; { long lg ; struct InputFile *f ; f = (struct InputFile *)myalloc( sizeof(struct InputFile) , 1 ) ; if (! strcmp( name , "-" )) { f->if_Desc = 0 ; f->if_Name = "stdin" ; BSET( f->if_Flag , IFF_STDIN ) ; } else { f->if_Name = (char *)myalloc( strlen(name)+1 ) ; strcpy( f->if_Name , name ) ; f->if_Desc = open( name , O_RDONLY ) ; } if ( f->if_Desc == -1 ) Fatal( ERR_OPEN ) ; /* charge le fichier en memoire */ if ( Flg & F_LOADED ) { lg = lseek( f->if_Desc , 0 , 2 ) ; if ( lg < 1 ) Fatal( ERR_EMPTY ) ; if ( lg == -1 ) Fatal( ERR_SEEK ) ; if ( lseek( f->if_Desc , 0 , 0 ) == -1 ) Fatal( ERR_SEEK ) ; f->if_Buf = (unsigned char *)myalloc( lg , 0 ) ; f->if_BufLen = lg ; if ( read( f->if_Desc , f->if_Buf , lg ) != lg ) Fatal( ERR_READ ) ; close( f->if_Desc ) ; BSET( f->if_Flag , IFF_LOADED ) ; } else f->if_Buf = (unsigned char *)myalloc( LGMAXBUF , 0 ) ; f->if_Line = 1 ; return( f ) ; } /**************************************************************************/ void CloseFile( f ) struct InputFile *f ; { if ( (f != NULL) && (f != (struct InputFile *)-1) && (f->if_Desc > 0) ) { if ( f->if_Buf ) free( f->if_Buf ) ; if ( f->if_Flag & (IFF_STDIN|IFF_LOADED) ) return ; close( f->if_Desc ) ; free( f->if_Name ) ; f->if_Desc = -1 ; } }