/* * Commandes nroff * (c)1991 par Denis GOUNELLE */ #include "aroff.h" #include "pile.h" extern unsigned char *TestString(), *TestNum() ; extern unsigned char Arg[], OutputBuf[], TabChar, *GetArg(), TitleSeq[] ; extern long ArgLen, OutputLen, AdjustMode, PageNumber, InputMode, LineLen, Indent, TitleLen, Flg, TmpIndent, PageOffset, PageLen, LineSpacing, TabLen, TmpCenter, LineNumber, NumInterv, NumSpace, NumIndent, TmpNoNum, OldInputMode, OutputLine, EmptyToWrite, FindTrp(), NewPageNumber, CtrlLen ; extern struct InputFile *CurrentInputFile, *NewFile() ; extern struct Macro *CurrentMacro ; extern struct TeteListe TMac ; extern struct Node *FindVar() ; static unsigned char tmp[LGMAXSTR+1], TrTab[LGMAXSTR+1] = "" ; static char *TableEsc[] = { "\033[22m" , /* b0 */ "\033[1m" , /* b1 */ "\033[23m" , /* i0 */ "\033[3m" , /* i1 */ "\033[24m" , /* u0 */ "\033[4m" , /* u1 */ "\033[0m" /* n */ } ; /***********************************************************************/ void do_br() { if ( Flg & F_NOBRK ) return ; if ( OutputLen ) { if ( AdjustMode != AM_BOTH ) AdjustLine() ; WriteLine() ; } } /***********************************************************************/ void do_tm() { if ( ArgLen > 0 ) { write( 2 , Arg , ArgLen ) ; write( 2 , "\n" , 1 ) ; } } /***********************************************************************/ void do_ab() { do_tm() ; Abort( 1 ) ; } /***********************************************************************/ void do_ad() { long oldmode ; unsigned char c ; c = Arg[0] ; oldmode = AdjustMode ; switch ( c ) { case 'c' : AdjustMode = AM_CENTER ; break ; case 'l' : AdjustMode = AM_LEFT ; break ; case 'r' : AdjustMode = AM_RIGHT ; break ; case 'b' : AdjustMode = AM_BOTH ; break ; case '\0' : AdjustMode = Pop( TE_ADJMOD , 0 ) ; if ( AdjustMode == -1 ) AdjustMode = AM_BOTH ; break ; default : Fatal( ERR_SYNTAX ) ; } Push( TE_ADJMOD , oldmode ) ; } /***********************************************************************/ void do_am() { struct Macro *m ; if ( InputMode & IM_EXMACRO ) Fatal( ERR_SYNTAX ) ; if ( ! ArgLen ) return ; m = (struct Macro *)FindVar( &TMac , Arg ) ; if ( ! m ) { SetMac( Arg ) ; m = CurrentMacro ; } m->m_NextL = NULL ; CurrentMacro = m ; OldInputMode = InputMode ; BCLR( InputMode , IM_FILLING ) ; BSET( InputMode , IM_RDMACRO ) ; } /***********************************************************************/ void do_as() { register long k ; register unsigned char *var, *val ; if ( ! ArgLen ) return ; /* isole le nom de la chaine */ var = Arg ; for ( k = 0 ; (Arg[k] != '\0') && (! isspace( Arg[k] )) ; k++ ) ; if ( Arg[k] == '\0' ) return ; Arg[k] = '\0' ; /* recupere la valeur */ for ( k++ ; isspace( Arg[k] ) ; k++ ) ; if ( Arg[k] == '\0' ) return ; if ( Arg[k] == '"' ) k++ ; val = &Arg[k] ; if ( *val == '\0' ) return ; /* fabrique la nouvelle valeur */ GetStr( var , tmp ) ; strcat( tmp , val ) ; SetStr( var , tmp ) ; } /***********************************************************************/ void do_bp() { do_br() ; if ( OutputLine > 1 ) EmptyToWrite += PageLen - OutputLine + 1 ; if ( isdigit( Arg[0] ) ) NewPageNumber = atoi( Arg ) ; if (! (Flg & F_SORTIE)) ChangePageNumber( NewPageNumber ) ; } /***********************************************************************/ void do_ce() { do_br() ; TmpCenter = ( isdigit( Arg[0] ) ) ? atoi( Arg ) : 1 ; } /***********************************************************************/ void do_de() { if ( InputMode & IM_EXMACRO ) Fatal( ERR_SYNTAX ) ; if ( ! ArgLen ) return ; SetMac( Arg ) ; OldInputMode = InputMode ; BCLR( InputMode , IM_FILLING ) ; BSET( InputMode , IM_RDMACRO ) ; } /***********************************************************************/ void do_ds() { register long k ; register unsigned char *var, *val ; if ( ! ArgLen ) return ; /* isole le nom de la chaine */ var = Arg ; for ( k = 0 ; (Arg[k] != '\0') && (! isspace( Arg[k] )) ; k++ ) ; if ( Arg[k] == '\0' ) return ; Arg[k] = '\0' ; /* recupere la valeur */ for ( k++ ; isspace( Arg[k] ) ; k++ ) ; if ( Arg[k] == '\0' ) return ; if ( Arg[k] == '"' ) k++ ; val = &Arg[k] ; if ( *val == '\0' ) return ; SetStr( var , val ) ; } /***********************************************************************/ void do_el() { if (! (Flg & F_WASIF)) Fatal( ERR_IFELSE ) ; if (! ArgLen) Fatal( ERR_SYNTAX ) ; if ( Flg & F_WASFALSE ) { sprintf( tmp , "%s\n" , Arg ) ; NewString( tmp ) ; } } /***********************************************************************/ void do_ex() { Abort( 1 ) ; } /***********************************************************************/ void do_fi() { do_br() ; BSET( InputMode , IM_FILLING ) ; } /***********************************************************************/ void do_fl( str ) unsigned char *str ; { register long k,l ; register unsigned char *p, *q ; k = strlen( str ) ; if ( k < 1 ) Fatal( ERR_WRITE ) ; for ( q = str ; *q ; q++ ) { if ( *q == SC_FIXSPC ) *q = ' ' ; for ( l = 0 ; TrTab[l] ; l += 2 ) /* do translation */ if ( *q == TrTab[l] ) { *q = TrTab[l+1] ; break ; } } write( 1 , str , k ) ; } /***********************************************************************/ void do_fs() { register long k ; register unsigned char *p, *q ; if ( ! ArgLen ) return ; for ( p = Arg ; *p ; p++ ) { switch ( *p ) { case 'b' : k = 0 ; break ; case 'i' : k = 2 ; break ; case 'u' : k = 4 ; break ; case 'n' : k = 6 ; break ; default : Fatal( ERR_SYNTAX ) ; break ; } if ( k != 6 ) { p++ ; if ( *p == '1' ) k++ ; else if ( *p != '0' ) Fatal( ERR_SYNTAX ) ; } for ( q = TableEsc[k] ; *q ; q++ ) { CtrlLen++ ; PutChar( *q ) ; } } BSET( Flg , F_CONTINUE ) ; } /***********************************************************************/ void do_if() { register unsigned char *p ; if (! ArgLen) Fatal( ERR_SYNTAX ) ; p = Arg ; BSET( Flg , F_WASIF ) ; BCLR( Flg , (F_IFNOT|F_WASFALSE) ) ; if ( *p == '!' ) { BSET( Flg , F_IFNOT ) ; p++ ; while ( isspace(*p) ) p++ ; } switch ( *p ) { case 'e' : if ( PageNumber & 1 ) BSET( Flg , F_WASFALSE ) ; p++ ; break ; case 'o' : if (! (PageNumber & 1)) BSET( Flg , F_WASFALSE ) ; p++ ; break ; case 'n' : p++ ; break ; case 't' : BSET( Flg , F_WASFALSE ) ; p++ ; break ; case '\'' : p = TestString( p ) ; break ; default : if (! isdigit(*p)) Fatal( ERR_SYNTAX ) ; p = TestNum( p ) ; break ; break ; } if ( Flg & F_IFNOT ) if ( Flg & F_WASFALSE ) BCLR( Flg , F_WASFALSE ) ; else BSET( Flg , F_WASFALSE ) ; while ( isspace(*p) ) p++ ; if (! *p) Fatal( ERR_SYNTAX ) ; sprintf( tmp , "%s\n\\\n" , p ) ; if (! (Flg & F_WASFALSE)) NewString( tmp ) ; } /***********************************************************************/ void do_in() { long oldval ; do_br() ; oldval = Indent ; if (! ChangeValue( &Indent )) Indent = Pop( TE_INDENT , 0 ) ; if ( Indent < 0 ) Indent = DEF_INDENT ; Push( TE_INDENT , oldval ) ; } /***********************************************************************/ void do_ll() { long oldval ; oldval = LineLen ; if (! ChangeValue( &LineLen )) LineLen = Pop( TE_LINLEN , 0 ) ; if ( LineLen < 0 ) LineLen = DEF_LINLEN ; Push( TE_LINLEN , oldval ) ; } /***********************************************************************/ void do_ls() { long oldval ; oldval = LineSpacing ; if (! (LineSpacing = atoi( Arg ))) LineSpacing = Pop( TE_LINSPC , 0 ) ; if ( LineSpacing < 1 ) LineSpacing = DEF_LINSPC ; Push( TE_LINSPC , oldval ) ; } /***********************************************************************/ void do_lt() { long oldval ; oldval = TitleLen ; if (! ChangeValue( &TitleLen )) TitleLen = Pop( TE_TITLEN , 0 ) ; if ( TitleLen < 0 ) TitleLen = DEF_TITLEN ; Push( TE_TITLEN , oldval ) ; } /***********************************************************************/ void do_na() { Push( TE_ADJMOD , AdjustMode ) ; AdjustMode = AM_LEFT ; } /***********************************************************************/ void do_ne() { register long k, l ; if ( ! ArgLen ) return ; k = OutputLine + (( isdigit( Arg[0] ) ) ? atoi( Arg ) : 1) - 1 ; if ( k > PageLen ) { _do_it: *Arg = '\0' ; ArgLen = 0 ; do_bp() ; return ; } for ( l = OutputLine ; l <= k ; l++ ) if ( FindTrp( l ) ) goto _do_it ; } /***********************************************************************/ void do_nf() { do_br() ; BCLR( InputMode , IM_FILLING ) ; } /***********************************************************************/ void do_nm() { unsigned char *p ; if (! ArgLen) { BCLR( Flg , F_NUMBER ) ; return ; } BSET( Flg , F_NUMBER ) ; ChangeValue( &LineNumber ) ; for ( p = Arg ; (*p != '\0') && (! isspace( *p )) ; p++ ) ; p = GetArg( p , &NumInterv ) ; if (! NumInterv) Fatal( ERR_SYNTAX ) ; p = GetArg( p , &NumSpace ) ; GetArg( p , &NumIndent ) ; } /***********************************************************************/ void do_nn() { TmpNoNum = ( isdigit( Arg[0] ) ) ? atoi( Arg ) : 1 ; } /***********************************************************************/ void do_nr() { register long k, val, inc ; register unsigned char *var ; if ( ! ArgLen ) return ; /* isole le nom du registre */ var = Arg ; for ( k = 0 ; (Arg[k] != '\0') && (! isspace( Arg[k] )) ; k++ ) ; if ( Arg[k] == '\0' ) return ; Arg[k] = '\0' ; /* recupere la valeur initiale */ for ( k++ ; isspace( Arg[k] ) ; k++ ) ; val = atoi( &Arg[k] ) ; /* recupere l'increment */ while ( isdigit( Arg[k] ) ) k++ ; while ( isspace( Arg[k] ) ) k++ ; inc = atoi( &Arg[k] ) ; SetReg( var , val , inc ) ; } /***********************************************************************/ void do_pl() { if (! ChangeValue( &PageLen )) PageLen = DEF_PAGLEN ; UpdateTrp() ; } /***********************************************************************/ void do_pm() { register struct Macro *m ; register struct MLine *l ; m = (struct Macro *) (( ArgLen ) ? FindVar( &TMac , Arg ) : NULL) ; if ( m ) for ( l = (struct MLine *)m->m_Def.tl_Premier ; l ; l = (struct MLine *)l->ml_Node.el_Suivant ) { write( 1 , l->ml_Text , l->ml_Len ) ; write( 1 , "\n" , 1 ) ; } else for ( m = (struct Macro *)TMac.tl_Premier ; m ; m = (struct Macro *)m->m_Node.el_Suivant ) { printf( "Macro %s : \n" , m->m_Name ) ; fflush( stdout ) ; for ( l = (struct MLine *)m->m_Def.tl_Premier ; l ; l = (struct MLine *)l->ml_Node.el_Suivant ) { write( 1 , l->ml_Text , l->ml_Len ) ; write( 1 , "\n" , 1 ) ; } } } /***********************************************************************/ void do_pn() { long oldval ; oldval = PageNumber ; if (! ChangeValue( &oldval )) return ; if ( oldval > 1 ) NewPageNumber = oldval ; } /***********************************************************************/ void do_po() { long oldval ; oldval = PageOffset ; if (! ChangeValue( &PageOffset )) PageOffset = Pop( TE_PAGOFS , 0 ) ; if ( PageOffset < 0 ) PageOffset = DEF_PAGOFS ; Push( TE_PAGOFS , oldval ) ; } /***********************************************************************/ void do_rm() { if ( ArgLen ) RemMac( Arg ) ; } /***********************************************************************/ void do_rr() { if ( ArgLen ) RemReg( Arg ) ; } /***********************************************************************/ void do_rs() { if ( ArgLen ) RemStr( Arg ) ; } /***********************************************************************/ void do_rt() { long lig, k ; if (! ArgLen) return ; lig = 0 ; if (! ChangeValue( &lig )) return ; RemTrp( lig ) ; } /***********************************************************************/ void do_so() { if ( ! ArgLen ) Fatal( ERR_SYNTAX ) ; Push( TE_INFILE , CurrentInputFile ) ; CurrentInputFile = NewFile( Arg ) ; if ( CurrentInputFile ) SetStr( "fn" , CurrentInputFile->if_Name ) ; } /***********************************************************************/ void do_sp() { do_br() ; EmptyToWrite += ( isdigit( Arg[0] ) ) ? atoi( Arg ) : 1 ; } /***********************************************************************/ void do_ta() { long oldval ; oldval = TabLen ; if (! ChangeValue( &TabLen )) TabLen = oldval ; } /***********************************************************************/ void do_tc() { TabChar = ( Arg[0] == '\0' ) ? DEF_TABCHR : Arg[0] ; } /***********************************************************************/ void do_ti() { do_br() ; TmpIndent = myatoi() ; BCLR( Flg , F_NOTI ) ; } /***********************************************************************/ void do_tl() { long i ; register long k, l ; unsigned char *centre, *droit ; register unsigned char delim, *gauche, *p ; if ( ! ArgLen ) return ; /* recupere les trois morceaux */ delim = Arg[0] ; gauche = &Arg[1] ; while ( (*gauche != delim) && (*gauche != '\0') ) gauche++ ; if ( *gauche == '\0' ) Fatal( ERR_SYNTAX ) ; *gauche = '\0' ; gauche++ ; centre = gauche ; while ( (*gauche != delim) && (*gauche != '\0') ) gauche++ ; if ( *gauche == '\0' ) Fatal( ERR_SYNTAX ) ; *gauche = '\0' ; gauche++ ; droit = gauche ; while ( (*gauche != delim) && (*gauche != '\0') ) gauche++ ; if ( *gauche == '\0' ) Fatal( ERR_SYNTAX ) ; *gauche = '\0' ; gauche = &Arg[1] ; /* calcule l'intervalle et pond le resultat */ p = tmp ; i = TitleLen - strlen( centre ) ; k = i >> 1 ; for ( l = 0 ; l < PageOffset ; l++ , p++ ) *p = ' ' ; if ( k > 0 ) { strcpy( p , TableEsc[6] ) ; /* repasse en normal */ while ( *p ) p++ ; for ( l = 0 ; TitleSeq[l] ; l++ ) { switch( TitleSeq[l] ) { case 'b' : strcpy( p , TableEsc[1] ) ; break ; case 'i' : strcpy( p , TableEsc[3] ) ; break ; case 'u' : strcpy( p , TableEsc[5] ) ; break ; default : Fatal( ERR_SYNTAX ) ; } while ( *p ) p++ ; } strcpy( p , gauche ) ; l = strlen( gauche ) ; p += l ; if ( i & 1 ) l-- ; for ( l = k - l ; l > 0 ; l-- , p++ ) *p = ' ' ; strcpy( p , centre ) ; p += strlen( centre ) ; for ( l = k - strlen( droit ) ; l > 0 ; l-- , p++ ) *p = ' ' ; strcpy( p , droit ) ; p += strlen( droit ) ; } strcpy( p , TableEsc[6] ) ; /* repasse en normal */ strcat( p , "\n" ) ; EmptyToWrite += LineSpacing - 1 ; LigneSuiv( tmp ) ; } /***********************************************************************/ void do_tr() { if (! ArgLen) return ; strcpy( TrTab , Arg ) ; if ( ArgLen & 1 ) strcat( TrTab , " " ) ; } /***********************************************************************/ void do_ts() { if ( ! ArgLen ) return ; strcpy( TitleSeq , Arg ) ; } /***********************************************************************/ void do_wh() { long lig, k ; unsigned char *p ; if (! ArgLen) return ; lig = 0 ; if (! ChangeValue( &lig )) return ; for ( p = Arg ; (*p) && (! isspace( *p )) ; p++ ) ; while ( isspace( *p ) ) p++ ; k = strlen( p ) ; if ( (k != 1) && (k != 2) ) Fatal( ERR_SYNTAX ) ; SetTrp( lig , p ) ; }