home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dmake40.zip / macparse.c < prev    next >
C/C++ Source or Header  |  1994-10-23  |  6KB  |  221 lines

  1. /* RCS      -- $Header: /u5/dvadura/src/public/dmake/src/RCS/macparse.c,v 1.1 1994/10/06 17:41:57 dvadura Exp $
  2. -- SYNOPSIS -- parse a macro definition
  3. -- 
  4. -- DESCRIPTION
  5. --    This file contains the code that parses a macro definition
  6. --    stored in a buffer.  If the string in buffer is not a valid
  7. --    macro definition the routie Parse_macro returns 0, otherwise it
  8. --    returns 1 to indicate success.
  9. -- 
  10. -- AUTHOR
  11. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  12. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  13. --
  14. -- COPYRIGHT
  15. --      Copyright (c) 1992,1994 by Dennis Vadura.  All rights reserved.
  16. -- 
  17. --      This program is free software; you can redistribute it and/or
  18. --      modify it under the terms of the GNU General Public License
  19. --      (version 1), as published by the Free Software Foundation, and
  20. --      found in the file 'LICENSE' included with this distribution.
  21. -- 
  22. --      This program is distributed in the hope that it will be useful,
  23. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  24. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25. --      GNU General Public License for more details.
  26. -- 
  27. --      You should have received a copy of the GNU General Public License
  28. --      along with this program;  if not, write to the Free Software
  29. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  30. --
  31. -- LOG
  32. --     $Log: macparse.c,v $
  33.  * Revision 1.1  1994/10/06  17:41:57  dvadura
  34.  * dmake Release Version 4.0, Initial revision
  35.  *
  36. */
  37.  
  38. #include "extern.h"
  39.  
  40. PUBLIC int
  41. Parse_macro( buffer, flag )/*
  42. =============================
  43.    Parse the string in buffer and define it as a macro if it is a valid macro.
  44.    Note especially the string .SETDIR= since it is an attribute, but looks a
  45.    lot like a macro definition.  This would not be a problem if make used
  46.    white space as token separators, since this is not the case we must do
  47.    something about it. */
  48. char *buffer;
  49. int  flag;
  50. {
  51.    char         *result;    /* temporary pointer for strings   */
  52.    TKSTR          input;        /* place to scan the buffer from   */
  53.    HASHPTR      hv;        /* pointer to hash table value       */
  54.    int          operator;    /* what macro operator do we have  */
  55.    char *tok1;            /* temporary place to keep a token */
  56.    char *tok2;            /* temporary place to keep a token */
  57.  
  58.    DB_ENTER( "Parse_macro" );
  59.  
  60.    SET_TOKEN( &input, buffer );
  61.    tok1 = Get_token( &input, "=+:*!?", 0 );
  62.  
  63.    operator=Macro_op(tok1);
  64.    if( operator ) {
  65.       Error( "No macro name" );
  66.       CLEAR_TOKEN( &input );
  67.       DB_RETURN( 1 );
  68.    }
  69.  
  70.    tok1 = DmStrDup(tok1);
  71.    tok2 = Get_token( &input, "=+:*!?", 2 );
  72.    if( !(operator = Macro_op(tok2)) || !strcmp(tok1,".SETDIR") ) {
  73.       CLEAR_TOKEN( &input );
  74.       FREE( tok1 );
  75.       DB_RETURN( 0 );
  76.    }
  77.  
  78.    tok2 = Expand(tok1); FREE(tok1); tok1 = tok2;
  79.    tok2 = Get_token( &input, NIL( char ), FALSE );
  80.  
  81.    /* Make sure we can force the assignment. */
  82.    if ( operator & M_OP_SI ) {
  83.       flag |= M_FORCE|M_MULTI;
  84.       operator &= ~M_OP_SI;
  85.    }
  86.  
  87.    switch( operator ) {
  88.       case M_OP_PLCL:
  89.       tok2 = Expand( tok2 );
  90.       /* Fall thru */
  91.  
  92.       case M_OP_PL:
  93.      /* Add to an existing macro, if it is not defined, though, then
  94.       * just define a new macro */
  95.  
  96.      if( (hv = GET_MACRO(tok1)) == NIL(HASH) || hv->ht_value == NIL(char) )
  97.         Def_macro( tok1, tok2, flag );
  98.      else {
  99.         result = DmStrAdd( hv->ht_value, tok2, FALSE );
  100.         Def_macro( tok1, result, flag );
  101.         FREE( result );
  102.      }
  103.      if( operator == M_OP_PLCL ) FREE(tok2);
  104.      break;
  105.  
  106.       case M_OP_DF:
  107.       if( (hv = GET_MACRO(tok1)) != NIL(HASH) )
  108.         break;
  109.      /* else FALLTHRU */
  110.  
  111.       case M_OP_EQ:
  112.      Def_macro( tok1, tok2, flag );
  113.      break;
  114.  
  115.       case M_OP_DFCL:
  116.       if( (hv = GET_MACRO(tok1)) != NIL(HASH) )
  117.         break;
  118.      /* else FALLTHRU */
  119.  
  120.       case M_OP_CL:
  121.      tok2 = Expand( tok2 );
  122.      Def_macro( tok1, tok2, M_EXPANDED | flag );
  123.      FREE( tok2 );
  124.      break;
  125.  
  126.       case M_OP_CM:{
  127.      CELLPTR     cp;
  128.      STRINGPTR   sp;
  129.  
  130.      if (flag & M_PUSH) {
  131.         Error("Nested conditional definition [%s ?= %s] ignored",
  132.           tok1, tok2);
  133.      }
  134.      else {
  135.         cp = Def_cell(tok1);
  136.         if (cp->ce_flag & F_MULTI) {
  137.            LINKPTR lp;
  138.            for(lp=cp->ce_prq; lp->cl_next; lp=lp->cl_next);
  139.            cp = lp->cl_prq;
  140.         }
  141.         TALLOC(sp,1,STRING);
  142.         sp->st_string = DmStrDup(tok2);
  143.         sp->st_next   = cp->ce_cond;
  144.         cp->ce_cond   = sp;
  145.  
  146.         tok1 = NIL(char);
  147.      }
  148.       }
  149.       break;
  150.    }
  151.  
  152.    if (tok1) {        
  153.       if ( LastMacName != NIL(char) )
  154.      FREE( LastMacName );
  155.  
  156.       LastMacName = tok1;
  157.    }
  158.  
  159.    DB_RETURN( 1 );
  160. }
  161.  
  162.  
  163.  
  164. PUBLIC int
  165. Macro_op( op )/*
  166. ================
  167.    Check the passed in op string and map it to one of the macro operators */
  168. char *op;
  169. {
  170.    int ret = 0;
  171.    DB_ENTER( "macro_op" );
  172.  
  173.    if ( *op == '!' ) {
  174.       ret = M_OP_SI;
  175.       op++;
  176.    }
  177.  
  178.    switch( *op ) {
  179.       case '=': ret |= M_OP_EQ; break;
  180.       case ':': ret |= M_OP_CL; op++; break;
  181.  
  182.       case '+':
  183.      op++;
  184.          if( *op == ':' ) {
  185.         ret |= M_OP_PLCL;
  186.         op++;
  187.      }
  188.      else {
  189.         ret |= M_OP_PL;
  190.      }
  191.          break;
  192.  
  193.       case '*':
  194.      op++;
  195.          if( *op == ':' ) {
  196.         ret |= M_OP_DFCL;
  197.         op++;
  198.      }
  199.      else {
  200.         ret |= M_OP_DF;
  201.      }
  202.          break;
  203.  
  204.       case '?':
  205.      ret |= M_OP_CM;
  206.      op++;
  207.      break;
  208.    }
  209.  
  210.    if( *op != '=' )
  211.       ret = 0;
  212.    else {
  213.       op++;
  214.       
  215.       if( *op != '\0' )
  216.      ret = 0;
  217.    }
  218.  
  219.    DB_RETURN( ret );
  220. }
  221.