Add functions for processing extendable arrays of pointers to strings.

Use for the .for variables and substution items - changing the latter from
make's all conquering lst.lib functions.
Being able to index everything makes the code simpler.
No functional changes intended.
This commit is contained in:
dsl 2008-12-20 22:41:53 +00:00
parent b575edd757
commit 899813caea
5 changed files with 175 additions and 83 deletions

View File

@ -1,9 +1,10 @@
# $NetBSD: Makefile,v 1.44 2008/10/06 22:09:21 joerg Exp $
# $NetBSD: Makefile,v 1.45 2008/12/20 22:41:53 dsl Exp $
# @(#)Makefile 5.2 (Berkeley) 12/28/90
PROG= make
SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \
make.c parse.c str.c suff.c targ.c trace.c var.c util.c
SRCS+= strlist.c
SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \
lstDatum.c lstDeQueue.c lstDestroy.c lstDupl.c lstEnQueue.c \
lstFind.c lstFindFrom.c lstFirst.c lstForEach.c lstForEachFrom.c \

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.boot,v 1.17 2004/05/07 00:04:38 ross Exp $
# $NetBSD: Makefile.boot,v 1.18 2008/12/20 22:41:53 dsl Exp $
#
# a very simple makefile...
#
@ -22,7 +22,7 @@ CFLAGS= -DTARGET_MACHINE=\"${MACHINE}\" \
LIBS=
OBJ=arch.o buf.o compat.o cond.o dir.o for.o hash.o job.o main.o make.o \
parse.o str.o suff.o targ.o trace.o var.o util.o
parse.o str.o strlist.o suff.o targ.o trace.o var.o util.o
LIBOBJ= lst.lib/lstAppend.o lst.lib/lstAtEnd.o lst.lib/lstAtFront.o \
lst.lib/lstClose.o lst.lib/lstConcat.o lst.lib/lstDatum.o \

View File

