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