diff -uBb misc.c-orig misc.c

--- misc.c-orig	Fri Dec 22 08:04:38 2000

+++ misc.c	Fri Dec 22 08:05:54 2000

@@ -627,8 +627,11 @@

     char trgnam[MMK_S_FILE], tmpsfx[MMK_S_SFX], fspec[MMK_S_FILE], *cp;

     unsigned int status;

     int pass, passmax, check_cms, trgnamlen, maybes, i;

+    int nofileok;

 

     maybes = 0;

+    nofileok = (generalize & 0x10) != 0;

+    generalize = generalize & 0x0F;

 

 /*

 **  When there's just one rule for this suffix pair, we want to avoid

@@ -641,6 +644,8 @@

 **  _just_ the prefixed rules.  When we call with generalize == 2, we

 **  want to check _just_ the non-prefixed rules.

 **

+**  when we call with generalize +16, we don't care if the file exists.

+**

 **  Phew! Now I understand why NMAKE doesn't have generic rules that

 **  work across directories.

 */

@@ -690,6 +695,7 @@

     	    memcpy(fspec+r->srcpfxlen, trgnam, trgnamlen);

     	    strcpy(fspec+(r->srcpfxlen+trgnamlen), r->src);

     	    if (check_cms) status = cms_get_rdt(fspec, 0, &rdt);

+    	    else if (nofileok) status = 1;

     	    else status = file_exists(fspec, 0);

     	    if (OK(status)) break;

 /*

diff -uBb readdesc.c-orig readdesc.c

--- readdesc.c-orig	Mon May 22 14:25:13 2000

+++ readdesc.c	Fri Dec 22 10:15:49 2000

@@ -62,6 +62,7 @@

     static void strip_comments(char *, char *);

     static void Process_Deferred_Dependencies(void);

     static void Fill_In_Missing_Sources(void);

+    static int Find_Usable_Object(struct SFX *s, struct DEPEND *dep);

 

 

 /*

@@ -357,12 +358,7 @@

 static void Fill_In_Missing_Sources (void) {

 

     struct DEPEND *dep;

-    struct OBJECT *obj, *obj2;

-    struct OBJREF *o;

-    struct RULE *r, *xr;

     struct SFX *s;

-    char trgnam[MMK_S_FILE];

-    int need_extra_source, trgnamlen;

 

 /*

 **  We only need to fill in sources when the target is a file _and_

@@ -373,35 +369,96 @@

     	if (dep->cmdqptr != 0 && dep->cmdqptr->flink != dep->cmdqptr) continue;

     	s = find_suffix(dep->target->sfx);

     	if (s) {

-    	    need_extra_source = 1;

-    	    for (o = dep->sources.flink; o != &dep->sources; o = o->flink) {

-    	    	if (o->obj->type != MMK_K_OBJ_FILE) continue;

-    	    	if (find_rule(dep->target->sfx, o->obj->sfx)) {

-    	    	    need_extra_source = 0;

-    	    	    break;

+        Find_Usable_Object(s, dep);

     	    	}

     	    }

-    	    if (need_extra_source) {

+} /* Fill_In_Missing_Sources */

+

 

-    	    	for (; s != &suffixes; s = s->flink) {

+static int

+Find_Usable_Object(struct SFX *s, struct DEPEND *dep)

+{

     	    	    int check_cms, slen;

+    struct SFX *s2;

+    struct RULE *r, *xr;

+    struct OBJECT *obj, *obj2;

+    struct OBJREF *o;

+    struct DEPEND *dep2;

+    char trgnam[MMK_S_FILE], tfile[MMK_S_FILE], sfile[MMK_S_FILE];

+    int trgnamlen;

 /*

 **  Don't use the CMS suffixes if we're not using CMS

 */

     	    	    slen = strlen(s->value);

     	    	    check_cms = s->value[slen-1] == '~';

-    	    	    if (check_cms && !use_cms) continue;

+    if (check_cms && !use_cms) return 0;

+/*

+**  go through suffixes, looking for one that (a) will get us to the

+**  desired suffix, and (b) has a source file.  If (a) and not (b)

+**  then recurse to find how to get the intermediate suffix (implicit

+**  rule chaining)

+*/

+    extract_name(tfile, dep->target->name);

+

+    for (s2 = s->flink; s2 != &suffixes; s2 = s2->flink) {

+

+/*      first check for an explicit rule */

+

+        for (dep2 = dependencies.flink; dep2 != &dependencies; dep2 = dep2->flink) {

+            if (dep2->target->type != MMK_K_OBJ_FILE) continue;

+            if (dep2->cmdqptr == 0 || dep2->cmdqptr->flink == dep2->cmdqptr) continue;

+            if (strcmp(dep2->target->sfx, s2->value) != 0) continue;

+            trgnamlen = extract_name(sfile, dep2->target->name);

+            if (strcmp(tfile, sfile) != 0) continue;

+

+            obj = mem_get_object();

+            memcpy(obj->name, tfile, trgnamlen);

+            strcpy(obj->name+trgnamlen, s2->value);

+            strcpy(obj->sfx, s2->value);

+            obj->type = MMK_K_OBJ_FILE;

+            if ((obj2 = Find_Object(obj)) == NULL) {

+                Insert_Object(obj);

+            } else {

+                mem_free_object(obj);

+                obj = obj2;

+            }

 

-    	    	    xr = find_rule(dep->target->sfx, s->value);

+            o = mem_get_objref();

+            o->obj = obj;

+            queue_insert(o, &dep->sources);

+            return 1;           /* signal all recursions OK, store object! */

+        }

+

+/*

+**      find a rule to get from s2 suffix to s suffix

+*/

+        xr = find_rule(s->value, s2->value);         

+/*

+**      found a rule, see if source file exists

+*/

     	    	    if (xr != 0) {

     	    	    	r = scan_rule_list(xr, dep->target->name, 0);

-    	    	    	if (r != 0) {

+/*

+**          if r: 

+**          got source file, so all previous recursions okay too, store result

+*/

+            if (!r) {

+/*

+**              rule is okay, but no source file

+**              recurse to try and build this suffix from other sources

+**              if not, then have to try next suffix

+*/

+                if (!Find_Usable_Object(s2, dep)) continue;

+                r = scan_rule_list(xr, dep->target->name, 0x10);

+                if (!r) continue;  /* should this ever happen? I think not*/

+            }

+

     	    	    	    obj = mem_get_object();

     	    	    	    trgnamlen = extract_filename(trgnam, dep->target->name);

     	    	    	    memcpy(obj->name, r->srcpfx, r->srcpfxlen);

     	    	    	    memcpy(obj->name+r->srcpfxlen, trgnam, trgnamlen);

-    	    	    	    strcpy(obj->name+(r->srcpfxlen+trgnamlen), s->value);

-    	    	    	    strcpy(obj->sfx, s->value);

+            strcpy(obj->name+(r->srcpfxlen+trgnamlen), s2->value);

+            strcpy(obj->sfx, s2->value);

     	    	    	    obj->type = MMK_K_OBJ_FILE;

     	    	    	    if ((obj2 = Find_Object(obj)) == NULL) {

     	    	    	    	Insert_Object(obj);

@@ -412,11 +470,9 @@

     	    	    	    o = mem_get_objref();

     	    	    	    o->obj = obj;

     	    	    	    queue_insert(o, &dep->sources);

-    	    	    	    break;

-    	    	    	}

+            return 1;           /* signal all recursions OK, store object! */

     	    	    }

     	    	}

-    	    }

-    	}

-    }

-} /* Fill_In_Missing_Sources */

+/*  no suffixes worked, report failure */

+    return 0;

+}

