Mon Jan 25 19:10:57 2021 UTC ()
make(1): extract ForLoop_New to separate function


(rillig)
diff -r1.136 -r1.137 src/usr.bin/make/for.c

cvs diff -r1.136 -r1.137 src/usr.bin/make/for.c (expand / switch to unified diff)

--- src/usr.bin/make/for.c 2021/01/25 19:05:39 1.136
+++ src/usr.bin/make/for.c 2021/01/25 19:10:57 1.137
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: for.c,v 1.136 2021/01/25 19:05:39 rillig Exp $ */ 1/* $NetBSD: for.c,v 1.137 2021/01/25 19:10:57 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1992, The Regents of the University of California. 4 * Copyright (c) 1992, The Regents of the University of California.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -48,75 +48,93 @@ @@ -48,75 +48,93 @@
48 * body is scanned for variable expressions, and those that match the variable 48 * body is scanned for variable expressions, and those that match the variable
49 * names are replaced with expressions of the form ${:U...} or $(:U...). 49 * names are replaced with expressions of the form ${:U...} or $(:U...).
50 * After that, the body is treated like a file from an .include directive. 50 * After that, the body is treated like a file from an .include directive.
51 * 51 *
52 * Interface: 52 * Interface:
53 * For_Eval Evaluate the loop in the passed line. 53 * For_Eval Evaluate the loop in the passed line.
54 * 54 *
55 * For_Run Run accumulated loop 55 * For_Run Run accumulated loop
56 */ 56 */
57 57
58#include "make.h" 58#include "make.h"
59 59
60/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */ 60/* "@(#)for.c 8.1 (Berkeley) 6/6/93" */
61MAKE_RCSID("$NetBSD: for.c,v 1.136 2021/01/25 19:05:39 rillig Exp $"); 61MAKE_RCSID("$NetBSD: for.c,v 1.137 2021/01/25 19:10:57 rillig Exp $");
62 62
63static int forLevel = 0; /* Nesting level */ 
64 63
65/* One of the variables to the left of the "in" in a .for loop. */ 64/* One of the variables to the left of the "in" in a .for loop. */
66typedef struct ForVar { 65typedef struct ForVar {
67 char *name; 66 char *name;
68 size_t nameLen; 67 size_t nameLen;
69} ForVar; 68} ForVar;
70 69
71typedef struct ForLoop { 70typedef struct ForLoop {
72 Buffer body; /* Unexpanded body of the loop */ 71 Buffer body; /* Unexpanded body of the loop */
73 Vector /* of ForVar */ vars; /* Iteration variables */ 72 Vector /* of ForVar */ vars; /* Iteration variables */
74 Words items; /* Substitution items */ 73 Words items; /* Substitution items */
75 Buffer curBody; /* Expanded body of the current iteration */ 74 Buffer curBody; /* Expanded body of the current iteration */
76 /* Is any of the names 1 character long? If so, when the variable values 75 /* Is any of the names 1 character long? If so, when the variable values
77 * are substituted, the parser must handle $V expressions as well, not 76 * are substituted, the parser must handle $V expressions as well, not
78 * only ${V} and $(V). */ 77 * only ${V} and $(V). */
79 Boolean short_var; 78 Boolean short_var;
80 unsigned int sub_next; /* Where to continue iterating */ 79 unsigned int sub_next; /* Where to continue iterating */
81} ForLoop; 80} ForLoop;
82 81
 82
83static ForLoop *accumFor; /* Loop being accumulated */ 83static ForLoop *accumFor; /* Loop being accumulated */
 84static int forLevel = 0; /* Nesting level */
84 85
85static void 86
86ForLoop_AddVar(ForLoop *f, const char *name, size_t len) 87static ForLoop *
 88ForLoop_New(void)
