Annotation of src/usr.bin/make/expandchildren.c, Revision 1.1
1.1 ! espie 1: /* $OpenBSD$ */
! 2: /* $NetBSD: suff.c,v 1.13 1996/11/06 17:59:25 christos Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1988, 1989, 1990, 1993
! 6: * The Regents of the University of California. All rights reserved.
! 7: * Copyright (c) 1989 by Berkeley Softworks
! 8: * All rights reserved.
! 9: *
! 10: * This code is derived from software contributed to Berkeley by
! 11: * Adam de Boor.
! 12: *
! 13: * Redistribution and use in source and binary forms, with or without
! 14: * modification, are permitted provided that the following conditions
! 15: * are met:
! 16: * 1. Redistributions of source code must retain the above copyright
! 17: * notice, this list of conditions and the following disclaimer.
! 18: * 2. Redistributions in binary form must reproduce the above copyright
! 19: * notice, this list of conditions and the following disclaimer in the
! 20: * documentation and/or other materials provided with the distribution.
! 21: * 3. Neither the name of the University nor the names of its contributors
! 22: * may be used to endorse or promote products derived from this software
! 23: * without specific prior written permission.
! 24: *
! 25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 35: * SUCH DAMAGE.
! 36: */
! 37:
! 38: /*-
! 39: * expandchildren.c --
! 40: * Dealing with final children expansion before building stuff
! 41: */
! 42:
! 43: #include <ctype.h>
! 44: #include <stdio.h>
! 45: #include <stdlib.h>
! 46: #include <string.h>
! 47: #include "config.h"
! 48: #include "defines.h"
! 49: #include "direxpand.h"
! 50: #include "engine.h"
! 51: #include "arch.h"
! 52: #include "expandchildren.h"
! 53: #include "var.h"
! 54: #include "targ.h"
! 55: #include "lst.h"
! 56: #include "gnode.h"
! 57: #include "suff.h"
! 58:
! 59: static void ExpandChildren(LstNode, GNode *);
! 60: static void ExpandVarChildren(LstNode, GNode *, GNode *);
! 61: static void ExpandWildChildren(LstNode, GNode *, GNode *);
! 62:
! 63: void
! 64: LinkParent(GNode *cgn, GNode *pgn)
! 65: {
! 66: Lst_AtEnd(&cgn->parents, pgn);
! 67: if (!has_been_built(cgn))
! 68: pgn->children_left++;
! 69: else if ( ! (cgn->type & (OP_EXEC|OP_USE))) {
! 70: if (cgn->built_status == REBUILT)
! 71: pgn->child_rebuilt = true;
! 72: (void)Make_TimeStamp(pgn, cgn);
! 73: }
! 74: }
! 75:
! 76: static void
! 77: ExpandVarChildren(LstNode after, GNode *cgn, GNode *pgn)
! 78: {
! 79: GNode *gn; /* New source 8) */
! 80: char *cp; /* Expanded value */
! 81: LIST members;
! 82:
! 83:
! 84: if (DEBUG(SUFF))
! 85: printf("Expanding \"%s\"...", cgn->name);
! 86:
! 87: cp = Var_Subst(cgn->name, &pgn->localvars, true);
! 88: if (cp == NULL) {
! 89: printf("Problem substituting in %s", cgn->name);
! 90: printf("\n");
! 91: return;
! 92: }
! 93:
! 94: Lst_Init(&members);
! 95:
! 96: if (cgn->type & OP_ARCHV) {
! 97: /*
! 98: * Node was an archive(member) target, so we want to call
! 99: * on the Arch module to find the nodes for us, expanding
! 100: * variables in the parent's context.
! 101: */
! 102: const char *sacrifice = (const char *)cp;
! 103:
! 104: (void)Arch_ParseArchive(&sacrifice, &members, &pgn->localvars);
! 105: } else {
! 106: /* Break the result into a vector of strings whose nodes
! 107: * we can find, then add those nodes to the members list.
! 108: * Unfortunately, we can't use brk_string because it
! 109: * doesn't understand about variable specifications with
! 110: * spaces in them... */
! 111: const char *start, *cp2;
! 112:
! 113: for (start = cp; *start == ' ' || *start == '\t'; start++)
! 114: continue;
! 115: for (cp2 = start; *cp2 != '\0';) {
! 116: if (ISSPACE(*cp2)) {
! 117: /* White-space -- terminate element, find the
! 118: * node, add it, skip any further spaces. */
! 119: gn = Targ_FindNodei(start, cp2, TARG_CREATE);
! 120: cp2++;
! 121: Lst_AtEnd(&members, gn);
! 122: while (ISSPACE(*cp2))
! 123: cp2++;
! 124: /* Adjust cp2 for increment at start of loop,
! 125: * but set start to first non-space. */
! 126: start = cp2;
! 127: } else if (*cp2 == '$')
! 128: /* Start of a variable spec -- contact variable
! 129: * module to find the end so we can skip over
! 130: * it. */
! 131: Var_ParseSkip(&cp2, &pgn->localvars);
! 132: else if (*cp2 == '\\' && cp2[1] != '\0')
! 133: /* Escaped something -- skip over it. */
! 134: cp2+=2;
! 135: else
! 136: cp2++;
! 137: }
! 138:
! 139: if (cp2 != start) {
! 140: /* Stuff left over -- add it to the list too. */
! 141: gn = Targ_FindNodei(start, cp2, TARG_CREATE);
! 142: Lst_AtEnd(&members, gn);
! 143: }
! 144: }
! 145: /* Add all elements of the members list to the parent node. */
! 146: while ((gn = Lst_DeQueue(&members)) != NULL) {
! 147: if (DEBUG(SUFF))
! 148: printf("%s...", gn->name);
! 149: if (Lst_Member(&pgn->children, gn) == NULL) {
! 150: Lst_Append(&pgn->children, after, gn);
! 151: after = Lst_Adv(after);
! 152: LinkParent(gn, pgn);
! 153: }
! 154: }
! 155: /* Free the result. */
! 156: free(cp);
! 157: if (DEBUG(SUFF))
! 158: printf("\n");
! 159: }
! 160:
! 161: static void
! 162: ExpandWildChildren(LstNode after, GNode *cgn, GNode *pgn)
! 163: {
! 164: char *cp; /* Expanded value */
! 165:
! 166: LIST exp; /* List of expansions */
! 167: Lst path; /* Search path along which to expand */
! 168:
! 169: if (DEBUG(SUFF))
! 170: printf("Wildcard expanding \"%s\"...", cgn->name);
! 171:
! 172: /* Find a path along which to expand the word: if
! 173: * the word has a known suffix, use the path for that suffix,
! 174: * otherwise use the default path. */
! 175: path = find_best_path(cgn->name);
! 176:
! 177: /* Expand the word along the chosen path. */
! 178: Lst_Init(&exp);
! 179: Dir_Expand(cgn->name, path, &exp);
! 180:
! 181: /* Fetch next expansion off the list and find its GNode. */
! 182: while ((cp = Lst_DeQueue(&exp)) != NULL) {
! 183: GNode *gn; /* New source 8) */
! 184: if (DEBUG(SUFF))
! 185: printf("%s...", cp);
! 186: gn = Targ_FindNode(cp, TARG_CREATE);
! 187:
! 188: /* If gn isn't already a child of the parent, make it so and
! 189: * up the parent's count of children to build. */
! 190: if (Lst_Member(&pgn->children, gn) == NULL) {
! 191: Lst_Append(&pgn->children, after, gn);
! 192: after = Lst_Adv(after);
! 193: LinkParent(gn, pgn);
! 194: }
! 195: }
! 196:
! 197: if (DEBUG(SUFF))
! 198: printf("\n");
! 199: }
! 200:
! 201: /*-
! 202: *-----------------------------------------------------------------------
! 203: * ExpandChildren --
! 204: * Expand the names of any children of a given node that contain
! 205: * variable invocations or file wildcards into actual targets.
! 206: *
! 207: * Side Effects:
! 208: * The expanded node is removed from the parent's list of children,
! 209: * and the parent's children to build counter is decremented,
! 210: * but other nodes may be added.
! 211: *-----------------------------------------------------------------------
! 212: */
! 213: static void
! 214: ExpandChildren(LstNode ln, /* LstNode of child, so we can replace it */
! 215: GNode *pgn)
! 216: {
! 217: GNode *cgn = Lst_Datum(ln);
! 218:
! 219: /* First do variable expansion -- this takes precedence over wildcard
! 220: * expansion. If the result contains wildcards, they'll be gotten to
! 221: * later since the resulting words are tacked on to the end of the
! 222: * children list. */
! 223: if (strchr(cgn->name, '$') != NULL)
! 224: ExpandVarChildren(ln, cgn, pgn);
! 225: else if (Dir_HasWildcards(cgn->name))
! 226: ExpandWildChildren(ln, cgn, pgn);
! 227: else
! 228: /* Third case: nothing to expand. */
! 229: return;
! 230:
! 231: /* Since the source was expanded, remove it from the list of children to
! 232: * keep it from being processed. */
! 233: pgn->children_left--;
! 234: Lst_Remove(&pgn->children, ln);
! 235: }
! 236:
! 237: void
! 238: expand_children_from(GNode *parent, LstNode from)
! 239: {
! 240: LstNode np, ln;
! 241:
! 242: for (ln = from; ln != NULL; ln = np) {
! 243: np = Lst_Adv(ln);
! 244: ExpandChildren(ln, parent);
! 245: }
! 246: }