home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 4 / CDPD_IV.bin / utilities / print / aroff / sources / aroff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-28  |  8.7 KB  |  378 lines

  1. /*
  2.  * Programme principal
  3.  * (c)1991 par Denis GOUNELLE
  4.  *
  5.  * Usage : aroff [-wstack] file
  6.  * L'option -w permet d'augmenter la taille de la pile interne (256 par defaut)
  7.  * Si "file" est "-", l'entree standard est utilisee
  8.  */
  9.  
  10. #include "aroff.h"
  11. #include "pile.h"
  12.  
  13. char DUMMYSTRING[]  = { '$' , 'V' , 'E', 'R' , ':' , ' ' } ,
  14.      *ARoff_Version = "ARoff v1.01, 20-Oct-91 by Denis GOUNELLE" ,
  15.      *ARoff_Usage   = "Usage : aroff [-wstack] file" ;
  16.  
  17. unsigned char cmd[LGMAXSTR+1] ,
  18.           Arg[LGMAXSTR+1] ,
  19.           TabChar = DEF_TABCHR ,
  20.           OutputBuf[LGMAXBUF] ; /* tampon de sortie */
  21.  
  22. long OutputLen ,        /* nb de car. dans OutputBuf[] */
  23.      ArgLen ,            /* nb de car. dans Arg[] */
  24.      Flg ,            /* divers indicateurs */
  25.      *Pile     = NULL ,
  26.      TaillePile  = DEF_PILE ,
  27.      OutputLine  = 1 ,        /* no ligne dans la page courante */
  28.      InputMode     = IM_FILLING , /* indicateur pour lecture */
  29.      AdjustMode  = AM_BOTH ,    /* type d'ajustement */
  30.      PageNumber  = 0 ,
  31.      NewPageNumber = DEF_PAGNUM ,
  32.      LineLen     = DEF_LINLEN ,
  33.      LineSpacing = DEF_LINSPC ,
  34.      TitleLen     = DEF_TITLEN ,
  35.      PageLen     = DEF_PAGLEN ,
  36.      PageOffset  = DEF_PAGOFS ,
  37.      Indent     = DEF_INDENT ,
  38.      TabLen     = DEF_TABLEN ,
  39.      LineNumber  = DEF_LINNUM ,
  40.      NumInterv     = 1 ,
  41.      NumSpace     = 1 ,
  42.      NumIndent     = 0 ,
  43.      TotalIndent = 0 ,
  44.      TmpIndent     = 0 ,
  45.      TmpCenter     = 0 ,
  46.      TmpNoNum     = 0 ,
  47.      EmptyToWrite= 0 ,
  48.      OldInputMode ,
  49.      CtrlLen ,            /* lg ajoutée par ".fs"             */
  50.      TmpLineLen ;        /* lg que doit avoir ligne courante */
  51.  
  52. struct TeteListe TReg, TStr, TMac, TTrp ;
  53. struct InputFile *CurrentInputFile = NULL ;
  54. struct Contexte *LastContext = NULL ;
  55. struct String *CurrentString = NULL ;
  56. struct Macro *CurrentMacro = NULL ;
  57.  
  58. extern struct InputFile *NewFile() ;
  59.  
  60. /***************************************************************************/
  61.  
  62. void Traite()
  63. {
  64.   register long c, d ;
  65.   unsigned char e, tmp[LGMAXSTR+1], aux[LGMAXSTR+1] ;
  66.  
  67.   Flg = F_WASNL|F_NOTI ;
  68.   OutputLen = CtrlLen = 0 ;
  69.  
  70.   for (;;)
  71.   {
  72.     BCLR( Flg , F_BREAKED ) ;
  73.     TotalIndent  = Indent + TmpIndent ;
  74.     TmpLineLen     = LineLen + CtrlLen - TotalIndent ;
  75.  
  76. #ifdef AZTEC_C
  77.     if ( SetSignal( 0L , 0L ) & SIGBREAKF_CTRL_C )
  78.     {
  79.       fprintf( stderr , "\n***BREAK\n" ) ;
  80.       Termine() ;
  81.     }
  82. #endif
  83.  
  84.     /*
  85.      * Boucle de lecture :
  86.      *      - on interprete \x
  87.      *      - on detecte et traite ".xx" en debut de ligne
  88.      *      - quand on sort, on doit traiter les "OutputLen" caracteres
  89.      *        places dans "OutputBuf[]"
  90.      */
  91.  
  92.     while ( (c = GetChar()) != EOF )
  93.     {
  94.       if ( (c == '\n') && (! (InputMode & IM_EXMACRO)) )
  95.       {
  96.     CurrentInputFile->if_Line++ ;
  97.     SetReg( "il" , CurrentInputFile->if_Line , 0 ) ;
  98.       }
  99.  
  100.       if ( Flg & F_WASBS )
  101.       {
  102.     switch ( c )
  103.     {
  104.       case 't'  : c = '\t'      ; break ;
  105.       case ' '  : c = SC_FIXSPC ; break ;
  106.       case '!'  : if (! OutputLen) BSET( InputMode , IM_TRANSP ) ;
  107.       case '\n' : c = SC_IGNORE ;
  108.               break ;
  109.       case 'n'  : e = '\0' ;
  110.       case '*'  : d = GetChar() ;
  111.               if ( (c == 'n') && ((d == '+') || (d == '-')) )
  112.               {
  113.             e = d ;
  114.             d = GetChar() ;
  115.               }
  116.  
  117.               if ( d != '(' )
  118.               {
  119.             if ( d == EOF ) Fatal( ERR_SYNTAX ) ;
  120.             tmp[0] = d ;
  121.             tmp[1] = '\0' ;
  122.               }
  123.               else if (! GetName( tmp )) Fatal( ERR_SYNTAX ) ;
  124.  
  125.               if ( c == 'n' )
  126.               {
  127.             if ( e != '\0' ) IncReg( tmp , e ) ;
  128.             GetReg( tmp , aux ) ;
  129.             for ( d = 0 ; aux[d] ; d++ ) PutChar( aux[d] ) ;
  130.             c = SC_EXPAND ;
  131.               }
  132.               else
  133.               {
  134.             GetStr( tmp , aux ) ;
  135.             NewString( aux ) ;
  136.             c = SC_IGNORE ;
  137.               }
  138.  
  139.               break ;
  140.       case '"'  : BSET( Flg , F_SKIPEOL ) ; break ;
  141.       case '$'  : if ( ! CurrentMacro ) Fatal( ERR_SYNTAX ) ;
  142.               c = GetChar() ;
  143.               if ( (c == EOF) || (c < '1') || (c > '9') )
  144.             Fatal( ERR_SYNTAX ) ;
  145.               c -= '1' ;
  146.               if ( c < CurrentMacro->m_NbArg )
  147.             NewString( CurrentMacro->m_Arg[c] ) ;
  148.               c = SC_IGNORE ;
  149.               break ;
  150.       default   : break ;
  151.     }
  152.     BCLR( Flg , F_WASBS ) ;
  153.       }
  154.       else if ( (c == '\\') && (! (InputMode & (IM_TRANSP|IM_STRING))) )
  155.       {
  156.     BSET( Flg , F_WASBS ) ;
  157.     continue ;
  158.       }
  159.  
  160.       if ( c == SC_EXPAND )
  161.       {
  162.     BCLR( Flg , (F_WASNL|F_NEWPAR) ) ;
  163.     if ( OutputLen > TmpLineLen ) break ;
  164.     continue ;
  165.       }
  166.  
  167.       if ( c == SC_IGNORE ) continue ;
  168.       if ( (c == ' ') && (InputMode & IM_RDARGS) && (! ArgLen) ) continue ;
  169.  
  170.       if ( InputMode & IM_TRANSP )
  171.       {
  172.     if ( PutChar( (char)c ) ) break ;
  173.     if ( c == '\n' )
  174.     {
  175.       BCLR( InputMode , IM_TRANSP ) ;
  176.       OutputBuf[OutputLen] = '\0' ;
  177.       OutputLen = 0 ;
  178.       LigneSuiv( OutputBuf ) ;
  179.     }
  180.     continue ;
  181.       }
  182.  
  183.       if ( Flg & F_SKIPEOL )
  184.       {
  185.     if ( c != '\n' ) continue ;
  186.     BCLR( Flg , F_SKIPEOL ) ;
  187.     BSET( Flg , F_WASNL ) ;
  188.     if (! (InputMode & IM_RDARGS)) continue ;
  189.       }
  190.  
  191.       if ( (Flg & F_WASNL) && ((c == '.') || (c == '\'')) )
  192.     if ( InputMode & IM_RDMACRO )
  193.     {
  194.       if ( (c = GetChar()) == EOF ) Fatal( ERR_SYNTAX ) ;
  195.       if ( c == '.' )
  196.       {
  197.         BSET( Flg , F_SKIPEOL ) ;
  198.         EnleveQueue( &(CurrentMacro->m_Def) ) ;
  199.         InputMode = OldInputMode ;
  200.         CurrentMacro = NULL ;
  201.         continue ;
  202.       }
  203.       BCLR( Flg , F_WASNL ) ;
  204.       PutChar( '.' ) ;
  205.       PutChar( (char)c ) ;
  206.       continue ;
  207.     }
  208.     else
  209.     {
  210.       if (! GetName( cmd )) Fatal( ERR_SYNTAX ) ;
  211.       if ( c == '\'' ) BSET( Flg , F_NOBRK ) ;
  212.       BSET( InputMode , IM_RDARGS ) ;
  213.       BCLR( Flg , F_WASNL ) ;
  214.       ArgLen = 0 ;
  215.       continue ;
  216.     }
  217.  
  218.       if ( c == '\n' )
  219.       {
  220.     if ( Flg & F_WASNL )
  221.     {
  222.       if ( (! OutputLen) && (! (InputMode & IM_RDMACRO)) ) PutChar( ' ' ) ;
  223.       else BSET( Flg , F_NEWPAR|F_BREAKED ) ;
  224.       break ;
  225.     }
  226.     BSET( Flg , F_WASNL ) ;
  227.  
  228.     if ( InputMode & IM_RDARGS )
  229.     {
  230.       BCLR( InputMode , IM_RDARGS ) ;
  231.       if ( OutputLen ) SauveContexte( 0 ) ;
  232.       BCLR( Flg , F_CONTINUE ) ;
  233.       ExecCmd( cmd ) ;
  234.       if ( Flg & F_CONTINUE ) continue ;
  235.       break ;
  236.     }
  237.  
  238.     if ( (InputMode & IM_FILLING) && (! TmpCenter) )
  239.     {
  240.       if ( OutputLen ) c = ' ' ;
  241.       else continue ;
  242.     }
  243.     else
  244.     {
  245.       BSET( Flg , F_BREAKED ) ;
  246.       break ;
  247.     }
  248.       }
  249.       else BCLR( Flg , F_WASNL ) ;
  250.  
  251.       if ( c == '\t' )
  252.       {
  253.     c =  TabLen * (1 + (OutputLen / TabLen)) ;
  254.     while ( OutputLen < c ) if ( PutChar( TabChar ) ) break ;
  255.     SauveContexte( 0 ) ;
  256.     if ( OutputLen > TmpLineLen ) break ;
  257.     continue ;
  258.       }
  259.  
  260.       if ( InputMode & IM_RDARGS )
  261.       {
  262.     PutChar( (char)c ) ;
  263.     continue ;
  264.       }
  265.  
  266.       if ( isspace( c ) &&
  267.        (! OutputLen) &&
  268.        (! (Flg & F_WASNL)) &&
  269.        (! (InputMode & IM_RDMACRO)) ) continue ;
  270.  
  271.       PutChar( (char)c ) ;
  272.       if ( isspace( c ) ) SauveContexte( 0 ) ;
  273.       BCLR( Flg , F_NEWPAR ) ;
  274.       if ( OutputLen >= TmpLineLen ) break ;
  275.     }
  276.  
  277.     if ( c == EOF ) BSET( Flg , F_BREAKED ) ;
  278.  
  279.     if ( OutputLen && (! (Flg & F_MACREQ)) )
  280.     {
  281.       AdjustLine() ;
  282.       if ( Flg & F_NEWPAR ) EmptyToWrite++ ;
  283.       WriteLine() ;
  284.       CtrlLen = 0 ;
  285.       if ( TmpNoNum ) TmpNoNum-- ;
  286.       if ( TmpCenter ) TmpCenter-- ;
  287.       FlushStack( TE_CONTEXT ) ;
  288.       BSET( Flg , F_SORTIE ) ;
  289.       if ( LastContext ) free( LastContext ) ;
  290.       LastContext = NULL ;
  291.     }
  292.  
  293.     if ( InputMode & IM_RDMACRO ) PutChar( '\n' ) ;
  294.     BCLR( Flg , F_MACREQ ) ;
  295.     BSET( Flg , F_NOTI ) ;
  296.  
  297.     if ( c == EOF )
  298.     {
  299.       CloseFile( CurrentInputFile ) ;
  300.       CurrentInputFile = (struct InputFile *) Pop( TE_INFILE , 0 ) ;
  301.       if ( (CurrentInputFile == NULL) ||
  302.        (CurrentInputFile == (struct InputFile *)-1) ) do_bp() ;
  303.       else SetStr( "fn" , CurrentInputFile->if_Name ) ;
  304.     }
  305.  
  306.     while ( EmptyToWrite > 0 )
  307.     {
  308.       EmptyToWrite-- ;
  309.       LigneSuiv( "\n" ) ;
  310.       BSET( Flg , F_SORTIE ) ;
  311.     }
  312.  
  313.     if ( c == EOF ) break ;
  314.   }
  315.  
  316. }
  317.  
  318. /***************************************************************************/
  319.  
  320. main( argc , argv )
  321. int argc ;
  322. char *argv[] ;
  323.  
  324. {
  325.   char *nom ;
  326.   long heure ;
  327.   struct tm *ladate ;
  328.  
  329.   time ( &heure ) ;
  330.   ladate = localtime( &heure ) ;
  331.  
  332.   if ( argc == 3 )
  333.   {
  334.     if (! strncmp( argv[1] , "-w" , 2 )) Fatal( ERR_ARGS ) ;
  335.     if (! isdigit( argv[1][2] )) Fatal( ERR_ARGS ) ;
  336.     TaillePile = atoi( &(argv[1][2]) ) ;
  337.     nom = argv[2] ;
  338.   }
  339.   else
  340.   {
  341.     if ( argc != 2 ) Fatal( ERR_ARGS ) ;
  342.     nom = argv[1] ;
  343.   }
  344.  
  345. /* cree la pile */
  346.  
  347.   Pile = (long *)myalloc( (TaillePile << 1) , 0 ) ;
  348.  
  349. /* initialise les registres */
  350.  
  351.   InitListe( &TReg ) ;
  352.   InitListe( &TStr ) ;
  353.   InitListe( &TMac ) ;
  354.   InitListe( &TTrp ) ;
  355.  
  356.   SetReg( "dw" , ladate->tm_wday + 1 , 0 ) ;
  357.   SetReg( "dy" , ladate->tm_mday , 0 ) ;
  358.   SetReg( "mo" , ladate->tm_mon + 1 , 0 ) ;
  359.   SetReg( "yr" , ladate->tm_year , 0 ) ;
  360.   SetReg( "hr" , ladate->tm_hour , 0 ) ;
  361.   SetReg( "mn" , ladate->tm_min , 0 ) ;
  362.   SetReg( "sc" , ladate->tm_sec , 0 ) ;
  363.   SetReg( "ol" , LineNumber , 0 ) ;
  364.   SetReg( "pn" , NewPageNumber , 0 ) ;
  365.  
  366. /* traite le fichier indique */
  367.  
  368.   CurrentInputFile = NewFile( nom ) ;
  369.   if ( CurrentInputFile )
  370.   {
  371.     SetStr( "fn" , CurrentInputFile->if_Name ) ;
  372.     SetReg( "il" , 1 , 0 ) ;
  373.     Traite() ;
  374.   }
  375.  
  376.   Termine() ;
  377. }
  378.