home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / DMAKE38A.ZIP / STAT.C < prev    next >
C/C++ Source or Header  |  1992-01-23  |  8KB  |  249 lines

  1. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/stat.c,v 1.1 1992/01/24 03:27:58 dvadura Exp $
  2. -- SYNOPSIS -- bind a target name to a file.
  3. -- 
  4. -- DESCRIPTION
  5. --    This file contains the code to go and stat a target.  The stat rules
  6. --    follow a predefined order defined in the comment for Stat_target.
  7. -- 
  8. -- AUTHOR
  9. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  10. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  11. --
  12. -- COPYRIGHT
  13. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  14. -- 
  15. --      This program is free software; you can redistribute it and/or
  16. --      modify it under the terms of the GNU General Public License
  17. --      (version 1), as published by the Free Software Foundation, and
  18. --      found in the file 'LICENSE' included with this distribution.
  19. -- 
  20. --      This program is distributed in the hope that it will be useful,
  21. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  22. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23. --      GNU General Public License for more details.
  24. -- 
  25. --      You should have received a copy of the GNU General Public License
  26. --      along with this program;  if not, write to the Free Software
  27. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  28. --
  29. -- LOG
  30. --     $Log: stat.c,v $
  31.  * Revision 1.1  1992/01/24  03:27:58  dvadura
  32.  * dmake Version 3.8, Initial revision
  33.  *
  34. */
  35.  
  36. #include "extern.h"
  37.  
  38.  
  39. static    int    _check_dir_list ANSI((CELLPTR, CELLPTR, int));
  40.  
  41. #ifdef DBUG
  42.    /* Just a little ditty for debugging this thing */
  43.    static time_t
  44.    _do_stat( name, lib, sym )
  45.    char *name;
  46.    char *lib;
  47.    char **sym;
  48.    {
  49.       time_t res;
  50.       DB_ENTER( "_do_stat" );
  51.  
  52.       res = Do_stat(name, lib, sym);
  53.       DB_PRINT( "stat", ("Statted [%s,%s,%d,%ld]", name, lib, sym, res) );
  54.  
  55.       DB_RETURN( res );
  56.    }   
  57. #define DO_STAT(A,B,C)  _do_stat(A,B,C)
  58. #else
  59. #define DO_STAT(A,B,C)  Do_stat(A,B,C)
  60. #endif
  61.  
  62. static char *_first;    /* local storage of first attempted path */
  63.  
  64. PUBLIC void
  65. Stat_target( cp, setfname )/*
  66. =============================
  67.     Stat a target.  When doing so follow the following rules, suppose
  68.     that cp->CE_NAME points at a target called fred.o:
  69.  
  70.         0.      If A_SYMBOL attribute set look into the library
  71.             then do the steps 1 thru 4 on the resulting name.
  72.         1.    Try path's obtained by prepending any dirs found as
  73.             prerequisites for .SOURCE.o.
  74.         2.    If not found, do same as 2 but use .SOURCE
  75.         3.    If not found and .LIBRARYM attribute for the target is
  76.             set then look for it in the corresponding library.
  77.             4.    If found in step 0 thru 3, then ce_fname points at
  78.             file name associate with target, else ce_fname points
  79.             at a file name built by the first .SOURCE* dir that
  80.             applied. */
  81.  
  82. CELLPTR cp;
  83. int     setfname;
  84. {
  85.    register HASHPTR hp;
  86.    static   HASHPTR srchp = NIL(HASH);
  87.    char            *name;
  88.    char            *tmp;
  89.    int            res = 0;
  90.  
  91.    DB_ENTER( "Stat_target" );
  92.  
  93.    name = cp->CE_NAME;
  94.    if( srchp == NIL(HASH) ) srchp = Get_name(".SOURCE",Defs,FALSE);
  95.  
  96.    /* Look for a symbol of the form lib((symbol)) the name of the symbol
  97.     * as entered in the hash table is (symbol) so pull out symbol and try
  98.     * to find it's module.  If successful DO_STAT will return the module
  99.     * as well as the archive member name (pointed at by tmp).  We then
  100.     * replace the symbol name with the archive member name so that we
  101.     * have the proper name for any future refrences. */
  102.  
  103.    if( cp->ce_attr & A_SYMBOL ) {
  104.       DB_PRINT( "stat", ("Binding lib symbol [%s]", name) );
  105.  
  106.       cp->ce_time = DO_STAT( name, cp->ce_lib, &tmp );
  107.  
  108.       if( cp->ce_time != (time_t) 0L ) {
  109.      /* stat the new member name below  note tmp must point at a string
  110.       * returned by MALLOC... ie. the Do_stat code should use _strdup */
  111.  
  112.      if( Verbose & V_MAKE )
  113.         printf( "%s:  Mapped ((%s)) to %s(%s)\n", Pname,
  114.              name, cp->ce_lib, tmp );
  115.  
  116.          FREE( name );        
  117.      name = cp->CE_NAME = tmp;        
  118.      cp->ce_attr &= ~(A_FFNAME | A_SYMBOL);
  119.       }
  120.       else
  121.          { DB_VOID_RETURN; }
  122.    }
  123.  
  124.    _first = NIL(char);
  125.    tmp = _strjoin( ".SOURCE", Get_suffix( name ), -1, FALSE);
  126.  
  127.    /* Check .SOURCE.xxx target */
  128.    if( (hp = Get_name(tmp, Defs, FALSE)) != NIL(HASH) )
  129.       res = _check_dir_list( cp, hp->CP_OWNR, setfname );
  130.  
  131.    /* Check just .SOURCE */
  132.    if( !res && (srchp != NIL(HASH)) )
  133.       res = _check_dir_list( cp, srchp->CP_OWNR, setfname );
  134.  
  135.    /* If libmember and we haven't found it check the library */
  136.    if( !res && (cp->ce_attr & A_LIBRARYM) ) {
  137.       cp->ce_time = DO_STAT(name, cp->ce_lib, NIL(char *));
  138.  
  139.       if( !cp->ce_time && Tmd && *Tmd && cp->ce_lib ) {
  140.      cp->ce_lib=Build_path(Tmd,cp->ce_lib);
  141.      cp->ce_time = DO_STAT(name, cp->ce_lib, NIL(char *));
  142.       }
  143.  
  144.       if( Verbose & V_MAKE )
  145.      printf( "%s:  Checking library '%s' for member [%s], time %ld\n",
  146.          Pname, cp->ce_lib, name, cp->ce_time );
  147.    }
  148.  
  149.    FREE( tmp );
  150.  
  151.    if( setfname == 1 || (setfname == -1 && cp->ce_time != (time_t)0L) ) {
  152.       if( (cp->ce_attr & A_FFNAME) && (cp->ce_fname != NIL(char)) )
  153.      FREE( cp->ce_fname );
  154.  
  155.       if( _first != NIL(char) ) {
  156.      cp->ce_fname = _first;
  157.      cp->ce_attr |= A_FFNAME;
  158.       }
  159.       else {
  160.      cp->ce_fname = cp->CE_NAME;
  161.      cp->ce_attr &= ~A_FFNAME;
  162.       }
  163.    }
  164.    else if( _first )
  165.       FREE( _first );
  166.  
  167.    /* set it as stated only if successful, this way, we shall try again
  168.     * later. */
  169.    if( cp->ce_time != (time_t)0L ) cp->ce_flag |= F_STAT;
  170.  
  171.    DB_VOID_RETURN;
  172. }
  173.  
  174.  
  175.  
  176. static int
  177. _check_dir_list( cp, sp, setfname )/*
  178. =====================================
  179.     Check the list of dir's given by the prerequisite list of sp, for a
  180.     file pointed at by cp.  Returns 0 if path not bound, else returns
  181.     1 and replaces old name for cell with new cell name. */
  182.  
  183. CELLPTR cp;
  184. CELLPTR sp;
  185. int     setfname;
  186. {
  187.    register LINKPTR lp;
  188.    char *dir;
  189.    char *path;
  190.    char *name;
  191.    int  res  = 0;
  192.    int  fset = 0;
  193.  
  194.    DB_ENTER( "_check_dir_list" );
  195.    DB_PRINT( "mem", ("%s:-> mem %ld", cp->CE_NAME, (long) coreleft()) );
  196.  
  197.    if( sp->ce_prq != NIL(LINK) )    /* check prerequisites if any */
  198.    {
  199.       /* Use the real name instead of basename, this prevents silly
  200.        * loops in inference code, and is consistent with man page */
  201.       name = cp->CE_NAME;
  202.  
  203.       /* Here we loop through each directory on the list, and try to stat
  204.        * the target.  We always save the first pathname we try and stat in
  205.        * _first.  If we subsequently get a match we then replace the value of
  206.        * _first by the matched path name.  */
  207.  
  208.       for( lp=sp->CE_PRQ; lp != NIL(LINK) && !res; lp=lp->cl_next ) {
  209.      int  nodup = 0;
  210.      dir  = lp->cl_prq->CE_NAME;
  211.  
  212.      if( strchr( dir, '$' ) ) dir = Expand(dir);
  213.      if( strcmp( dir, ".NULL" ) == 0 ) {
  214.         nodup = 1;
  215.         path = cp->CE_NAME;
  216.      }
  217.      else
  218.         path = Build_path( dir, name );
  219.  
  220.      res = ((cp->ce_time = DO_STAT(path,NIL(char),NIL(char *))) != (time_t)0L);
  221. #if 0
  222. I think this will break a lot of things!
  223.      /* It didn't work and TMD macro has a value so try to stat it
  224.       * relative to the original MAKEDIR directory. */
  225.      if( Tmd && !*Tmd && !res ) {
  226.         char *p = _strdup(path);
  227.         path = Build_path(Tmd,p); FREE(p);
  228.         res = ((cp->ce_time = DO_STAT(path,NIL(char),NIL(char *))) != (time_t)0L);
  229.      }
  230. #endif
  231.  
  232.      /* Have to use _strdup to set _first since Build_path, builds it's
  233.       * path names inside a static buffer. */
  234.      if( setfname )
  235.         if( (_first == NIL(char) && !fset) || res ) {
  236.            if( _first != NIL(char) ) FREE( _first );
  237.            _first = nodup ? NIL(char) : _strdup(path);
  238.            fset = 1;
  239.         }
  240.  
  241.      DB_PRINT( "stat", ("_first [%s], path [%s]", _first, path) );
  242.      if( dir != lp->cl_prq->CE_NAME )  FREE(dir);
  243.       }
  244.    }
  245.  
  246.    DB_PRINT( "mem", ("%s:-< mem %ld", cp->CE_NAME, (long) coreleft()) );
  247.    DB_RETURN( res );
  248. }
  249.