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 >
C/C++ Source or Header  |  1992-01-04  |  10KB  |  408 lines

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