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

  1. /* RCS      -- $Header: /u5/dvadura/src/public/dmake/src/RCS/stat.c,v 1.1 1994/10/06 17:42:01 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) 1992,1994 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  1994/10/06  17:42:01  dvadura
  32.  * dmake Release Version 4.0, Initial revision
  33.  *
  34. */
  35.  
  36. #include "extern.h"
  37.  
  38.  
  39. static    int    _check_dir_list ANSI((CELLPTR, CELLPTR, int, int));
  40.  
  41. #ifdef DBUG
  42.    /* Just a little ditty for debugging this thing */
  43.    static time_t
  44.    _do_stat( name, lib, sym, force )
  45.    char *name;
  46.    char *lib;
  47.    char **sym;
  48.    int  force;
  49.    {
  50.       time_t res;
  51.       DB_ENTER( "_do_stat" );
  52.  
  53.       res = Do_stat(name, lib, sym, force);
  54.       DB_PRINT( "stat", ("Statted [%s,%s,%d,%ld]", name, lib, sym, res) );
  55.  
  56.       DB_RETURN( res );
  57.    }   
  58. #define DO_STAT(A,B,C,D)  _do_stat(A,B,C,D)
  59. #else
  60. #define DO_STAT(A,B,C,D)  Do_stat(A,B,C,D)
  61. #endif
  62.  
  63. static char *_first;    /* local storage of first attempted path */
  64.  
  65. PUBLIC void
  66. Stat_target( cp, setfname, force )/*
  67. ====================================
  68.     Stat a target.  When doing so follow the following rules, suppose
  69.     that cp->CE_NAME points at a target called fred.o:
  70.  
  71.         0.      If A_SYMBOL attribute set look into the library
  72.             then do the steps 1 thru 4 on the resulting name.
  73.         1.    Try path's obtained by prepending any dirs found as
  74.             prerequisites for .SOURCE.o.
  75.         2.    If not found, do same as 2 but use .SOURCE
  76.         3.    If not found and .LIBRARYM attribute for the target is
  77.             set then look for it in the corresponding library.
  78.             4.    If found in step 0 thru 3, then ce_fname points at
  79.             file name associate with target, else ce_fname points
  80.             at a file name built by the first .SOURCE* dir that
  81.             applied. */
  82.  
  83. CELLPTR cp;
  84. int     setfname;
  85. int     force;
  86. {
  87.    register HASHPTR hp;
  88.    static   HASHPTR srchp = NIL(HASH);
  89.    char            *name;
  90.    char            *tmp;
  91.    int            res = 0;
  92.  
  93.    DB_ENTER( "Stat_target" );
  94.  
  95.    name = cp->CE_NAME;
  96.    if( srchp == NIL(HASH) ) srchp = Get_name(".SOURCE",Defs,FALSE);
  97.  
  98.    /* Look for a symbol of the form lib((symbol)) the name of the symbol
  99.     * as entered in the hash table is (symbol) so pull out symbol and try
  100.     * to find it's module.  If successful DO_STAT will return the module
  101.     * as well as the archive member name (pointed at by tmp).  We then
  102.     * replace the symbol name with the archive member name so that we
  103.     * have the proper name for any future refrences. */
  104.  
  105.    if( cp->ce_attr & A_SYMBOL ) {
  106.       DB_PRINT( "stat", ("Binding lib symbol [%s]", name) );
  107.  
  108.       cp->ce_time = DO_STAT( name, cp->ce_lib, &tmp, force );
  109.  
  110.       if( cp->ce_time != (time_t) 0L ) {
  111.      /* stat the new member name below  note tmp must point at a string
  112.       * returned by MALLOC... ie. the Do_stat code should use DmStrDup */
  113.  
  114.      if( Verbose & V_MAKE )
  115.         printf( "%s:  Mapped ((%s)) to %s(%s)\n", Pname,
  116.              name, cp->ce_lib, tmp );
  117.  
  118.          FREE( name );        
  119.      name = cp->CE_NAME = tmp;        
  120.      cp->ce_attr &= ~(A_FFNAME | A_SYMBOL);
  121.       }
  122.       else
  123.          { DB_VOID_RETURN; }
  124.    }
  125.  
  126.    _first = NIL(char);
  127.    tmp = DmStrJoin( ".SOURCE", Get_suffix(name), -1, FALSE);
  128.  
  129.    /* Check .SOURCE.xxx target */
  130.    if( (hp = Get_name(tmp, Defs, FALSE)) != NIL(HASH) )
  131.       res = _check_dir_list( cp, hp->CP_OWNR, setfname, force );
  132.  
  133.    /* Check just .SOURCE */
  134.    if( !res && (srchp != NIL(HASH)) )
  135.       res = _check_dir_list( cp, srchp->CP_OWNR, setfname, force );
  136.  
  137.    /* If libmember and we haven't found it check the library */
  138.    if( !res && (cp->ce_attr & A_LIBRARYM) ) {
  139.       cp->ce_time = DO_STAT(name, cp->ce_lib, NIL(char *), force);
  140.  
  141.       if( !cp->ce_time && Tmd && *Tmd && cp->ce_lib ) {
  142.      char *tmplib;
  143.      tmplib=DmStrDup(Build_path(Tmd,cp->ce_lib));
  144.  
  145.      if ((cp->ce_time = DO_STAT(name, tmplib, NIL(char *),force)) != (time_t)0L){
  146.         cp->ce_lib=DmStrDup(tmplib);
  147.      }
  148.       }
  149.  
  150.       if( Verbose & V_MAKE )
  151.      printf( "%s:  Checking library '%s' for member [%s], time %ld\n",
  152.          Pname, cp->ce_lib, name, cp->ce_time );
  153.    }
  154.  
  155.    FREE( tmp );
  156.  
  157.    if( setfname == 1 || (setfname == -1 && cp->ce_time != (time_t)0L) ) {
  158.       int setlib = (cp->ce_lib == cp->ce_fname);
  159.  
  160.       if( (cp->ce_attr & A_FFNAME) && (cp->ce_fname != NIL(char)) )
  161.      FREE( cp->ce_fname );
  162.  
  163.       if( _first != NIL(char) ) {
  164.      cp->ce_fname = _first;
  165.      cp->ce_attr |= A_FFNAME;
  166.       }
  167.       else {
  168.      cp->ce_fname = cp->CE_NAME;
  169.      cp->ce_attr &= ~A_FFNAME;
  170.       }
  171.  
  172.       if ( setlib ) cp->ce_lib = cp->ce_fname;
  173.    }
  174.    else if( _first )
  175.       FREE( _first );
  176.  
  177.    /* set it as stated only if successful, this way, we shall try again
  178.     * later. */
  179.    if( cp->ce_time != (time_t)0L ) {
  180.       cp->ce_flag |= F_STAT;
  181.  
  182.       /* If it is a whatif this changed scenario then return the current
  183.        * time, but do so only if the stat was successful. */
  184.       if ( (cp->ce_attr & A_WHATIF) && !(cp->ce_flag & F_MADE) ) {
  185.      cp->ce_time = Do_time();
  186.       }
  187.    }
  188.  
  189.    DB_VOID_RETURN;
  190. }
  191.  
  192.  
  193.  
  194. static int
  195. _check_dir_list( cp, sp, setfname, force )/*
  196. ============================================
  197.     Check the list of dir's given by the prerequisite list of sp, for a
  198.     file pointed at by cp.  Returns 0 if path not bound, else returns
  199.     1 and replaces old name for cell with new cell name. */
  200.  
  201. CELLPTR cp;
  202. CELLPTR sp;
  203. int     setfname;
  204. int     force;
  205. {
  206.    register LINKPTR lp;
  207.    char *dir;
  208.    char *path;
  209.    char *name;
  210.    int  res  = 0;
  211.    int  fset = 0;
  212.  
  213.    DB_ENTER( "_check_dir_list" );
  214.    DB_PRINT( "mem", ("%s:-> mem %ld", cp->CE_NAME, (long) coreleft()) );
  215.  
  216.    if( sp->ce_prq != NIL(LINK) )    /* check prerequisites if any */
  217.    {
  218.       /* Use the real name instead of basename, this prevents silly
  219.        * loops in inference code, and is consistent with man page */
  220.       name = cp->CE_NAME;
  221.  
  222.       /* Here we loop through each directory on the list, and try to stat
  223.        * the target.  We always save the first pathname we try to stat in
  224.        * _first.  If we subsequently get a match we then replace the value of
  225.        * _first by the matched path name.  */
  226.  
  227.       for( lp=sp->CE_PRQ; lp != NIL(LINK) && !res; lp=lp->cl_next ) {
  228.      int  nodup = 0;
  229.      dir  = lp->cl_prq->CE_NAME;
  230.  
  231.      if( strchr( dir, '$' ) ) dir = Expand(dir);
  232.      if( strcmp( dir, ".NULL" ) == 0 ) {
  233.         nodup = 1;
  234.         path = cp->CE_NAME;
  235.      }
  236.      else {
  237.         path = DmStrDup(Build_path(dir,name));
  238.      }
  239.  
  240.      res = ((cp->ce_time=DO_STAT(path,NIL(char),NIL(char *),force))!=(time_t)0L);
  241.  
  242.      /* Have to use DmStrDup to set _first since Build_path, builds it's
  243.       * path names inside a static buffer. */
  244.      if( setfname )
  245.         if( (_first == NIL(char) && !fset) || res ) {
  246.            if( _first != NIL(char) ) FREE( _first );
  247.            if (nodup)
  248.           _first = NIL(char);
  249.            else {
  250.           _first = path;
  251.           path = NIL(char);
  252.            }
  253.            fset = 1;
  254.         }
  255.  
  256.      DB_PRINT( "stat", ("_first [%s], path [%s]", _first, path) );
  257.      if( dir != lp->cl_prq->CE_NAME )  FREE(dir);
  258.      if( path && path != cp->CE_NAME ) FREE(path);
  259.       }
  260.    }
  261.  
  262.    DB_PRINT( "mem", ("%s:-< mem %ld", cp->CE_NAME, (long) coreleft()) );
  263.    DB_RETURN( res );
  264. }
  265.