Print this page
make: unifdef SUN5_0 (defined)
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/make/bin/files.cc
+++ new/usr/src/cmd/make/bin/files.cc
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 27 * files.c
28 28 *
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
29 29 * Various file related routines:
30 30 * Figure out if file exists
31 31 * Wildcard resolution for directory reader
32 32 * Directory reader
33 33 */
34 34
35 35
36 36 /*
37 37 * Included files
38 38 */
39 -#if defined(SUN5_0) || defined(HP_UX)
40 39 #include <dirent.h> /* opendir() */
41 -#else
42 -#include <sys/dir.h> /* opendir() */
43 -#endif
44 40 #include <errno.h> /* errno */
45 41 #include <mk/defs.h>
46 42 #include <mksh/macro.h> /* getvar() */
47 43 #include <mksh/misc.h> /* get_prop(), append_prop() */
48 44 #include <sys/stat.h> /* lstat() */
49 45
50 46 /*
51 47 * Defined macros
52 48 */
53 49
54 50 /*
55 51 * typedefs & structs
56 52 */
57 53
58 54 /*
59 55 * Static variables
60 56 */
61 57
62 58 /*
63 59 * File table of contents
64 60 */
65 61 extern timestruc_t& exists(register Name target);
66 62 extern void set_target_stat(register Name target, struct stat buf);
67 63 static timestruc_t& vpath_exists(register Name target);
68 64 static Name enter_file_name(wchar_t *name_string, wchar_t *library);
69 65 static Boolean star_match(register char *string, register char *pattern);
70 66 static Boolean amatch(register wchar_t *string, register wchar_t *pattern);
71 67
72 68 /*
73 69 * exists(target)
74 70 *
75 71 * Figure out the timestamp for one target.
76 72 *
77 73 * Return value:
78 74 * The time the target was created
79 75 *
80 76 * Parameters:
81 77 * target The target to check
82 78 *
83 79 * Global variables used:
84 80 * debug_level Should we trace the stat call?
85 81 * recursion_level Used for tracing
86 82 * vpath_defined Was the variable VPATH defined in environment?
87 83 */
88 84 timestruc_t&
89 85 exists(register Name target)
90 86 {
91 87 struct stat buf;
92 88 register int result;
93 89
94 90 /* We cache stat information. */
95 91 if (target->stat.time != file_no_time) {
96 92 return target->stat.time;
97 93 }
98 94
99 95 /*
100 96 * If the target is a member, we have to extract the time
101 97 * from the archive.
102 98 */
103 99 if (target->is_member &&
104 100 (get_prop(target->prop, member_prop) != NULL)) {
105 101 return read_archive(target);
106 102 }
107 103
108 104 if (debug_level > 1) {
109 105 (void) printf(NOCATGETS("%*sstat(%s)\n"),
110 106 recursion_level,
111 107 "",
112 108 target->string_mb);
113 109 }
114 110
115 111 result = lstat_vroot(target->string_mb, &buf, NULL, VROOT_DEFAULT);
116 112 if ((result != -1) && ((buf.st_mode & S_IFMT) == S_IFLNK)) {
117 113 /*
118 114 * If the file is a symbolic link, we remember that
119 115 * and then we get the status for the refd file.
120 116 */
121 117 target->stat.is_sym_link = true;
122 118 result = stat_vroot(target->string_mb, &buf, NULL, VROOT_DEFAULT);
123 119 } else {
124 120 target->stat.is_sym_link = false;
125 121 }
126 122
127 123 if (result < 0) {
128 124 target->stat.time = file_doesnt_exist;
129 125 target->stat.stat_errno = errno;
130 126 if ((errno == ENOENT) &&
131 127 vpath_defined &&
132 128 /* azv, fixing bug 1262942, VPATH works with a leaf name
133 129 * but not a directory name.
134 130 */
135 131 (target->string_mb[0] != (int) slash_char) ) {
136 132 /* BID_1214655 */
137 133 /* azv */
138 134 vpath_exists(target);
139 135 // return vpath_exists(target);
140 136 }
141 137 } else {
142 138 /* Save all the information we need about the file */
143 139 target->stat.stat_errno = 0;
144 140 target->stat.is_file = true;
145 141 target->stat.mode = buf.st_mode & 0777;
146 142 target->stat.size = buf.st_size;
147 143 target->stat.is_dir =
148 144 BOOLEAN((buf.st_mode & S_IFMT) == S_IFDIR);
149 145 if (target->stat.is_dir) {
150 146 target->stat.time = file_is_dir;
151 147 } else {
152 148 /* target->stat.time = buf.st_mtime; */
153 149 /* BID_1129806 */
154 150 /* vis@nbsp.nsk.su */
155 151 #if defined(linux)
156 152 timestruc_t ttime = { buf.st_mtime, 0 };
157 153 target->stat.time = MAX(ttime, file_min_time);
158 154 #else
159 155 target->stat.time = MAX(buf.st_mtim, file_min_time);
160 156 #endif
161 157 }
162 158 }
163 159 if ((target->colon_splits > 0) &&
164 160 (get_prop(target->prop, time_prop) == NULL)) {
165 161 append_prop(target, time_prop)->body.time.time =
166 162 target->stat.time;
167 163 }
168 164 return target->stat.time;
169 165 }
170 166
171 167 /*
172 168 * set_target_stat( target, buf)
173 169 *
174 170 * Called by exists() to set some stat fields in the Name structure
175 171 * to those read by the stat_vroot() call (from disk).
176 172 *
177 173 * Parameters:
178 174 * target The target whose stat field is set
179 175 * buf stat values (on disk) of the file
180 176 * represented by target.
181 177 */
182 178 void
183 179 set_target_stat(register Name target, struct stat buf)
184 180 {
185 181 target->stat.stat_errno = 0;
186 182 target->stat.is_file = true;
187 183 target->stat.mode = buf.st_mode & 0777;
188 184 target->stat.size = buf.st_size;
189 185 target->stat.is_dir =
190 186 BOOLEAN((buf.st_mode & S_IFMT) == S_IFDIR);
191 187 if (target->stat.is_dir) {
192 188 target->stat.time = file_is_dir;
193 189 } else {
194 190 /* target->stat.time = buf.st_mtime; */
195 191 /* BID_1129806 */
196 192 /* vis@nbsp.nsk.su */
197 193 #if defined(linux)
198 194 timestruc_t ttime = { buf.st_mtime, 0 };
199 195 target->stat.time = ttime;
200 196 #else
201 197 target->stat.time = MAX(buf.st_mtim, file_min_time);
202 198 #endif
203 199 }
204 200 }
205 201
206 202
207 203 /*
208 204 * vpath_exists(target)
209 205 *
210 206 * Called if exists() discovers that there is a VPATH defined.
211 207 * This function stats the VPATH translation of the target.
212 208 *
213 209 * Return value:
214 210 * The time the target was created
215 211 *
216 212 * Parameters:
217 213 * target The target to check
218 214 *
219 215 * Global variables used:
220 216 * vpath_name The Name "VPATH", used to get macro value
221 217 */
222 218 static timestruc_t&
223 219 vpath_exists(register Name target)
224 220 {
225 221 wchar_t *vpath;
226 222 wchar_t file_name[MAXPATHLEN];
227 223 wchar_t *name_p;
228 224 Name alias;
229 225
230 226 /*
231 227 * To avoid recursive search through VPATH when exists(alias) is called
232 228 */
233 229 vpath_defined = false;
234 230
235 231 Wstring wcb(getvar(vpath_name));
236 232 Wstring wcb1(target);
237 233
238 234 vpath = wcb.get_string();
239 235
240 236 while (*vpath != (int) nul_char) {
241 237 name_p = file_name;
242 238 while ((*vpath != (int) colon_char) &&
243 239 (*vpath != (int) nul_char)) {
244 240 *name_p++ = *vpath++;
245 241 }
246 242 *name_p++ = (int) slash_char;
247 243 (void) wscpy(name_p, wcb1.get_string());
248 244 alias = GETNAME(file_name, FIND_LENGTH);
249 245 if (exists(alias) != file_doesnt_exist) {
250 246 target->stat.is_file = true;
251 247 target->stat.mode = alias->stat.mode;
252 248 target->stat.size = alias->stat.size;
253 249 target->stat.is_dir = alias->stat.is_dir;
254 250 target->stat.time = alias->stat.time;
255 251 maybe_append_prop(target, vpath_alias_prop)->
256 252 body.vpath_alias.alias = alias;
257 253 target->has_vpath_alias_prop = true;
258 254 vpath_defined = true;
259 255 return alias->stat.time;
260 256 }
261 257 while ((*vpath != (int) nul_char) &&
262 258 ((*vpath == (int) colon_char) || iswspace(*vpath))) {
263 259 vpath++;
264 260 }
265 261 }
266 262 /*
267 263 * Restore vpath_defined
268 264 */
269 265 vpath_defined = true;
270 266 return target->stat.time;
271 267 }
272 268
273 269 /*
274 270 * read_dir(dir, pattern, line, library)
275 271 *
276 272 * Used to enter the contents of directories into makes namespace.
277 273 * Presence of a file is important when scanning for implicit rules.
278 274 * read_dir() is also used to expand wildcards in dependency lists.
279 275 *
280 276 * Return value:
281 277 * Non-0 if we found files to match the pattern
282 278 *
283 279 * Parameters:
284 280 * dir Path to the directory to read
285 281 * pattern Pattern for that files should match or NULL
286 282 * line When we scan using a pattern we enter files
287 283 * we find as dependencies for this line
288 284 * library If we scan for "lib.a(<wildcard-member>)"
289 285 *
290 286 * Global variables used:
291 287 * debug_level Should we trace the dir reading?
292 288 * dot The Name ".", compared against
293 289 * sccs_dir_path The path to the SCCS dir (from PROJECTDIR)
294 290 * vpath_defined Was the variable VPATH defined in environment?
295 291 * vpath_name The Name "VPATH", use to get macro value
296 292 */
297 293 int
298 294 read_dir(Name dir, wchar_t *pattern, Property line, wchar_t *library)
↓ open down ↓ |
245 lines elided |
↑ open up ↑ |
299 295 {
300 296 wchar_t file_name[MAXPATHLEN];
301 297 wchar_t *file_name_p = file_name;
302 298 Name file;
303 299 wchar_t plain_file_name[MAXPATHLEN];
304 300 wchar_t *plain_file_name_p;
305 301 Name plain_file;
306 302 wchar_t tmp_wcs_buffer[MAXPATHLEN];
307 303 DIR *dir_fd;
308 304 int m_local_dependency=0;
309 -#if defined(SUN5_0) || defined(HP_UX)
310 305 #define d_fileno d_ino
311 306 register struct dirent *dp;
312 -#else
313 - register struct direct *dp;
314 -#endif
315 307 wchar_t *vpath = NULL;
316 308 wchar_t *p;
317 309 int result = 0;
318 310
319 311 if(dir->hash.length >= MAXPATHLEN) {
320 312 return 0;
321 313 }
322 314
323 315 Wstring wcb(dir);
324 316 Wstring vps;
325 317
326 318 /* A directory is only read once unless we need to expand wildcards. */
327 319 if (pattern == NULL) {
328 320 if (dir->has_read_dir) {
329 321 return 0;
330 322 }
331 323 dir->has_read_dir = true;
332 324 }
333 325 /* Check if VPATH is active and setup list if it is. */
334 326 if (vpath_defined && (dir == dot)) {
335 327 vps.init(getvar(vpath_name));
336 328 vpath = vps.get_string();
337 329 }
338 330
339 331 /*
340 332 * Prepare the string where we build the full name of the
341 333 * files in the directory.
342 334 */
343 335 if ((dir->hash.length > 1) || (wcb.get_string()[0] != (int) period_char)) {
344 336 (void) wscpy(file_name, wcb.get_string());
345 337 MBSTOWCS(wcs_buffer, "/");
346 338 (void) wscat(file_name, wcs_buffer);
347 339 file_name_p = file_name + wslen(file_name);
348 340 }
349 341
350 342 /* Open the directory. */
351 343 vpath_loop:
352 344 dir_fd = opendir(dir->string_mb);
353 345 if (dir_fd == NULL) {
354 346 return 0;
355 347 }
356 348
357 349 /* Read all the directory entries. */
358 350 while ((dp = readdir(dir_fd)) != NULL) {
359 351 /* We ignore "." and ".." */
360 352 if ((dp->d_fileno == 0) ||
361 353 ((dp->d_name[0] == (int) period_char) &&
362 354 ((dp->d_name[1] == 0) ||
363 355 ((dp->d_name[1] == (int) period_char) &&
364 356 (dp->d_name[2] == 0))))) {
365 357 continue;
366 358 }
367 359 /*
368 360 * Build the full name of the file using whatever
369 361 * path supplied to the function.
370 362 */
371 363 MBSTOWCS(tmp_wcs_buffer, dp->d_name);
372 364 (void) wscpy(file_name_p, tmp_wcs_buffer);
373 365 file = enter_file_name(file_name, library);
374 366 if ((pattern != NULL) && amatch(tmp_wcs_buffer, pattern)) {
375 367 /*
376 368 * If we are expanding a wildcard pattern, we
377 369 * enter the file as a dependency for the target.
378 370 */
379 371 if (debug_level > 0){
380 372 WCSTOMBS(mbs_buffer, pattern);
381 373 (void) printf(catgets(catd, 1, 231, "'%s: %s' due to %s expansion\n"),
382 374 line->body.line.target->string_mb,
383 375 file->string_mb,
384 376 mbs_buffer);
385 377 }
386 378 enter_dependency(line, file, false);
387 379 result++;
388 380 } else {
389 381 /*
390 382 * If the file has an SCCS/s. file,
391 383 * we will detect that later on.
392 384 */
393 385 file->stat.has_sccs = NO_SCCS;
394 386 /*
395 387 * If this is an s. file, we also enter it as if it
396 388 * existed in the plain directory.
397 389 */
398 390 if ((dp->d_name[0] == 's') &&
399 391 (dp->d_name[1] == (int) period_char)) {
400 392
401 393 MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
402 394 plain_file_name_p = plain_file_name;
403 395 (void) wscpy(plain_file_name_p, tmp_wcs_buffer);
404 396 plain_file = GETNAME(plain_file_name, FIND_LENGTH);
405 397 plain_file->stat.is_file = true;
406 398 plain_file->stat.has_sccs = HAS_SCCS;
407 399 /*
408 400 * Enter the s. file as a dependency for the
409 401 * plain file.
410 402 */
411 403 maybe_append_prop(plain_file, sccs_prop)->
412 404 body.sccs.file = file;
413 405 MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
414 406 if ((pattern != NULL) &&
415 407 amatch(tmp_wcs_buffer, pattern)) {
416 408 if (debug_level > 0) {
417 409 WCSTOMBS(mbs_buffer, pattern);
418 410 (void) printf(catgets(catd, 1, 232, "'%s: %s' due to %s expansion\n"),
419 411 line->body.line.target->
420 412 string_mb,
421 413 plain_file->string_mb,
422 414 mbs_buffer);
423 415 }
424 416 enter_dependency(line, plain_file, false);
425 417 result++;
426 418 }
427 419 }
428 420 }
429 421 }
430 422 (void) closedir(dir_fd);
431 423 if ((vpath != NULL) && (*vpath != (int) nul_char)) {
432 424 while ((*vpath != (int) nul_char) &&
433 425 (iswspace(*vpath) || (*vpath == (int) colon_char))) {
434 426 vpath++;
435 427 }
436 428 p = vpath;
437 429 while ((*vpath != (int) colon_char) &&
438 430 (*vpath != (int) nul_char)) {
439 431 vpath++;
440 432 }
441 433 if (vpath > p) {
442 434 dir = GETNAME(p, vpath - p);
443 435 goto vpath_loop;
444 436 }
445 437 }
446 438 /*
447 439 * look into SCCS directory only if it's not svr4. For svr4 dont do that.
448 440 */
449 441
450 442 /*
451 443 * Now read the SCCS directory.
452 444 * Files in the SCSC directory are considered to be part of the set of
453 445 * files in the plain directory. They are also entered in their own right.
454 446 * Prepare the string where we build the true name of the SCCS files.
455 447 */
456 448 (void) wsncpy(plain_file_name,
457 449 file_name,
458 450 file_name_p - file_name);
459 451 plain_file_name[file_name_p - file_name] = 0;
460 452 plain_file_name_p = plain_file_name + wslen(plain_file_name);
461 453
462 454 if(!svr4) {
463 455
464 456 if (sccs_dir_path != NULL) {
465 457 wchar_t tmp_wchar;
466 458 wchar_t path[MAXPATHLEN];
467 459 char mb_path[MAXPATHLEN];
468 460
469 461 if (file_name_p - file_name > 0) {
470 462 tmp_wchar = *file_name_p;
471 463 *file_name_p = 0;
472 464 WCSTOMBS(mbs_buffer, file_name);
473 465 (void) sprintf(mb_path, NOCATGETS("%s/%s/SCCS"),
474 466 sccs_dir_path,
475 467 mbs_buffer);
476 468 *file_name_p = tmp_wchar;
477 469 } else {
478 470 (void) sprintf(mb_path, NOCATGETS("%s/SCCS"), sccs_dir_path);
479 471 }
480 472 MBSTOWCS(path, mb_path);
481 473 (void) wscpy(file_name, path);
482 474 } else {
483 475 MBSTOWCS(wcs_buffer, NOCATGETS("SCCS"));
484 476 (void) wscpy(file_name_p, wcs_buffer);
485 477 }
486 478 } else {
487 479 MBSTOWCS(wcs_buffer, NOCATGETS("."));
488 480 (void) wscpy(file_name_p, wcs_buffer);
489 481 }
490 482 /* Internalize the constructed SCCS dir name. */
491 483 (void) exists(dir = GETNAME(file_name, FIND_LENGTH));
492 484 /* Just give up if the directory file doesnt exist. */
493 485 if (!dir->stat.is_file) {
494 486 return result;
495 487 }
496 488 /* Open the directory. */
497 489 dir_fd = opendir(dir->string_mb);
498 490 if (dir_fd == NULL) {
499 491 return result;
500 492 }
501 493 MBSTOWCS(wcs_buffer, "/");
502 494 (void) wscat(file_name, wcs_buffer);
503 495 file_name_p = file_name + wslen(file_name);
504 496
505 497 while ((dp = readdir(dir_fd)) != NULL) {
506 498 if ((dp->d_fileno == 0) ||
507 499 ((dp->d_name[0] == (int) period_char) &&
508 500 ((dp->d_name[1] == 0) ||
509 501 ((dp->d_name[1] == (int) period_char) &&
510 502 (dp->d_name[2] == 0))))) {
511 503 continue;
512 504 }
513 505 /* Construct and internalize the true name of the SCCS file. */
514 506 MBSTOWCS(wcs_buffer, dp->d_name);
515 507 (void) wscpy(file_name_p, wcs_buffer);
516 508 file = GETNAME(file_name, FIND_LENGTH);
517 509 file->stat.is_file = true;
518 510 file->stat.has_sccs = NO_SCCS;
519 511 /*
520 512 * If this is an s. file, we also enter it as if it
521 513 * existed in the plain directory.
522 514 */
523 515 if ((dp->d_name[0] == 's') &&
524 516 (dp->d_name[1] == (int) period_char)) {
525 517
526 518 MBSTOWCS(wcs_buffer, dp->d_name + 2);
527 519 (void) wscpy(plain_file_name_p, wcs_buffer);
528 520 plain_file = GETNAME(plain_file_name, FIND_LENGTH);
529 521 plain_file->stat.is_file = true;
530 522 plain_file->stat.has_sccs = HAS_SCCS;
531 523 /* if sccs dependency is already set,skip */
532 524 if(plain_file->prop) {
533 525 Property sprop = get_prop(plain_file->prop,sccs_prop);
534 526 if(sprop != NULL) {
535 527 if (sprop->body.sccs.file) {
536 528 goto try_pattern;
537 529 }
538 530 }
539 531 }
540 532
541 533 /*
542 534 * Enter the s. file as a dependency for the
543 535 * plain file.
544 536 */
545 537 maybe_append_prop(plain_file, sccs_prop)->
546 538 body.sccs.file = file;
547 539 try_pattern:
548 540 MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
549 541 if ((pattern != NULL) &&
550 542 amatch(tmp_wcs_buffer, pattern)) {
551 543 if (debug_level > 0) {
552 544 WCSTOMBS(mbs_buffer, pattern);
553 545 (void) printf(catgets(catd, 1, 233, "'%s: %s' due to %s expansion\n"),
554 546 line->body.line.target->
555 547 string_mb,
556 548 plain_file->string_mb,
557 549 mbs_buffer);
558 550 }
559 551 enter_dependency(line, plain_file, false);
560 552 result++;
561 553 }
562 554 }
563 555 }
564 556 (void) closedir(dir_fd);
565 557
566 558 return result;
567 559 }
568 560
569 561 /*
570 562 * enter_file_name(name_string, library)
571 563 *
572 564 * Helper function for read_dir().
573 565 *
574 566 * Return value:
575 567 * The Name that was entered
576 568 *
577 569 * Parameters:
578 570 * name_string Name of the file we want to enter
579 571 * library The library it is a member of, if any
580 572 *
581 573 * Global variables used:
582 574 */
583 575 static Name
584 576 enter_file_name(wchar_t *name_string, wchar_t *library)
585 577 {
586 578 wchar_t buffer[STRING_BUFFER_LENGTH];
587 579 String_rec lib_name;
588 580 Name name;
589 581 Property prop;
590 582
591 583 if (library == NULL) {
592 584 name = GETNAME(name_string, FIND_LENGTH);
593 585 name->stat.is_file = true;
594 586 return name;
595 587 }
596 588
597 589 INIT_STRING_FROM_STACK(lib_name, buffer);
598 590 append_string(library, &lib_name, FIND_LENGTH);
599 591 append_char((int) parenleft_char, &lib_name);
600 592 append_string(name_string, &lib_name, FIND_LENGTH);
601 593 append_char((int) parenright_char, &lib_name);
602 594
603 595 name = GETNAME(lib_name.buffer.start, FIND_LENGTH);
604 596 name->stat.is_file = true;
605 597 name->is_member = true;
606 598 prop = maybe_append_prop(name, member_prop);
607 599 prop->body.member.library = GETNAME(library, FIND_LENGTH);
608 600 prop->body.member.library->stat.is_file = true;
609 601 prop->body.member.entry = NULL;
610 602 prop->body.member.member = GETNAME(name_string, FIND_LENGTH);
611 603 prop->body.member.member->stat.is_file = true;
612 604 return name;
613 605 }
614 606
615 607 /*
616 608 * star_match(string, pattern)
617 609 *
618 610 * This is a regular shell type wildcard pattern matcher
619 611 * It is used when xpanding wildcards in dependency lists
620 612 *
621 613 * Return value:
622 614 * Indication if the string matched the pattern
623 615 *
624 616 * Parameters:
625 617 * string String to match
626 618 * pattern Pattern to match it against
627 619 *
628 620 * Global variables used:
629 621 */
630 622 static Boolean
631 623 star_match(register wchar_t *string, register wchar_t *pattern)
632 624 {
633 625 register int pattern_ch;
634 626
635 627 switch (*pattern) {
636 628 case 0:
637 629 return succeeded;
638 630 case bracketleft_char:
639 631 case question_char:
640 632 case asterisk_char:
641 633 while (*string) {
642 634 if (amatch(string++, pattern)) {
643 635 return succeeded;
644 636 }
645 637 }
646 638 break;
647 639 default:
648 640 pattern_ch = (int) *pattern++;
649 641 while (*string) {
650 642 if ((*string++ == pattern_ch) &&
651 643 amatch(string, pattern)) {
652 644 return succeeded;
653 645 }
654 646 }
655 647 break;
656 648 }
657 649 return failed;
658 650 }
659 651
660 652 /*
661 653 * amatch(string, pattern)
662 654 *
663 655 * Helper function for shell pattern matching
664 656 *
665 657 * Return value:
666 658 * Indication if the string matched the pattern
667 659 *
668 660 * Parameters:
669 661 * string String to match
670 662 * pattern Pattern to match it against
671 663 *
672 664 * Global variables used:
673 665 */
674 666 static Boolean
675 667 amatch(register wchar_t *string, register wchar_t *pattern)
676 668 {
677 669 register long lower_bound;
678 670 register long string_ch;
679 671 register long pattern_ch;
680 672 register int k;
681 673
682 674 top:
683 675 for (; 1; pattern++, string++) {
684 676 lower_bound = 017777777777;
685 677 string_ch = *string;
686 678 switch (pattern_ch = *pattern) {
687 679 case bracketleft_char:
688 680 k = 0;
689 681 while ((pattern_ch = *++pattern) != 0) {
690 682 switch (pattern_ch) {
691 683 case bracketright_char:
692 684 if (!k) {
693 685 return failed;
694 686 }
695 687 string++;
696 688 pattern++;
697 689 goto top;
698 690 case hyphen_char:
699 691 k |= (lower_bound <= string_ch) &&
700 692 (string_ch <=
701 693 (pattern_ch = pattern[1]));
702 694 default:
703 695 if (string_ch ==
704 696 (lower_bound = pattern_ch)) {
705 697 k++;
706 698 }
707 699 }
708 700 }
709 701 return failed;
710 702 case asterisk_char:
711 703 return star_match(string, ++pattern);
712 704 case 0:
713 705 return BOOLEAN(!string_ch);
714 706 case question_char:
715 707 if (string_ch == 0) {
716 708 return failed;
717 709 }
718 710 break;
719 711 default:
720 712 if (pattern_ch != string_ch) {
721 713 return failed;
722 714 }
723 715 break;
724 716 }
725 717 }
726 718 /* NOTREACHED */
727 719 }
728 720
↓ open down ↓ |
404 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX