home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d5xx
/
d583
/
aroff.lha
/
ARoff
/
Sources
/
aroff.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-04
|
10KB
|
408 lines
/*
* 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() ;
}