@ -1,4 +1,4 @@
/* $NetBSD: for.c,v 1.37 2008/12/20 17:38:37 dsl Exp $ */
/* $NetBSD: for.c,v 1.38 2008/12/20 22:41:53 dsl Exp $ */
/*
* Copyright (c) 1992, The Regents of the University of California.
@ -30,14 +30,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: for.c,v 1.37 2008/12/20 17:38:37 dsl Exp $";
static char rcsid[] = "$NetBSD: for.c,v 1.38 2008/12/20 22:41:53 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: for.c,v 1.37 2008/12/20 17:38:37 dsl Exp $");
__RCSID("$NetBSD: for.c,v 1.38 2008/12/20 22:41:53 dsl Exp $");
#endif
#endif /* not lint */
#endif
@ -59,6 +59,7 @@ __RCSID("$NetBSD: for.c,v 1.37 2008/12/20 17:38:37 dsl Exp $");
#include "hash.h"
#include "dir.h"
#include "buf.h"
#include "strlist.h"
/*
* For statements are of the form:
@ -85,17 +86,12 @@ static int forLevel = 0; /* Nesting level */
*/
typedef struct _For {
Buffer buf; /* Body of loop */
char **vars; /* Iteration variables */
int nvars; /* # of iteration vars */
int nitem; /* # of substitution items */
Lst lst; /* List of items */
strlist_t vars; /* Iteration variables */
strlist_t items; /* Substitution items */
} For;
static For accumFor; /* Loop being accumulated */
static void ForAddVar(const char *, size_t);
static char *
@ -109,27 +105,6 @@ make_str(const char *ptr, int len)
return new_ptr;
}
/*-
*-----------------------------------------------------------------------
* ForAddVar --
* Add an iteration variable to the currently accumulating for.
*
* Results: none
* Side effects: no additional side effects.
*-----------------------------------------------------------------------
*/
static void
ForAddVar(const char *data, size_t len)
{
int nvars;
nvars = accumFor.nvars;
accumFor.nvars = nvars + 1;
accumFor.vars = bmake_realloc(accumFor.vars,
accumFor.nvars * sizeof(*accumFor.vars));
accumFor.vars[nvars] = make_str(data, len);
}
/*-
*-----------------------------------------------------------------------
* For_Eval --
@ -194,10 +169,10 @@ For_Eval(char *line)
ptr += 2;
break;
}
ForAddVar(ptr, len);
strlist_add_str(&accumFor.vars, make_str(ptr, len));
}
if (accumFor.nvars == 0) {
if (strlist_num(&accumFor.vars) == 0) {
Parse_Error(PARSE_FATAL, "no iteration variables in for");
return -1;
}
@ -208,25 +183,24 @@ For_Eval(char *line)
/*
* Make a list with the remaining words
*/
accumFor.lst = Lst_Init(FALSE);
sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE);
for (ptr = sub;; ptr += len, accumFor.nitem++) {
for (ptr = sub;; ptr += len) {
while (*ptr && isspace((unsigned char)*ptr))
ptr++;
if (*ptr == 0)
break;
for (len = 1; ptr[len] && !isspace((unsigned char)ptr[len]); len++)
continue;
Lst_AtFront(accumFor.lst, make_str(ptr, len));
strlist_add_str(&accumFor.items, make_str(ptr, len));
}
free(sub);
if (accumFor.nitem % accumFor.nvars) {
if (strlist_num(&accumFor.items) % strlist_num(&accumFor.vars)) {
Parse_Error(PARSE_FATAL,
"Wrong number of words in .for substitution list %d %d",
accumFor.nitem, accumFor.nvars);
strlist_num(&accumFor.items), strlist_num(&accumFor.vars));
/*
* Return 'success' so that the body of the .for loop is accumulated.
* The loop will have zero iterations expanded due a later test.
@ -290,42 +264,20 @@ void
For_Run(int lineno)
{
For arg;
LstNode ln;
int i, done = 0, len;
int i, len;
unsigned int item_no;
char *guy, *orig_guy, *old_guy;
char *var, *item;
arg = accumFor;
accumFor.buf = NULL;
accumFor.vars = NULL;
accumFor.nvars = 0;
accumFor.lst = NULL;
memset(&accumFor, 0, sizeof accumFor);
if (arg.nitem % arg.nvars)
item_no = strlist_num(&arg.items);
if (item_no % strlist_num(&arg.vars))
/* Error message already printed */
return;
if (Lst_Open(arg.lst) != SUCCESS)
return;
while (!done) {
/*
* due to the dumb way this is set up, this loop must run
* backwards.
*/
for (i = arg.nvars - 1; i >= 0; i--) {
ln = Lst_Next(arg.lst);
if (ln == NULL) {
done = 1;
break;
}
Var_Set(arg.vars[i], Lst_Datum(ln), VAR_GLOBAL, 0);
if (DEBUG(FOR))
(void)fprintf(debug_file, "--- %s = %s\n", arg.vars[i],
(char *)Lst_Datum(ln));
}
if (done)
break;
goto out;
while (item_no != 0) {
/*
* Hack, hack, kludge.
* This is really ugly, but to do it any better way would require
@ -334,28 +286,28 @@ For_Run(int lineno)
* for expanding a single variable. That should be corrected, but
* not right away. (XXX)
*/
guy = (char *)Buf_GetAll(arg.buf, &len);
orig_guy = guy;
for (i = 0; i < arg.nvars; i++) {
item_no -= strlist_num(&arg.vars);
STRLIST_FOREACH(var, &arg.vars, i) {
item = strlist_str(&arg.items, item_no + i);
if (DEBUG(FOR))
(void)fprintf(debug_file, "--- %s = %s\n", var, item);
Var_Set(var, item, VAR_GLOBAL, 0);
old_guy = guy;
guy = Var_Subst(arg.vars[i], guy, VAR_GLOBAL, FALSE);
guy = Var_Subst(var, guy, VAR_GLOBAL, FALSE);
if (old_guy != orig_guy)
free(old_guy);
}
Parse_SetInput(NULL, lineno, -1, guy);
for (i = 0; i < arg.nvars; i++)
Var_Delete(arg.vars[i], VAR_GLOBAL);
}
Lst_Close(arg.lst);
STRLIST_FOREACH(var, &arg.vars, i)
Var_Delete(var, VAR_GLOBAL);
for (i=0; i<arg.nvars; i++) {
free(arg.vars[i]);
}
free(arg.vars);
out:
strlist_clean(&arg.vars);
strlist_clean(&arg.items);
Lst_Destroy(arg.lst, (FreeProc *)free);
Buf_Destroy(arg.buf, TRUE);
}

85
usr.bin/make/strlist.c Normal file
View File

@ -0,0 +1,85 @@
/* $NetBSD: strlist.c,v 1.1 2008/12/20 22:41:53 dsl Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: strlist.c,v 1.1 2008/12/20 22:41:53 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: strlist.c,v 1.1 2008/12/20 22:41:53 dsl Exp $");
#endif /* not lint */
#endif
#include <stddef.h>
#include <stdlib.h>
#include "strlist.h"
#include "make.h"
void
strlist_init(strlist_t *sl)
{
sl->sl_num = 0;
sl->sl_str = NULL;
}
void
strlist_clean(strlist_t *sl)
{
char *str;
int i;
STRLIST_FOREACH(str, sl, i)
free(str);
free(sl->sl_str);
sl->sl_num = 0;
sl->sl_str = NULL;
}
void
strlist_add_str(strlist_t *sl, char *str)
{
unsigned int n;
char **new_strs;
if (str == NULL)
return;
n = sl->sl_num + 1;
sl->sl_num = n;
new_strs = bmake_realloc(sl->sl_str, (n + 1) * sizeof *sl->sl_str);
new_strs[n - 1] = str;
new_strs[n] = NULL; /* STRLIST_FOREACH() terminator */
sl->sl_str = new_strs;
}

54
usr.bin/make/strlist.h Normal file
View File

@ -0,0 +1,54 @@
/* $NetBSD: strlist.h,v 1.1 2008/12/20 22:41:53 dsl Exp $ */
/*-
* Copyright (c) 2006 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STRLIST_H
#define _STRLIST_H
typedef struct {
unsigned int sl_num;
char **sl_str;
} strlist_t;
void strlist_init(strlist_t *sl);
void strlist_clean(strlist_t *sl);
void strlist_add_str(strlist_t *sl, char *str);
#define strlist_num(sl) ((sl)->sl_num)
#define strlist_str(sl, n) ((sl)->sl_str[n])
#define STRLIST_FOREACH(v, sl, index) \
if ((sl)->sl_str != NULL) \
for (index = 0; (v = (sl)->sl_str[index]) != NULL; index++)
#endif /* _STRLIST_H */