87{ 89{
88 ForVar *var = Vector_Push(&f->vars); 90 ForLoop *f = bmake_malloc(sizeof *f);
89 var->name = bmake_strldup(name, len); 91
90 var->nameLen = len; 92 Buf_Init(&f->body);
 93 Vector_Init(&f->vars, sizeof(ForVar));
 94 f->items.words = NULL;
 95 f->items.freeIt = NULL;
 96 Buf_Init(&f->curBody);
 97 f->short_var = FALSE;
 98 f->sub_next = 0;
 99
 100 return f;
91} 101}
92 102
93static void 103static void
94ForLoop_Free(ForLoop *f) 104ForLoop_Free(ForLoop *f)
95{ 105{
96 Buf_Destroy(&f->body, TRUE); 106 Buf_Destroy(&f->body, TRUE);
97 107
98 while (f->vars.len > 0) { 108 while (f->vars.len > 0) {
99 ForVar *var = Vector_Pop(&f->vars); 109 ForVar *var = Vector_Pop(&f->vars);
100 free(var->name); 110 free(var->name);
101 } 111 }
102 Vector_Done(&f->vars); 112 Vector_Done(&f->vars);
103 113
104 Words_Free(f->items); 114 Words_Free(f->items);
105 Buf_Destroy(&f->curBody, TRUE); 115 Buf_Destroy(&f->curBody, TRUE);
106 116
107 free(f); 117 free(f);
108} 118}
109 119
 120static void
 121ForLoop_AddVar(ForLoop *f, const char *name, size_t len)
 122{
 123 ForVar *var = Vector_Push(&f->vars);
 124 var->name = bmake_strldup(name, len);
 125 var->nameLen = len;
 126}
 127
110static Boolean 128static Boolean
111IsFor(const char *p) 129IsFor(const char *p)
112{ 130{
113 return p[0] == 'f' && p[1] == 'o' && p[2] == 'r' && ch_isspace(p[3]); 131 return p[0] == 'f' && p[1] == 'o' && p[2] == 'r' && ch_isspace(p[3]);
114} 132}
115 133
116static Boolean 134static Boolean
117IsEndfor(const char *p) 135IsEndfor(const char *p)
118{ 136{
119 return p[0] == 'e' && strncmp(p, "endfor", 6) == 0 && 137 return p[0] == 'e' && strncmp(p, "endfor", 6) == 0 &&
120 (p[6] == '\0' || ch_isspace(p[6])); 138 (p[6] == '\0' || ch_isspace(p[6]));
121} 139}
122 140
@@ -144,34 +162,27 @@ For_Eval(const char *line) @@ -144,34 +162,27 @@ For_Eval(const char *line)
144 if (!IsFor(p)) { 162 if (!IsFor(p)) {
145 if (IsEndfor(p)) { 163 if (IsEndfor(p)) {
146 Parse_Error(PARSE_FATAL, "for-less endfor"); 164 Parse_Error(PARSE_FATAL, "for-less endfor");
147 return -1; 165 return -1;
148 } 166 }
149 return 0; 167 return 0;
150 } 168 }
151 p += 3; 169 p += 3;
152 170
153 /* 171 /*
154 * we found a for loop, and now we are going to parse it. 172 * we found a for loop, and now we are going to parse it.
155 */ 173 */
156 174
157 f = bmake_malloc(sizeof *f); 175 f = ForLoop_New();
158 Buf_Init(&f->body); 
159 Vector_Init(&f->vars, sizeof(ForVar)); 
160 f->items.words = NULL; 
161 f->items.freeIt = NULL; 
162 Buf_Init(&f->curBody); 
163 f->short_var = FALSE; 
164 f->sub_next = 0; 
165 176
166 /* Grab the variables. Terminate on "in". */ 177 /* Grab the variables. Terminate on "in". */
167 for (;;) { 178 for (;;) {
168 size_t len; 179 size_t len;
169 180
170 cpp_skip_whitespace(&p); 181 cpp_skip_whitespace(&p);
171 if (*p == '\0') { 182 if (*p == '\0') {
172 Parse_Error(PARSE_FATAL, "missing `in' in for"); 183 Parse_Error(PARSE_FATAL, "missing `in' in for");
173 ForLoop_Free(f); 184 ForLoop_Free(f);
174 return -1; 185 return -1;
175 } 186 }
176 187
177 /* 188 /*