home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 608b.lha / ARoff / Sources.LZH / Sources / fonctions.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-06  |  12.3 KB  |  567 lines

  1. /*
  2.  * Diverses fonctions de base
  3.  * (c)1991 par Denis GOUNELLE
  4.  */
  5.  
  6. #include "aroff.h"
  7. #include "pile.h"
  8.  
  9. static unsigned char tmp[1+LGMAXSTR<<1], aux[LGMAXSTR+1] ;
  10.  
  11. extern struct Contexte *LastContext ;
  12. extern struct String *CurrentString ;
  13. extern unsigned char Arg[], OutputBuf[] ;
  14. extern char *ARoff_Version, *ARoff_Usage ;
  15. extern struct InputFile *CurrentInputFile ;
  16. extern struct Macro *CurrentMacro, *FindVar() ;
  17. extern struct TeteListe TReg, TStr, TMac, TTrp ;
  18. extern long ArgLen, OutputLen, TotalIndent, LineSpacing, LineNumber,
  19.         NumInterv, NumSpace, NumIndent, PageOffset, Flg, TmpNoNum,
  20.         InputMode, TmpIndent, OutputLine, PageLen, PageNumber,
  21.         EmptyToWrite, NewPageNumber ;
  22.  
  23. extern void do_ab(), do_ad(), do_am(), do_as(), do_bp(), do_br(), do_ce(),
  24.         do_de(), do_ds(), do_el(), do_ex(), do_fi(), do_fs(), do_fl(),
  25.         do_if(), do_in(), do_ll(), do_ls(), do_lt(), do_na(), do_ne(),
  26.         do_nf(), do_nm(), do_nn(), do_nr(), do_pl(), do_pm(), do_pn(),
  27.         do_po(), do_rm(), do_rr(), do_rs(), do_rt(), do_so(), do_sp(),
  28.         do_ta(), do_tc(), do_ti(), do_tl(), do_tm(), do_tr(), do_ts(),
  29.         do_wh() ;
  30.  
  31. /**************************************************************************/
  32.  
  33. void Termine()
  34. {
  35.   register long k ;
  36.   register struct Macro *m ;
  37.  
  38.   CloseFile( CurrentInputFile ) ;
  39.  
  40.   VideListe( &TReg ) ;
  41.   VideListe( &TStr ) ;
  42.   VideListe( &TTrp ) ;
  43.  
  44.   for ( m = (struct Macro *)TMac.tl_Premier ;
  45.     m ;
  46.     m = (struct Macro *)m->m_Node.el_Suivant )
  47.   {
  48.     VideListe( &(m->m_Def) ) ;
  49.     for ( k = 0 ; m->m_Arg[k] ; k++ ) free( m->m_Arg[k] ) ;
  50.   }
  51.   VideListe( &TMac ) ;
  52.  
  53.   exit( 0 ) ;
  54. }
  55.  
  56. /**************************************************************************/
  57.  
  58. void Abort( indic )
  59. long indic ;
  60.  
  61. {
  62.   if ( (indic) && (OutputLen) )
  63.   {
  64.     OutputBuf[OutputLen] = '\0' ;
  65.     OutputLen = '\0' ;
  66.     LigneSuiv( OutputBuf ) ;
  67.   }
  68.   Termine() ;
  69. }
  70.  
  71. /**************************************************************************/
  72.  
  73. void FatalError( code , line , file )
  74. long code, line ;
  75. char *file ;
  76.  
  77. {
  78.   if ( code == ERR_ARGS )
  79.     fprintf( stderr , "%s\n%s\n" , ARoff_Version , ARoff_Usage ) ;
  80.   else
  81.   {
  82.     fprintf( stderr , "Error %d in file %s at line %d\n" , code , file , line ) ;
  83.     if ( CurrentInputFile )
  84.       fprintf( stderr , "current file: %s, line: %d\n" ,
  85.            CurrentInputFile->if_Name , CurrentInputFile->if_Line ) ;
  86.   }
  87.  
  88.   Abort( 0 ) ;
  89. }
  90.  
  91. /**************************************************************************/
  92.  
  93. char *myalloc( len , indic )
  94. register long len ;
  95. long indic ;
  96.  
  97. {
  98.   register long *p ;
  99.  
  100.   if (! len) Fatal( ERR_INTERNAL ) ;
  101.  
  102.   if ( len & 1 ) len++ ; /* forces len to next even value  */
  103.   p = (long *)malloc( len ) ;
  104.   if ( ! p ) Fatal( ERR_MEMORY ) ;
  105.   if ( indic ) bzero( p , len ) ;
  106.   return( (char *)p ) ;
  107. }
  108.  
  109. /**************************************************************************/
  110.  
  111. void SetMacArgs()
  112. {
  113.   register long k ;
  114.   register struct Macro *m ;
  115.   register unsigned char *p, c ;
  116.  
  117.   m = CurrentMacro ;
  118.   m->m_NbArg = k = 0 ;
  119.  
  120.   while ( Arg[k] )
  121.   {
  122.     p = m->m_Arg[m->m_NbArg] = (unsigned char *)myalloc( ArgLen - k + 1 , 0 ) ;
  123.     while ( (c = Arg[k]) && (! isspace( c )) )
  124.     {
  125.       if ( c == SC_FIXSPC ) c = ' ' ;
  126.       *p = c ;
  127.       k++ ;
  128.       p++ ;
  129.     }
  130.     *p = '\0' ;
  131.     while ( isspace( Arg[k] ) ) k++ ;
  132.     m->m_NbArg++ ;
  133.   }
  134.  
  135.   SetReg( ".$" , m->m_NbArg , 0 ) ;
  136. }
  137.  
  138. /**************************************************************************/
  139.  
  140. struct Command CmdTable[] =
  141. {
  142.   "ab",do_ab,
  143.   "ad",do_ad,
  144.   "am",do_am,
  145.   "as",do_as,
  146.   "bp",do_bp,
  147.   "br",do_br,
  148.   "ce",do_ce,
  149.   "de",do_de,
  150.   "ds",do_ds,
  151.   "el",do_el,
  152.   "ex",do_ex,
  153.   "fi",do_fi,
  154. /*"fl",do_fl, inaccessible pour l'utilisateur */
  155.   "fs",do_fs,
  156.   "if",do_if,
  157.   "in",do_in,
  158.   "ll",do_ll,
  159.   "ls",do_ls,
  160.   "lt",do_lt,
  161.   "na",do_na,
  162.   "ne",do_ne,
  163.   "nf",do_nf,
  164.   "nm",do_nm,
  165.   "nn",do_nn,
  166.   "nr",do_nr,
  167.   "pl",do_pl,
  168.   "pm",do_pm,
  169.   "pn",do_pn,
  170.   "po",do_po,
  171.   "rm",do_rm,
  172.   "rr",do_rr,
  173.   "rs",do_rs,
  174.   "rt",do_rt,
  175.   "so",do_so,
  176.   "sp",do_sp,
  177.   "ta",do_ta,
  178.   "tc",do_tc,
  179.   "ti",do_ti,
  180.   "tl",do_tl,
  181.   "tm",do_tm,
  182.   "tr",do_tr,
  183.   "ts",do_ts,
  184.   "wh",do_wh,
  185.   ""  ,NULL,
  186. } ;
  187.  
  188. void ExecCmd( cmd )
  189. char *cmd ;
  190.  
  191. {
  192.   register struct Macro *m ;
  193.   register struct Command *p ;
  194.  
  195.   Arg[ArgLen] = '\0' ;
  196.  
  197.   /* est-ce une requete ? */
  198.  
  199.   for ( p = CmdTable ; p->c_func ; p++ )
  200.     if (! strcmp( p->c_name , cmd ))
  201.     {
  202.       (*p->c_func)() ;
  203.       goto _end ;
  204.     }
  205.  
  206.   /* est-ce une macro ? */
  207.  
  208.   m = FindVar( &TMac , cmd ) ;
  209.   if ( m )
  210.   {
  211.     if ( InputMode & IM_EXMACRO ) Push( TE_MACRO , CurrentMacro ) ;
  212.     if ( InputMode & IM_STRING ) Push( TE_STRING , CurrentString ) ;
  213.     Push( TE_INMODE , InputMode ) ;
  214.     BCLR( InputMode , (IM_STRING|IM_EXMACRO) ) ;
  215.  
  216.     m->m_NextC = 0 ;
  217.     m->m_NextL = (struct MLine *)m->m_Def.tl_Premier ;
  218.     CurrentMacro = m ;
  219.     SetMacArgs() ;
  220.     BSET( InputMode , IM_EXMACRO ) ;
  221.   }
  222.  
  223. _end:
  224.  
  225.   if ( (Flg & F_WASIF) && (strcmp( cmd , "if")) ) BCLR( Flg , F_WASIF ) ;
  226.   BCLR( Flg , F_NOBRK ) ;
  227.   BSET( Flg , (F_MACREQ|F_WASNL) ) ;
  228. }
  229.  
  230. /**************************************************************************/
  231.  
  232. long GetName( dst )
  233. char *dst ;
  234.  
  235. {
  236.   long c ;
  237.  
  238.   if ( (c = GetChar()) == EOF ) return( 0 ) ;
  239.   dst[0] = c ;
  240.   if ( (c = GetChar()) == EOF ) return( 0 ) ;
  241.   dst[1] = c ;
  242.   dst[2] = '\0' ;
  243.   return( 1 ) ;
  244. }
  245.  
  246. /**************************************************************************/
  247.  
  248. long myatoi()
  249.  
  250. {
  251.   long k ;
  252.   unsigned char *p ;
  253.  
  254.   k = strtol( Arg , &p , 10 ) ;
  255.   if ( (*p != '\0') && (! isspace( *p )) ) Fatal( ERR_SYNTAX ) ;
  256.   return( k ) ;
  257. }
  258.  
  259. /**************************************************************************/
  260.  
  261. char *GetArg( pstr , pval )
  262. unsigned char *pstr ;
  263. long *pval ;
  264.  
  265. {
  266.   while ( isspace( *pstr ) ) pstr++ ;
  267.   if ( isdigit( *pstr ) ) *pval = atoi( pstr ) ;
  268.   while ( (*pstr != '\0') && (! isspace( *pstr)) ) pstr++ ;
  269.   return( pstr ) ;
  270. }
  271.  
  272. /**************************************************************************/
  273.  
  274. long ChangeValue( val )
  275. long *val ;
  276.  
  277. {
  278.   register char c ;
  279.   register long k ;
  280.  
  281.   k = 0 ;
  282.   c = '\0' ;
  283.   if ( (Arg[k] == '+') || (Arg[k] == '-') )
  284.   {
  285.     c = Arg[k] ;
  286.     k++ ;
  287.   }
  288.  
  289.   if (! isdigit( Arg[k] )) return( 0 ) ;
  290.   k = atoi( &Arg[k] ) ;
  291.  
  292.   switch ( c )
  293.   {
  294.     case '+' : *val += k ; break ;
  295.     case '-' : *val -= k ; break ;
  296.     default  : *val  = k ; break ;
  297.   }
  298.  
  299.   return( 1 ) ;
  300. }
  301.  
  302. /**************************************************************************/
  303.  
  304. void ChangePageNumber( number )
  305. long number ;
  306.  
  307. {
  308.    PageNumber = number ;
  309.    SetReg( "pn" , PageNumber , 0 ) ;
  310.    NewPageNumber = number + 1 ;
  311. }
  312.  
  313. /**************************************************************************/
  314.  
  315. long LigneSuiv( str )
  316. char *str ;
  317.  
  318. {
  319.   register long k ;
  320.   register char *p ;
  321.   register struct Macro *m ;
  322.  
  323.   m = CurrentMacro ;
  324.   k = strlen( str ) ;
  325.  
  326.   if ( TestTrp( OutputLine ) )
  327.   {
  328.     BSET( Flg , F_TRAP ) ;
  329.     BSET( CurrentMacro->m_Flag , MF_TRAP ) ;
  330.     p = myalloc( k+1 , 0 ) ;
  331.     strcpy( p , str ) ;
  332.     Push( TE_OUTLINE , p ) ;
  333.     Push( TE_TOWRITE , EmptyToWrite ) ;
  334.     if ( m ) BSET( m->m_Flag , MF_WAIT ) ;
  335.     EmptyToWrite = 0 ;
  336.     return ;
  337.   }
  338.  
  339.   if ( k ) do_fl( str ) ;
  340.   OutputLine++ ;
  341.   if ( OutputLine > PageLen )
  342.   {
  343.     OutputLine = 1 ;
  344.     ChangePageNumber( NewPageNumber ) ;
  345.   }
  346.  
  347. }
  348.  
  349. /**************************************************************************/
  350.  
  351. void WriteLine()
  352.  
  353. {
  354.   register long k ;
  355.   register unsigned char *p ;
  356.  
  357.   /* ajoute le decalage de page */
  358.  
  359.   p = tmp ;
  360.   for ( k = 0 ; k < PageOffset ; k++ , p++ ) *p = ' ' ;
  361.  
  362.   /* effectue la numerotation */
  363.  
  364.   for ( k = 0 ; k < OutputLen ; k++ ) if (! isspace( OutputBuf[k] )) break ;
  365.   if ( (Flg & F_NUMBER) && (k < OutputLen) && (! TmpNoNum) )
  366.   {
  367.     for ( k = 0 ; k < NumIndent ; k++ , p++ ) *p = ' ' ;
  368.     sprintf( aux , "%d" , LineNumber ) ;
  369.     LineNumber++ ;
  370.     SetReg( "ol" , LineNumber , 0 ) ;
  371.     if ( (NumInterv != 1) && ((LineNumber % NumInterv) != 1) )
  372.       for ( k = 0 ; aux[k] != '\0' ; k++ ) aux[k] = ' ' ;
  373.     strcpy( p , aux ) ;
  374.     p += strlen( aux ) ;
  375.     for ( k = 0 ; k < NumSpace ; k++ , p++ ) *p = ' ' ;
  376.   }
  377.  
  378.   /* ajoute l'indentation */
  379.  
  380.   for ( k = 0 ; k < TotalIndent ; k++ , p++ ) *p = ' ' ;
  381.   if ( Flg & F_NOTI ) TmpIndent = 0 ;
  382.  
  383.   /* ecrit la ligne finale */
  384.  
  385.   bcopy( OutputBuf , p , OutputLen ) ;
  386.   p += OutputLen ;
  387.   OutputLen = 0 ;
  388.   *p = '\n' ;
  389.   p[1] = '\0' ;
  390.  
  391.   EmptyToWrite += LineSpacing - 1 ;
  392.   LigneSuiv( tmp ) ;
  393. }
  394.  
  395. /**************************************************************************/
  396.  
  397. void SauveContexte( indic )
  398. long indic ;
  399.  
  400. {
  401.   register long k ;
  402.   register struct Macro *m ;
  403.   register struct Contexte *p ;
  404.  
  405.   p = (struct Contexte *)myalloc( sizeof(struct Contexte) , 0 ) ;
  406.  
  407.   if ( InputMode & IM_EXMACRO )
  408.   {
  409.     m = CurrentMacro ;
  410.     bcopy( m , &(p->src.c_macro) , sizeof(struct Macro) ) ;
  411.     p->c_ptr = (long)m ;
  412.     p->c_len = sizeof(struct Macro) ;
  413.   }
  414.   else if ( InputMode & IM_STRING )
  415.   {
  416.     k = 9 + CurrentString->s_len ;
  417.     bcopy( CurrentString , &(p->src.c_string) , k ) ;
  418.     p->c_ptr = (long)CurrentString ;
  419.     p->c_len = k ;
  420.   }
  421.   else
  422.   {
  423.     bcopy( CurrentInputFile , &(p->src.c_file) , sizeof(struct InputFile) ) ;
  424.     if (! (CurrentInputFile->if_Flag & IFF_LOADED))
  425.     {
  426.       bcopy( CurrentInputFile->if_Buf , p->c_ibuf , CurrentInputFile->if_BufLen ) ;
  427.       p->c_seek = lseek( p->src.c_file.if_Desc , 0 , 1 ) ;
  428.       if ( p->c_seek == -1 ) Fatal( ERR_SEEK ) ;
  429.     }
  430.     p->c_ptr = (long)CurrentInputFile ;
  431.   }
  432.  
  433.   bcopy( OutputBuf , p->c_obuf , OutputLen ) ;
  434.   p->c_olen = OutputLen ;
  435.   p->c_imod = InputMode ;
  436.   p->c_flag = Flg ;
  437.  
  438.   if ( indic )
  439.   {
  440.     if ( LastContext ) free( LastContext ) ;
  441.     LastContext = p ;
  442.   }
  443.   else Push( TE_CONTEXT , p ) ;
  444. }
  445.  
  446. /**************************************************************************/
  447.  
  448. void RestoreContexte( indic )
  449. long indic ;
  450.  
  451. {
  452.   register struct Contexte *p ;
  453.  
  454.   if ( indic ) p = LastContext ;
  455.   else p = (struct Contexte *) Pop( TE_CONTEXT , 1 ) ;
  456.  
  457.   Flg = p->c_flag ;
  458.   InputMode = p->c_imod ;
  459.   if ( InputMode & IM_EXMACRO )
  460.   {
  461.     CurrentMacro = (struct Macro *)p->c_ptr ;
  462.     bcopy( &(p->src.c_macro) , CurrentMacro , p->c_len ) ;
  463.   }
  464.   else if ( InputMode & IM_STRING )
  465.   {
  466.     CurrentString = (struct String *)p->c_ptr ;
  467.     bcopy( &(p->src.c_string) , CurrentString , p->c_len ) ;
  468.   }
  469.   else
  470.   {
  471.     CurrentInputFile = (struct InputFile *)p->c_ptr ;
  472.     bcopy( &(p->src.c_file) , CurrentInputFile, sizeof(struct InputFile) ) ;
  473.     if (! (CurrentInputFile->if_Flag & IFF_LOADED))
  474.     {
  475.       bcopy( p->c_ibuf , CurrentInputFile->if_Buf , CurrentInputFile->if_BufLen ) ;
  476.       if ( lseek( p->src.c_file.if_Desc , p->c_seek , 0 ) == -1 )
  477.     Fatal( ERR_SEEK ) ;
  478.     }
  479.   }
  480.  
  481.   bcopy( p->c_obuf , OutputBuf , OutputLen ) ;
  482.   OutputLen = p->c_olen ;
  483.   free( p ) ;
  484.   if ( indic ) LastContext = NULL ;
  485. }
  486.  
  487. /**************************************************************************/
  488.  
  489. void NewString( str )
  490. char *str ;
  491.  
  492. {
  493.   register struct String *s ;
  494.  
  495.   if ( ! *str ) return ;
  496.  
  497.   if ( InputMode & IM_STRING ) Push( TE_STRING , CurrentString ) ;
  498.   if ( InputMode & IM_EXMACRO ) Push( TE_MACRO , CurrentMacro ) ;
  499.   Push( TE_INMODE , InputMode ) ;
  500.   BCLR( InputMode , (IM_STRING|IM_EXMACRO) ) ;
  501.  
  502.   s = (struct String *)myalloc( sizeof(struct String) , 0 ) ;
  503.   strcpy( s->s_val , str ) ;
  504.   s->s_len = strlen( str ) ;
  505.   s->s_pos = 0 ;
  506.   CurrentString = s ;
  507.   BSET( InputMode , IM_STRING ) ;
  508. }
  509.  
  510. /**************************************************************************/
  511.  
  512. unsigned char *TestString( p )
  513. register unsigned char *p ;
  514.  
  515. {
  516.   unsigned char *s, *d ;
  517.  
  518.   p++ ;
  519.   if (! *p) Fatal( ERR_SYNTAX ) ;
  520.   s = p ;
  521.   while ( (*p != '\'') && (*p != '\0') ) p++ ;
  522.   if ( *p != '\'' ) Fatal( ERR_SYNTAX ) ;
  523.   *p = '\0' ;
  524.  
  525.   p++ ;
  526.   if (! *p) Fatal( ERR_SYNTAX ) ;
  527.   d = p ;
  528.   while ( (*p != '\'') && (*p != '\0') ) p++ ;
  529.   if ( *p != '\'' ) Fatal( ERR_SYNTAX ) ;
  530.   *p = '\0' ;
  531.  
  532.   p++ ;
  533.   if ( strcmp( s , d ) ) BSET( Flg , F_WASFALSE ) ;
  534.   return( p ) ;
  535. }
  536.  
  537. /**************************************************************************/
  538.  
  539. unsigned char *TestNum( p )
  540. unsigned char *p ;
  541.  
  542. {
  543.   register char c ;
  544.   register long s , d ;
  545.  
  546.   s = strtol( p , &p , 10 ) ;
  547.   while ( isspace(*p) ) p++ ;
  548.  
  549.   if (! *p) Fatal( ERR_SYNTAX ) ;
  550.   c = *p ;
  551.   p++ ;
  552.   while ( isspace(*p) ) p++ ;
  553.  
  554.   if (! *p) Fatal( ERR_SYNTAX ) ;
  555.   d = strtol( p , &p , 10 ) ;
  556.  
  557.   switch ( c )
  558.   {
  559.     case '<' : if ( s >= d ) BSET( Flg , F_WASFALSE ) ; break ;
  560.     case '>' : if ( s <= d ) BSET( Flg , F_WASFALSE ) ; break ;
  561.     case '=' : if ( s != d ) BSET( Flg , F_WASFALSE ) ; break ;
  562.     default  : Fatal( ERR_SYNTAX ) ;
  563.   }
  564.  
  565.   return( p ) ;
  566. }
  567.