/* * Programme principal * (c)1991 par Denis GOUNELLE * * Usage : aroff [-wstack] [-l] file * L'option -w permet d'augmenter la taille de la pile interne (256 par defaut) * L'option -l provoque le chargement du fichier en mémoire avant traitement * Si "file" est "-", l'entree standard est utilisee */ #include "aroff.h" #include "pile.h" static char PourVersion[] = "$VER: ARoff 1.12 (29.11.91)" ; char *ARoff_Version = "ARoff v1.12 (c)1991 by Denis GOUNELLE" , *ARoff_Usage = "Usage : aroff [-wstack] [-l] file" ; unsigned char cmd[LGMAXSTR+1] , Arg[LGMAXSTR+1] , TitleSeq[LGMAXSTR+1] , TabChar = DEF_TABCHR , OutputBuf[LGMAXBUF] ; /* tampon de sortie */ long OutputLen , /* nb de car. dans OutputBuf[] */ ArgLen , /* nb de car. dans Arg[] */ Flg , /* divers indicateurs */ *Pile = NULL , TaillePile = DEF_PILE , OutputLine = 1 , /* no ligne dans la page courante */ InputMode = IM_FILLING , /* indicateur pour lecture */ AdjustMode = AM_BOTH , /* type d'ajustement */ PageNumber = 0 , NewPageNumber = DEF_PAGNUM , LineLen = DEF_LINLEN , LineSpacing = DEF_LINSPC , TitleLen = DEF_TITLEN , PageLen = DEF_PAGLEN , PageOffset = DEF_PAGOFS , Indent = DEF_INDENT , TabLen = DEF_TABLEN , LineNumber = DEF_LINNUM , NumInterv = 1 , NumSpace = 1 , NumIndent = 0 , TotalIndent = 0 , TmpIndent = 0 , TmpCenter = 0 , TmpNoNum = 0 , EmptyToWrite= 0 , OldInputMode , CtrlLen , /* lg ajoutée par ".fs" */ TmpLineLen ; /* lg que doit avoir ligne courante */ struct TeteListe TReg, TStr, TMac, TTrp ; struct InputFile *CurrentInputFile = NULL ; struct Contexte *LastContext = NULL ; struct String *CurrentString = NULL ; struct Macro *CurrentMacro = NULL ; extern struct InputFile *NewFile() ; /***************************************************************************/ void Traite() { register long c, d ; unsigned char e, tmp[LGMAXSTR+1], aux[LGMAXSTR+1] ; Flg &= F_LOADED ; /* raz tous les bits sauf F_LOADED */ OutputLen = CtrlLen = 0 ; BSET( Flg , (F_WASNL|F_NOTI) ) ; for (;;) { BCLR( Flg , F_BREAKED ) ; TotalIndent = Indent + TmpIndent ; TmpLineLen = LineLen + CtrlLen - TotalIndent ; #ifdef AZTEC_C if ( SetSignal( 0L , 0L ) & SIGBREAKF_CTRL_C ) { fprintf( stderr , "\n***BREAK\n" ) ; Termine() ; } #endif /* * Boucle de lecture : * - on interprete \x * - on detecte et traite ".xx" en debut de ligne * - quand on sort, on doit traiter les "OutputLen" caracteres * places dans "OutputBuf[]" */ while ( (c = GetChar()) != EOF ) { if ( (c == '\n') && (! (InputMode & IM_EXMACRO)) ) { CurrentInputFile->if_Line++ ; SetReg( "il" , CurrentInputFile->if_Line , 0 ) ; } if ( Flg & F_WASBS ) { switch ( c ) { case 't' : c = '\t' ; break ; case ' ' : c = SC_FIXSPC ; break ; case '!' : if (! OutputLen) BSET( InputMode , IM_TRANSP ) ; for ( c = 0 ; c < TotalIndent ; c++ ) PutChar( (char)' ' ) ; case '\n' : c = SC_IGNORE ; break ; case 'n' : e = '\0' ; case '*' : d = GetChar() ; if ( (c == 'n') && ((d == '+') || (d == '-')) ) { e = d ; d = GetChar() ; } if ( d != '(' ) { if ( d == EOF ) Fatal( ERR_SYNTAX ) ; tmp[0] = d ; tmp[1] = '\0' ; } else if (! GetName( tmp )) Fatal( ERR_SYNTAX ) ; if ( c == 'n' ) { if ( e != '\0' ) IncReg( tmp , e ) ; GetReg( tmp , aux ) ; for ( d = 0 ; aux[d] ; d++ ) PutChar( aux[d] ) ; c = SC_EXPAND ; } else { GetStr( tmp , aux ) ; NewString( aux ) ; c = SC_IGNORE ; } break ; case '"' : BSET( Flg , F_SKIPEOL ) ; break ; case '$' : if ( ! CurrentMacro ) Fatal( ERR_SYNTAX ) ; c = GetChar() ; if ( (c == EOF) || (c < '1') || (c > '9') ) Fatal( ERR_SYNTAX ) ; c -= '1' ; if ( c < CurrentMacro->m_NbArg ) NewString( CurrentMacro->m_Arg[c] ) ; c = SC_IGNORE ; break ; default : break ; } BCLR( Flg , F_WASBS ) ; } else if ( (c == '\\') && (! (InputMode & (IM_TRANSP|IM_STRING))) ) { BSET( Flg , F_WASBS ) ; continue ; } if ( c == SC_EXPAND ) { BCLR( Flg , (F_WASNL|F_NEWPAR) ) ; if ( OutputLen > TmpLineLen ) break ; continue ; } if ( c == SC_IGNORE ) continue ; if ( (c == ' ') && (InputMode & IM_RDARGS) && (! ArgLen) ) continue ; if ( InputMode & IM_TRANSP ) { if ( PutChar( (unsigned char)c ) ) break ; if ( c == '\n' ) { BCLR( InputMode , IM_TRANSP ) ; OutputBuf[OutputLen] = '\0' ; OutputLen = 0 ; LigneSuiv( OutputBuf ) ; } continue ; } if ( Flg & F_SKIPEOL ) { if ( c != '\n' ) continue ; BCLR( Flg , F_SKIPEOL ) ; BSET( Flg , F_WASNL ) ; if (! (InputMode & IM_RDARGS)) continue ; } if ( (Flg & F_WASNL) && ((c == '.') || (c == '\'')) ) if ( InputMode & IM_RDMACRO ) { if ( (c = GetChar()) == EOF ) Fatal( ERR_SYNTAX ) ; if ( c == '.' ) { BSET( Flg , F_SKIPEOL ) ; EnleveQueue( &(CurrentMacro->m_Def) ) ; InputMode = OldInputMode ; CurrentMacro = NULL ; continue ; } BCLR( Flg , F_WASNL ) ; PutChar( '.' ) ; PutChar( (unsigned char)c ) ; continue ; } else { if (! GetName( cmd )) Fatal( ERR_SYNTAX ) ; if ( c == '\'' ) BSET( Flg , F_NOBRK ) ; BSET( InputMode , IM_RDARGS ) ; BCLR( Flg , F_WASNL ) ; ArgLen = 0 ; continue ; } if ( c == '\n' ) { if ( Flg & F_WASNL ) { if ( (! OutputLen) && (! (InputMode & IM_RDMACRO)) ) PutChar( ' ' ) ; else BSET( Flg , F_NEWPAR|F_BREAKED ) ; break ; } BSET( Flg , F_WASNL ) ; if ( InputMode & IM_RDARGS ) { BCLR( InputMode , IM_RDARGS ) ; if ( OutputLen ) SauveContexte( 0 ) ; BCLR( Flg , F_CONTINUE ) ; ExecCmd( cmd ) ; if ( Flg & F_CONTINUE ) continue ; break ; } if ( (InputMode & IM_FILLING) && (! TmpCenter) ) { if ( OutputLen ) c = ' ' ; else continue ; } else { BSET( Flg , F_BREAKED ) ; break ; } } else BCLR( Flg , F_WASNL ) ; if ( c == '\t' ) { c = TabLen * (1 + (OutputLen / TabLen)) ; while ( OutputLen < c ) if ( PutChar( TabChar ) ) break ; SauveContexte( 0 ) ; if ( OutputLen > TmpLineLen ) break ; continue ; } if ( InputMode & IM_RDARGS ) { PutChar( (unsigned char)c ) ; continue ; } if ( isspace( c ) && (! OutputLen) && (! (Flg & F_WASNL)) && (! (InputMode & IM_RDMACRO)) ) continue ; PutChar( (unsigned char)c ) ; if ( isspace( c ) ) SauveContexte( 0 ) ; BCLR( Flg , F_NEWPAR ) ; if ( OutputLen >= TmpLineLen ) break ; } if ( c == EOF ) BSET( Flg , F_BREAKED ) ; if ( OutputLen && (! (Flg & F_MACREQ)) ) { AdjustLine() ; if ( Flg & F_NEWPAR ) EmptyToWrite++ ; WriteLine() ; CtrlLen = 0 ; if ( TmpNoNum ) TmpNoNum-- ; if ( TmpCenter ) TmpCenter-- ; FlushStack( TE_CONTEXT ) ; BSET( Flg , F_SORTIE ) ; if ( LastContext ) free( LastContext ) ; LastContext = NULL ; } if ( InputMode & IM_RDMACRO ) PutChar( '\n' ) ; BCLR( Flg , F_MACREQ ) ; BSET( Flg , F_NOTI ) ; if ( c == EOF ) { CloseFile( CurrentInputFile ) ; CurrentInputFile = (struct InputFile *) Pop( TE_INFILE , 0 ) ; if ( (CurrentInputFile == NULL) || (CurrentInputFile == (struct InputFile *)-1) ) do_bp() ; else { c = 0 ; SetStr( "fn" , CurrentInputFile->if_Name ) ; } } while ( EmptyToWrite > 0 ) { EmptyToWrite-- ; LigneSuiv( "\n" ) ; BSET( Flg , F_SORTIE ) ; } if ( c == EOF ) break ; } } /***************************************************************************/ main( argc , argv ) int argc ; char *argv[] ; { char *nom ; long heure, k ; struct tm *ladate ; time ( &heure ) ; ladate = localtime( &heure ) ; /* examine les arguments */ Flg = 0 ; nom = NULL ; for ( k = 1 ; k < argc ; k++ ) if ( argv[k][0] == '-' ) switch( argv[k][1] ) { case 'w' : if (! isdigit( argv[k][2] )) Fatal( ERR_ARGS ) ; TaillePile = atoi( &(argv[k][2]) ) ; break ; case 'l' : if ( argv[k][2] != '\0' ) Fatal( ERR_ARGS ) ; BSET( Flg , F_LOADED ) ; break ; case '\0' : if ( nom != NULL ) Fatal( ERR_ARGS ) ; nom = argv[k] ; break ; default : Fatal( ERR_ARGS ) ; break ; } else { if ( nom != NULL ) Fatal( ERR_ARGS ) ; nom = argv[k] ; } if ( nom == NULL ) Fatal( ERR_ARGS ) ; /* cree la pile */ Pile = (long *)myalloc( (TaillePile << 3) , 0 ) ; /* initialise les registres */ InitListe( &TReg ) ; InitListe( &TStr ) ; InitListe( &TMac ) ; InitListe( &TTrp ) ; SetReg( "dw" , ladate->tm_wday + 1 , 0 ) ; SetReg( "dy" , ladate->tm_mday , 0 ) ; SetReg( "mo" , ladate->tm_mon + 1 , 0 ) ; SetReg( "yr" , ladate->tm_year , 0 ) ; SetReg( "hr" , ladate->tm_hour , 0 ) ; SetReg( "mn" , ladate->tm_min , 0 ) ; SetReg( "sc" , ladate->tm_sec , 0 ) ; SetReg( "ol" , LineNumber , 0 ) ; ChangePageNumber( NewPageNumber ) ; *TitleSeq = '\0' ; /* traite le fichier indique */ CurrentInputFile = NewFile( nom ) ; if ( CurrentInputFile ) { SetStr( "fn" , CurrentInputFile->if_Name ) ; SetReg( "il" , 1 , 0 ) ; Traite() ; } Termine() ; }