Print this page
make: remove SCCS ident stuff
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/make/lib/mksh/src/misc.cc
+++ new/usr/src/cmd/make/lib/mksh/src/misc.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.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
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 2004 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 -/*
26 - * @(#)misc.cc 1.31 06/12/12
27 - */
28 25
29 -#pragma ident "@(#)misc.cc 1.31 06/12/12"
30 26
31 27 /*
32 28 * misc.cc
33 29 *
34 30 * This file contains various unclassified routines. Some main groups:
35 31 * getname
36 32 * Memory allocation
37 33 * String handling
38 34 * Property handling
39 35 * Error message handling
40 36 * Make internal state dumping
41 37 * main routine support
42 38 */
43 39
44 40 /*
45 41 * Included files
46 42 */
47 43 #include <bsd/bsd.h> /* bsd_signal() */
48 44 #include <mksh/i18n.h> /* get_char_semantics_value() */
49 45 #include <mksh/misc.h>
50 46 #include <mksdmsi18n/mksdmsi18n.h>
51 47 #include <stdarg.h> /* va_list, va_start(), va_end() */
52 48 #include <stdlib.h> /* mbstowcs() */
53 49 #include <sys/signal.h> /* SIG_DFL */
54 50 #include <sys/wait.h> /* wait() */
55 51
56 52 #ifdef SUN5_0
57 53 #include <string.h> /* strerror() */
58 54 #endif
59 55
60 56 #if defined (HP_UX) || defined (linux)
61 57 #include <unistd.h>
62 58 #endif
63 59
64 60 /*
65 61 * Defined macros
66 62 */
67 63
68 64 /*
69 65 * typedefs & structs
70 66 */
71 67
72 68 /*
73 69 * Static variables
74 70 */
75 71 #ifdef SUN5_0
76 72 extern "C" void (*sigivalue)(int) = SIG_DFL;
77 73 extern "C" void (*sigqvalue)(int) = SIG_DFL;
78 74 extern "C" void (*sigtvalue)(int) = SIG_DFL;
79 75 extern "C" void (*sighvalue)(int) = SIG_DFL;
80 76 #else
81 77 static void (*sigivalue)(int) = (void (*) (int)) SIG_DFL;
82 78 static void (*sigqvalue)(int) = (void (*) (int)) SIG_DFL;
83 79 static void (*sigtvalue)(int) = (void (*) (int)) SIG_DFL;
84 80 static void (*sighvalue)(int) = (void (*) (int)) SIG_DFL;
85 81 #endif
86 82
87 83 long getname_bytes_count = 0;
88 84 long getname_names_count = 0;
89 85 long getname_struct_count = 0;
90 86
91 87 long freename_bytes_count = 0;
92 88 long freename_names_count = 0;
93 89 long freename_struct_count = 0;
94 90
95 91 long expandstring_count = 0;
96 92 long getwstring_count = 0;
97 93
98 94 /*
99 95 * File table of contents
100 96 */
101 97 static void expand_string(register String string, register int length);
102 98
103 99 #define FATAL_ERROR_MSG_SIZE 200
104 100
105 101 /*
106 102 * getmem(size)
107 103 *
108 104 * malloc() version that checks the returned value.
109 105 *
110 106 * Return value:
111 107 * The memory chunk we allocated
112 108 *
113 109 * Parameters:
114 110 * size The size of the chunk we need
115 111 *
116 112 * Global variables used:
117 113 */
118 114 char *
119 115 getmem(register int size)
120 116 {
121 117 register char *result = (char *) malloc((unsigned) size);
122 118 if (result == NULL) {
123 119 char buf[FATAL_ERROR_MSG_SIZE];
124 120 sprintf(buf, NOCATGETS("*** Error: malloc(%d) failed: %s\n"), size, strerror(errno));
125 121 strcat(buf, catgets(libmksdmsi18n_catd, 1, 126, "mksh: Fatal error: Out of memory\n"));
126 122 fputs(buf, stderr);
127 123 #ifdef SUN5_0
128 124 exit_status = 1;
129 125 #endif
130 126 exit(1);
131 127 }
132 128 return result;
133 129 }
134 130
135 131 /*
136 132 * retmem(p)
137 133 *
138 134 * Cover funtion for free() to make it possible to insert advises.
139 135 *
140 136 * Parameters:
141 137 * p The memory block to free
142 138 *
143 139 * Global variables used:
144 140 */
145 141 void
146 142 retmem(wchar_t *p)
147 143 {
148 144 (void) free((char *) p);
149 145 }
150 146
151 147 void
152 148 retmem_mb(caddr_t p)
153 149 {
154 150 (void) free(p);
155 151 }
156 152
157 153 /*
158 154 * getname_fn(name, len, dont_enter)
159 155 *
160 156 * Hash a name string to the corresponding nameblock.
161 157 *
162 158 * Return value:
163 159 * The Name block for the string
164 160 *
165 161 * Parameters:
166 162 * name The string we want to internalize
167 163 * len The length of that string
168 164 * dont_enter Don't enter the name if it does not exist
169 165 *
170 166 * Global variables used:
171 167 * funny The vector of semantic tags for characters
172 168 * hashtab The hashtable used for the nametable
173 169 */
174 170 Name
175 171 getname_fn(wchar_t *name, register int len, register Boolean dont_enter, register Boolean * foundp)
176 172 {
177 173 register int length;
178 174 register wchar_t *cap = name;
179 175 register Name np;
180 176 static Name_rec empty_Name;
181 177 char *tmp_mbs_buffer = NULL;
182 178 char *mbs_name = mbs_buffer;
183 179
184 180 /*
185 181 * First figure out how long the string is.
186 182 * If the len argument is -1 we count the chars here.
187 183 */
188 184 if (len == FIND_LENGTH) {
189 185 length = wslen(name);
190 186 } else {
191 187 length = len;
192 188 }
193 189
194 190 Wstring ws;
195 191 ws.init(name, length);
196 192 if (length >= MAXPATHLEN) {
197 193 mbs_name = tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
198 194 }
199 195 (void) wcstombs(mbs_name, ws.get_string(), (length * MB_LEN_MAX) + 1);
200 196
201 197 /* Look for the string */
202 198 if (dont_enter || (foundp != 0)) {
203 199 np = hashtab.lookup(mbs_name);
204 200 if (foundp != 0) {
205 201 *foundp = (np != 0) ? true : false;
206 202 }
207 203 if ((np != 0) || dont_enter) {
208 204 if(tmp_mbs_buffer != NULL) {
209 205 retmem_mb(tmp_mbs_buffer);
210 206 }
211 207 return np;
212 208 } else {
213 209 np = ALLOC(Name);
214 210 }
215 211 } else {
216 212 Boolean found;
217 213 np = hashtab.insert(mbs_name, found);
218 214 if (found) {
219 215 if(tmp_mbs_buffer != NULL) {
220 216 retmem_mb(tmp_mbs_buffer);
221 217 }
222 218 return np;
223 219 }
224 220 }
225 221 getname_struct_count += sizeof(struct _Name);
226 222 *np = empty_Name;
227 223
228 224 np->string_mb = strdup(mbs_name);
229 225 if(tmp_mbs_buffer != NULL) {
230 226 retmem_mb(tmp_mbs_buffer);
231 227 mbs_name = tmp_mbs_buffer = NULL;
232 228 }
233 229 getname_bytes_count += strlen(np->string_mb) + 1;
234 230 /* Fill in the new Name */
235 231 np->stat.time = file_no_time;
236 232 np->hash.length = length;
237 233 /* Scan the namestring to classify it */
238 234 for (cap = name, len = 0; --length >= 0;) {
239 235 len |= get_char_semantics_value(*cap++);
240 236 }
241 237 np->dollar = BOOLEAN((len & (int) dollar_sem) != 0);
242 238 np->meta = BOOLEAN((len & (int) meta_sem) != 0);
243 239 np->percent = BOOLEAN((len & (int) percent_sem) != 0);
244 240 np->wildcard = BOOLEAN((len & (int) wildcard_sem) != 0);
245 241 np->colon = BOOLEAN((len & (int) colon_sem) != 0);
246 242 np->parenleft = BOOLEAN((len & (int) parenleft_sem) != 0);
247 243 getname_names_count++;
248 244 return np;
249 245 }
250 246
251 247 void
252 248 store_name(Name name)
253 249 {
254 250 hashtab.insert(name);
255 251 }
256 252
257 253 void
258 254 free_name(Name name)
259 255 {
260 256 freename_names_count++;
261 257 freename_struct_count += sizeof(struct _Name);
262 258 freename_bytes_count += strlen(name->string_mb) + 1;
263 259 retmem_mb(name->string_mb);
264 260 for (Property next, p = name->prop; p != NULL; p = next) {
265 261 next = p->next;
266 262 free(p);
267 263 }
268 264 free(name);
269 265 }
270 266
271 267 /*
272 268 * enable_interrupt(handler)
273 269 *
274 270 * This routine sets a new interrupt handler for the signals make
275 271 * wants to deal with.
276 272 *
277 273 * Parameters:
278 274 * handler The function installed as interrupt handler
279 275 *
280 276 * Static variables used:
281 277 * sigivalue The original signal handler
282 278 * sigqvalue The original signal handler
283 279 * sigtvalue The original signal handler
284 280 * sighvalue The original signal handler
285 281 */
286 282 void
287 283 enable_interrupt(register void (*handler) (int))
288 284 {
289 285 #ifdef SUN5_0
290 286 if (sigivalue != SIG_IGN) {
291 287 #else
292 288 if (sigivalue != (void (*) (int)) SIG_IGN) {
293 289 #endif
294 290 (void) bsd_signal(SIGINT, (SIG_PF) handler);
295 291 }
296 292 #ifdef SUN5_0
297 293 if (sigqvalue != SIG_IGN) {
298 294 #else
299 295 if (sigqvalue != (void (*) (int)) SIG_IGN) {
300 296 #endif
301 297 (void) bsd_signal(SIGQUIT, (SIG_PF) handler);
302 298 }
303 299 #ifdef SUN5_0
304 300 if (sigtvalue != SIG_IGN) {
305 301 #else
306 302 if (sigtvalue != (void (*) (int)) SIG_IGN) {
307 303 #endif
308 304 (void) bsd_signal(SIGTERM, (SIG_PF) handler);
309 305 }
310 306 #ifdef SUN5_0
311 307 if (sighvalue != SIG_IGN) {
312 308 #else
313 309 if (sighvalue != (void (*) (int)) SIG_IGN) {
314 310 #endif
315 311 (void) bsd_signal(SIGHUP, (SIG_PF) handler);
316 312 }
317 313 }
318 314
319 315 /*
320 316 * setup_char_semantics()
321 317 *
322 318 * Load the vector char_semantics[] with lexical markers
323 319 *
324 320 * Parameters:
325 321 *
326 322 * Global variables used:
327 323 * char_semantics The vector of character semantics that we set
328 324 */
329 325 void
330 326 setup_char_semantics(void)
331 327 {
332 328 char *s;
333 329 wchar_t wc_buffer[1];
334 330 int entry;
335 331
336 332 if (svr4) {
337 333 s = "@-";
338 334 } else {
339 335 s = "=@-?!+";
340 336 }
341 337 for (s; MBTOWC(wc_buffer, s); s++) {
342 338 entry = get_char_semantics_entry(*wc_buffer);
343 339 char_semantics[entry] |= (int) command_prefix_sem;
344 340 }
345 341 char_semantics[dollar_char_entry] |= (int) dollar_sem;
346 342 for (s = "#|=^();&<>*?[]:$`'\"\\\n"; MBTOWC(wc_buffer, s); s++) {
347 343 entry = get_char_semantics_entry(*wc_buffer);
348 344 char_semantics[entry] |= (int) meta_sem;
349 345 }
350 346 char_semantics[percent_char_entry] |= (int) percent_sem;
351 347 for (s = "@*<%?^"; MBTOWC(wc_buffer, s); s++) {
352 348 entry = get_char_semantics_entry(*wc_buffer);
353 349 char_semantics[entry] |= (int) special_macro_sem;
354 350 }
355 351 for (s = "?[*"; MBTOWC(wc_buffer, s); s++) {
356 352 entry = get_char_semantics_entry(*wc_buffer);
357 353 char_semantics[entry] |= (int) wildcard_sem;
358 354 }
359 355 char_semantics[colon_char_entry] |= (int) colon_sem;
360 356 char_semantics[parenleft_char_entry] |= (int) parenleft_sem;
361 357 }
362 358
363 359 /*
364 360 * errmsg(errnum)
365 361 *
366 362 * Return the error message for a system call error
367 363 *
368 364 * Return value:
369 365 * An error message string
370 366 *
371 367 * Parameters:
372 368 * errnum The number of the error we want to describe
373 369 *
374 370 * Global variables used:
375 371 * sys_errlist A vector of error messages
376 372 * sys_nerr The size of sys_errlist
377 373 */
378 374 char *
379 375 errmsg(int errnum)
380 376 {
381 377 #ifdef linux
382 378 return strerror(errnum);
383 379 #else // linux
384 380
385 381 extern int sys_nerr;
386 382 #ifdef SUN4_x
387 383 extern char *sys_errlist[];
388 384 #endif
389 385 char *errbuf;
390 386
391 387 if ((errnum < 0) || (errnum > sys_nerr)) {
392 388 errbuf = getmem(6+1+11+1);
393 389 (void) sprintf(errbuf, catgets(libmksdmsi18n_catd, 1, 127, "Error %d"), errnum);
394 390 return errbuf;
395 391 } else {
396 392 #ifdef SUN4_x
397 393 return(sys_errlist[errnum]);
398 394 #endif
399 395 #ifdef SUN5_0
400 396 return strerror(errnum);
401 397 #endif
402 398
403 399 }
404 400 #endif // linux
405 401 }
406 402
407 403 static char static_buf[MAXPATHLEN*3];
408 404
409 405 /*
410 406 * fatal_mksh(format, args...)
411 407 *
412 408 * Print a message and die
413 409 *
414 410 * Parameters:
415 411 * format printf type format string
416 412 * args Arguments to match the format
417 413 */
418 414 /*VARARGS*/
419 415 void
420 416 fatal_mksh(char * message, ...)
421 417 {
422 418 va_list args;
423 419 char *buf = static_buf;
424 420 char *mksh_fat_err = catgets(libmksdmsi18n_catd, 1, 128, "mksh: Fatal error: ");
425 421 char *cur_wrk_dir = catgets(libmksdmsi18n_catd, 1, 129, "Current working directory: ");
426 422 int mksh_fat_err_len = strlen(mksh_fat_err);
427 423
428 424 va_start(args, message);
429 425 (void) fflush(stdout);
430 426 (void) strcpy(buf, mksh_fat_err);
431 427 size_t buf_len = vsnprintf(static_buf + mksh_fat_err_len,
432 428 sizeof(static_buf) - mksh_fat_err_len,
433 429 message, args)
434 430 + mksh_fat_err_len
435 431 + strlen(cur_wrk_dir)
436 432 + strlen(get_current_path_mksh())
437 433 + 3; // "\n\n"
438 434 va_end(args);
439 435 if (buf_len >= sizeof(static_buf)) {
440 436 buf = getmem(buf_len);
441 437 (void) strcpy(buf, mksh_fat_err);
442 438 va_start(args, message);
443 439 (void) vsprintf(buf + mksh_fat_err_len, message, args);
444 440 va_end(args);
445 441 }
446 442 (void) strcat(buf, "\n");
447 443 /*
448 444 if (report_pwd) {
449 445 */
450 446 if (1) {
451 447 (void) strcat(buf, cur_wrk_dir);
452 448 (void) strcat(buf, get_current_path_mksh());
453 449 (void) strcat(buf, "\n");
454 450 }
455 451 (void) fputs(buf, stderr);
456 452 (void) fflush(stderr);
457 453 if (buf != static_buf) {
458 454 retmem_mb(buf);
459 455 }
460 456 #ifdef SUN5_0
461 457 exit_status = 1;
462 458 #endif
463 459 exit(1);
464 460 }
465 461
466 462 /*
467 463 * fatal_reader_mksh(format, args...)
468 464 *
469 465 * Parameters:
470 466 * format printf style format string
471 467 * args arguments to match the format
472 468 */
473 469 /*VARARGS*/
474 470 void
475 471 fatal_reader_mksh(char * pattern, ...)
476 472 {
477 473 va_list args;
478 474 char message[1000];
479 475
480 476 va_start(args, pattern);
481 477 /*
482 478 if (file_being_read != NULL) {
483 479 WCSTOMBS(mbs_buffer, file_being_read);
484 480 if (line_number != 0) {
485 481 (void) sprintf(message,
486 482 catgets(libmksdmsi18n_catd, 1, 130, "%s, line %d: %s"),
487 483 mbs_buffer,
488 484 line_number,
489 485 pattern);
490 486 } else {
491 487 (void) sprintf(message,
492 488 "%s: %s",
493 489 mbs_buffer,
494 490 pattern);
495 491 }
496 492 pattern = message;
497 493 }
498 494 */
499 495
500 496 (void) fflush(stdout);
501 497 (void) fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 131, "mksh: Fatal error in reader: "));
502 498 (void) vfprintf(stderr, pattern, args);
503 499 (void) fprintf(stderr, "\n");
504 500 va_end(args);
505 501
506 502 /*
507 503 if (temp_file_name != NULL) {
508 504 (void) fprintf(stderr,
509 505 catgets(libmksdmsi18n_catd, 1, 132, "mksh: Temp-file %s not removed\n"),
510 506 temp_file_name->string_mb);
511 507 temp_file_name = NULL;
512 508 }
513 509 */
514 510
515 511 /*
516 512 if (report_pwd) {
517 513 */
518 514 if (1) {
519 515 (void) fprintf(stderr,
520 516 catgets(libmksdmsi18n_catd, 1, 133, "Current working directory %s\n"),
521 517 get_current_path_mksh());
522 518 }
523 519 (void) fflush(stderr);
524 520 #ifdef SUN5_0
525 521 exit_status = 1;
526 522 #endif
527 523 exit(1);
528 524 }
529 525
530 526 /*
531 527 * warning_mksh(format, args...)
532 528 *
533 529 * Print a message and continue.
534 530 *
535 531 * Parameters:
536 532 * format printf type format string
537 533 * args Arguments to match the format
538 534 */
539 535 /*VARARGS*/
540 536 void
541 537 warning_mksh(char * message, ...)
542 538 {
543 539 va_list args;
544 540
545 541 va_start(args, message);
546 542 (void) fflush(stdout);
547 543 (void) fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 134, "mksh: Warning: "));
548 544 (void) vfprintf(stderr, message, args);
549 545 (void) fprintf(stderr, "\n");
550 546 va_end(args);
551 547 /*
552 548 if (report_pwd) {
553 549 */
554 550 if (1) {
555 551 (void) fprintf(stderr,
556 552 catgets(libmksdmsi18n_catd, 1, 135, "Current working directory %s\n"),
557 553 get_current_path_mksh());
558 554 }
559 555 (void) fflush(stderr);
560 556 }
561 557
562 558 /*
563 559 * get_current_path_mksh()
564 560 *
565 561 * Stuff current_path with the current path if it isnt there already.
566 562 *
567 563 * Parameters:
568 564 *
569 565 * Global variables used:
570 566 */
571 567 char *
572 568 get_current_path_mksh(void)
573 569 {
574 570 char pwd[(MAXPATHLEN * MB_LEN_MAX)];
575 571 static char *current_path;
576 572
577 573 if (current_path == NULL) {
578 574 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
579 575 getcwd(pwd, sizeof(pwd));
580 576 #else
581 577 (void) getwd(pwd);
582 578 #endif
583 579 if (pwd[0] == (int) nul_char) {
584 580 pwd[0] = (int) slash_char;
585 581 pwd[1] = (int) nul_char;
586 582 }
587 583 current_path = strdup(pwd);
588 584 }
589 585 return current_path;
590 586 }
591 587
592 588 /*
593 589 * append_prop(target, type)
594 590 *
595 591 * Create a new property and append it to the property list of a Name.
596 592 *
597 593 * Return value:
598 594 * A new property block for the target
599 595 *
600 596 * Parameters:
601 597 * target The target that wants a new property
602 598 * type The type of property being requested
603 599 *
604 600 * Global variables used:
605 601 */
606 602 Property
607 603 append_prop(register Name target, register Property_id type)
608 604 {
609 605 register Property *insert = &target->prop;
610 606 register Property prop = *insert;
611 607 register int size;
612 608
613 609 switch (type) {
614 610 case conditional_prop:
615 611 size = sizeof (struct Conditional);
616 612 break;
617 613 case line_prop:
618 614 size = sizeof (struct Line);
619 615 break;
620 616 case macro_prop:
621 617 size = sizeof (struct _Macro);
622 618 break;
623 619 case makefile_prop:
624 620 size = sizeof (struct Makefile);
625 621 break;
626 622 case member_prop:
627 623 size = sizeof (struct Member);
628 624 break;
629 625 case recursive_prop:
630 626 size = sizeof (struct Recursive);
631 627 break;
632 628 case sccs_prop:
633 629 size = sizeof (struct Sccs);
634 630 break;
635 631 case suffix_prop:
636 632 size = sizeof (struct Suffix);
637 633 break;
638 634 case target_prop:
639 635 size = sizeof (struct Target);
640 636 break;
641 637 case time_prop:
642 638 size = sizeof (struct STime);
643 639 break;
644 640 case vpath_alias_prop:
645 641 size = sizeof (struct Vpath_alias);
646 642 break;
647 643 case long_member_name_prop:
648 644 size = sizeof (struct Long_member_name);
649 645 break;
650 646 case macro_append_prop:
651 647 size = sizeof (struct _Macro_appendix);
652 648 break;
653 649 case env_mem_prop:
654 650 size = sizeof (struct _Env_mem);
655 651 break;
656 652 default:
657 653 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 136, "Internal error. Unknown prop type %d"), type);
658 654 }
659 655 for (; prop != NULL; insert = &prop->next, prop = *insert);
660 656 size += PROPERTY_HEAD_SIZE;
661 657 *insert = prop = (Property) getmem(size);
662 658 memset((char *) prop, 0, size);
663 659 prop->type = type;
664 660 prop->next = NULL;
665 661 return prop;
666 662 }
667 663
668 664 /*
669 665 * maybe_append_prop(target, type)
670 666 *
671 667 * Append a property to the Name if none of this type exists
672 668 * else return the one already there
673 669 *
674 670 * Return value:
675 671 * A property of the requested type for the target
676 672 *
677 673 * Parameters:
678 674 * target The target that wants a new property
679 675 * type The type of property being requested
680 676 *
681 677 * Global variables used:
682 678 */
683 679 Property
684 680 maybe_append_prop(register Name target, register Property_id type)
685 681 {
686 682 register Property prop;
687 683
688 684 if ((prop = get_prop(target->prop, type)) != NULL) {
689 685 return prop;
690 686 }
691 687 return append_prop(target, type);
692 688 }
693 689
694 690 /*
695 691 * get_prop(start, type)
696 692 *
697 693 * Scan the property list of a Name to find the next property
698 694 * of a given type.
699 695 *
700 696 * Return value:
701 697 * The first property of the type, if any left
702 698 *
703 699 * Parameters:
704 700 * start The first property block to check for type
705 701 * type The type of property block we need
706 702 *
707 703 * Global variables used:
708 704 */
709 705 Property
710 706 get_prop(register Property start, register Property_id type)
711 707 {
712 708 for (; start != NULL; start = start->next) {
713 709 if (start->type == type) {
714 710 return start;
715 711 }
716 712 }
717 713 return NULL;
718 714 }
719 715
720 716 /*
721 717 * append_string(from, to, length)
722 718 *
723 719 * Append a C string to a make string expanding it if nessecary
724 720 *
725 721 * Parameters:
726 722 * from The source (C style) string
727 723 * to The destination (make style) string
728 724 * length The length of the from string
729 725 *
730 726 * Global variables used:
731 727 */
732 728 void
733 729 append_string(register wchar_t *from, register String to, register int length)
734 730 {
735 731 if (length == FIND_LENGTH) {
736 732 length = wslen(from);
737 733 }
738 734 if (to->buffer.start == NULL) {
739 735 expand_string(to, 32 + length);
740 736 }
741 737 if (to->buffer.end - to->text.p <= length) {
742 738 expand_string(to,
743 739 (to->buffer.end - to->buffer.start) * 2 +
744 740 length);
745 741 }
746 742 if (length > 0) {
747 743 (void) wsncpy(to->text.p, from, length);
748 744 to->text.p += length;
749 745 }
750 746 *(to->text.p) = (int) nul_char;
751 747 }
752 748
753 749 wchar_t * get_wstring(char *from) {
754 750 if(from == NULL) {
755 751 return NULL;
756 752 }
757 753 getwstring_count++;
758 754 wchar_t * wcbuf = ALLOC_WC(strlen(from) + 1);
759 755 mbstowcs(wcbuf, from, strlen(from)+1);
760 756 return wcbuf;
761 757 }
762 758
763 759 void
764 760 append_string(register char *from, register String to, register int length)
765 761 {
766 762 if (length == FIND_LENGTH) {
767 763 length = strlen(from);
768 764 }
769 765 if (to->buffer.start == NULL) {
770 766 expand_string(to, 32 + length);
771 767 }
772 768 if (to->buffer.end - to->text.p <= length) {
773 769 expand_string(to,
774 770 (to->buffer.end - to->buffer.start) * 2 +
775 771 length);
776 772 }
777 773 if (length > 0) {
778 774 (void) mbstowcs(to->text.p, from, length);
779 775 to->text.p += length;
780 776 }
781 777 *(to->text.p) = (int) nul_char;
782 778 }
783 779
784 780 /*
785 781 * expand_string(string, length)
786 782 *
787 783 * Allocate more memory for strings that run out of space.
788 784 *
789 785 * Parameters:
790 786 * string The make style string we want to expand
791 787 * length The new length we need
792 788 *
793 789 * Global variables used:
794 790 */
795 791 static void
796 792 expand_string(register String string, register int length)
797 793 {
798 794 register wchar_t *p;
799 795
800 796 if (string->buffer.start == NULL) {
801 797 /* For strings that have no memory allocated */
802 798 string->buffer.start =
803 799 string->text.p =
804 800 string->text.end =
805 801 ALLOC_WC(length);
806 802 string->buffer.end = string->buffer.start + length;
807 803 string->text.p[0] = (int) nul_char;
808 804 string->free_after_use = true;
809 805 expandstring_count++;
810 806 return;
811 807 }
812 808 if (string->buffer.end - string->buffer.start >= length) {
813 809 /* If we really don't need more memory. */
814 810 return;
815 811 }
816 812 /*
817 813 * Get more memory, copy the string and free the old buffer if
818 814 * it is was malloc()'ed.
819 815 */
820 816 expandstring_count++;
821 817 p = ALLOC_WC(length);
822 818 (void) wscpy(p, string->buffer.start);
823 819 string->text.p = p + (string->text.p - string->buffer.start);
824 820 string->text.end = p + (string->text.end - string->buffer.start);
825 821 string->buffer.end = p + length;
826 822 if (string->free_after_use) {
827 823 retmem(string->buffer.start);
828 824 }
829 825 string->buffer.start = p;
830 826 string->free_after_use = true;
831 827 }
832 828
833 829 /*
834 830 * append_char(from, to)
835 831 *
836 832 * Append one char to a make string expanding it if nessecary
837 833 *
838 834 * Parameters:
839 835 * from Single character to append to string
840 836 * to The destination (make style) string
841 837 *
842 838 * Global variables used:
843 839 */
844 840 void
845 841 append_char(wchar_t from, register String to)
846 842 {
847 843 if (to->buffer.start == NULL) {
848 844 expand_string(to, 32);
849 845 }
850 846 if (to->buffer.end - to->text.p <= 2) {
851 847 expand_string(to, to->buffer.end - to->buffer.start + 32);
852 848 }
853 849 *(to->text.p)++ = from;
854 850 *(to->text.p) = (int) nul_char;
855 851 }
856 852
857 853 /*
858 854 * handle_interrupt_mksh()
859 855 *
860 856 * This is where C-C traps are caught.
861 857 */
862 858 void
863 859 handle_interrupt_mksh(int)
864 860 {
865 861 (void) fflush(stdout);
866 862 /* Make sure the processes running under us terminate first. */
867 863 if (childPid > 0) {
868 864 kill(childPid, SIGTERM);
869 865 childPid = -1;
870 866 }
871 867 #if defined(SUN5_0) || defined(HP_UX) || defined(linux)
872 868 while (wait((int *) NULL) != -1);
873 869 #if defined(SUN5_0)
874 870 exit_status = 2;
875 871 #endif
876 872 #else
877 873 while (wait((union wait *) NULL) != -1);
878 874 #endif
879 875 exit(2);
880 876 }
881 877
882 878 /*
883 879 * setup_interrupt()
884 880 *
885 881 * This routine saves the original interrupt handler pointers
886 882 *
887 883 * Parameters:
888 884 *
889 885 * Static variables used:
890 886 * sigivalue The original signal handler
891 887 * sigqvalue The original signal handler
892 888 * sigtvalue The original signal handler
893 889 * sighvalue The original signal handler
894 890 */
895 891 void
896 892 setup_interrupt(register void (*handler) (int))
897 893 {
898 894 #ifdef SUN5_0
899 895 sigivalue = bsd_signal(SIGINT, SIG_IGN);
900 896 sigqvalue = bsd_signal(SIGQUIT, SIG_IGN);
901 897 sigtvalue = bsd_signal(SIGTERM, SIG_IGN);
902 898 sighvalue = bsd_signal(SIGHUP, SIG_IGN);
903 899 #else
904 900 sigivalue = (void (*) (int)) bsd_signal(SIGINT, SIG_IGN);
905 901 sigqvalue = (void (*) (int)) bsd_signal(SIGQUIT, SIG_IGN);
906 902 sigtvalue = (void (*) (int)) bsd_signal(SIGTERM, SIG_IGN);
907 903 sighvalue = (void (*) (int)) bsd_signal(SIGHUP, SIG_IGN);
908 904 #endif
909 905 enable_interrupt(handler);
910 906 }
911 907
912 908
913 909 void
914 910 mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n)
915 911 {
916 912 if(mbstowcs(pwcs, s, n) == -1) {
917 913 fatal_mksh(catgets(libmksdmsi18n_catd, 1, 143, "The string `%s' is not valid in current locale"), s);
918 914 }
919 915 }
920 916
921 917
922 918
923 919 Wstring::Wstring()
924 920 {
925 921 INIT_STRING_FROM_STACK(string, string_buf);
926 922 }
927 923
928 924 Wstring::Wstring(struct _Name * name)
929 925 {
930 926 INIT_STRING_FROM_STACK(string, string_buf);
931 927 append_string(name->string_mb, &string, name->hash.length);
932 928 }
933 929
934 930 Wstring::~Wstring()
935 931 {
936 932 if(string.free_after_use) {
937 933 retmem(string.buffer.start);
938 934 }
939 935 }
940 936
941 937 void
942 938 Wstring::init(struct _Name * name)
943 939 {
944 940 if(string.free_after_use) {
945 941 retmem(string.buffer.start);
946 942 }
947 943 INIT_STRING_FROM_STACK(string, string_buf);
948 944 append_string(name->string_mb, &string, name->hash.length);
949 945 }
950 946
951 947 void
952 948 Wstring::init(wchar_t * name, unsigned length)
953 949 {
954 950 INIT_STRING_FROM_STACK(string, string_buf);
955 951 append_string(name, &string, length);
956 952 string.buffer.start[length] = 0;
957 953 }
958 954
959 955 Boolean
960 956 Wstring::equaln(wchar_t * str, unsigned length)
961 957 {
962 958 return (Boolean)IS_WEQUALN(string.buffer.start, str, length);
963 959 }
964 960
965 961 Boolean
966 962 Wstring::equaln(Wstring * str, unsigned length)
967 963 {
968 964 return (Boolean)IS_WEQUALN(string.buffer.start, str->string.buffer.start, length);
969 965 }
970 966
971 967 Boolean
972 968 Wstring::equal(wchar_t * str, unsigned off, unsigned length)
973 969 {
974 970 return (Boolean)IS_WEQUALN(string.buffer.start + off, str, length);
975 971 }
976 972
977 973 Boolean
978 974 Wstring::equal(wchar_t * str, unsigned off)
979 975 {
980 976 return (Boolean)IS_WEQUAL(string.buffer.start + off, str);
981 977 }
982 978
983 979 Boolean
984 980 Wstring::equal(wchar_t * str)
985 981 {
986 982 return equal(str, 0);
987 983 }
988 984
989 985 Boolean
990 986 Wstring::equal(Wstring * str, unsigned off, unsigned length)
991 987 {
992 988 return (Boolean)IS_WEQUALN(string.buffer.start + off, str->string.buffer.start, length);
993 989 }
994 990
995 991 Boolean
996 992 Wstring::equal(Wstring * str)
997 993 {
998 994 return equal(str, 0);
999 995 }
1000 996
1001 997 Boolean
1002 998 Wstring::equal(Wstring * str, unsigned off)
1003 999 {
1004 1000 return (Boolean)IS_WEQUAL(string.buffer.start + off, str->string.buffer.start);
1005 1001 }
1006 1002
1007 1003 void
1008 1004 Wstring::append_to_str(struct _String * str, unsigned off, unsigned length)
1009 1005 {
1010 1006 append_string(string.buffer.start + off, str, length);
1011 1007 }
1012 1008
1013 1009 Name
1014 1010 Name_set::lookup(const char *key)
1015 1011 {
1016 1012 for (entry *node = root; node != 0;) {
1017 1013 int res = strcmp(key, node->name->string_mb);
1018 1014 if (res < 0) {
1019 1015 node = node->left;
1020 1016 } else if (res > 0) {
1021 1017 node = node->right;
1022 1018 } else {
1023 1019 return node->name;
1024 1020 }
1025 1021 }
1026 1022 return 0;
1027 1023 }
1028 1024
1029 1025 Name
1030 1026 Name_set::insert(const char *key, Boolean &found)
1031 1027 {
1032 1028 Name name = 0;
1033 1029
1034 1030 if (root != 0) {
1035 1031 for (entry *node = root; name == 0;) {
1036 1032 int res = strcmp(key, node->name->string_mb);
1037 1033 if (res < 0) {
1038 1034 if (node->left != 0) {
1039 1035 node = node->left;
1040 1036 } else {
1041 1037 found = false;
1042 1038 name = ALLOC(Name);
1043 1039
1044 1040 node->left = new entry(name, node);
1045 1041 rebalance(node);
1046 1042 }
1047 1043 } else if (res > 0) {
1048 1044 if (node->right != 0) {
1049 1045 node = node->right;
1050 1046 } else {
1051 1047 found = false;
1052 1048 name = ALLOC(Name);
1053 1049
1054 1050 node->right = new entry(name, node);
1055 1051 rebalance(node);
1056 1052 }
1057 1053 } else {
1058 1054 found = true;
1059 1055 name = node->name;
1060 1056 }
1061 1057 }
1062 1058 } else {
1063 1059 found = false;
1064 1060 name = ALLOC(Name);
1065 1061
1066 1062 root = new entry(name, 0);
1067 1063 }
1068 1064 return name;
1069 1065 }
1070 1066
1071 1067 void
1072 1068 Name_set::insert(Name name) {
1073 1069 if (root != 0) {
1074 1070 for (entry *node = root;;) {
1075 1071 int res = strcmp(name->string_mb, node->name->string_mb);
1076 1072 if (res < 0) {
1077 1073 if (node->left != 0) {
1078 1074 node = node->left;
1079 1075 } else {
1080 1076 node->left = new entry(name, node);
1081 1077 rebalance(node);
1082 1078 break;
1083 1079 }
1084 1080 } else if (res > 0) {
1085 1081 if (node->right != 0) {
1086 1082 node = node->right;
1087 1083 } else {
1088 1084 node->right = new entry(name, node);
1089 1085 rebalance(node);
1090 1086 break;
1091 1087 }
1092 1088 } else {
1093 1089 // should be an error: inserting already existing name
1094 1090 break;
1095 1091 }
1096 1092 }
1097 1093 } else {
1098 1094 root = new entry(name, 0);
1099 1095 }
1100 1096 }
1101 1097
1102 1098 void
1103 1099 Name_set::rebalance(Name_set::entry *node) {
1104 1100 for (; node != 0; node = node->parent) {
1105 1101 entry *right = node->right;
1106 1102 entry *left = node->left;
1107 1103
1108 1104 unsigned rdepth = (right != 0) ? right->depth : 0;
1109 1105 unsigned ldepth = (left != 0) ? left->depth : 0;
1110 1106
1111 1107 if (ldepth > rdepth + 1) {
1112 1108 if ((node->left = left->right) != 0) {
1113 1109 left->right->parent = node;
1114 1110 }
1115 1111 if ((left->parent = node->parent) != 0) {
1116 1112 if (node == node->parent->right) {
1117 1113 node->parent->right = left;
1118 1114 } else {
1119 1115 node->parent->left = left;
1120 1116 }
1121 1117 } else {
1122 1118 root = left;
1123 1119 }
1124 1120 left->right = node;
1125 1121 node->parent = left;
1126 1122
1127 1123 node->setup_depth();
1128 1124 node = left;
1129 1125 } else if (rdepth > ldepth + 1) {
1130 1126 if ((node->right = right->left) != 0) {
1131 1127 right->left->parent = node;
1132 1128 }
1133 1129 if ((right->parent = node->parent) != 0) {
1134 1130 if (node == node->parent->right) {
1135 1131 node->parent->right = right;
1136 1132 } else {
1137 1133 node->parent->left = right;
1138 1134 }
1139 1135 } else {
1140 1136 root = right;
1141 1137 }
1142 1138 right->left = node;
1143 1139 node->parent = right;
1144 1140
1145 1141 node->setup_depth();
1146 1142 node = right;
1147 1143 }
1148 1144 node->setup_depth();
1149 1145 }
1150 1146 }
1151 1147
1152 1148 Name_set::iterator
1153 1149 Name_set::begin() const {
1154 1150 for (entry *node = root; node != 0; node = node->left) {
1155 1151 if (node->left == 0) {
1156 1152 return iterator(node);
1157 1153 }
1158 1154 }
1159 1155 return iterator();
1160 1156 }
1161 1157
1162 1158 Name_set::iterator&
1163 1159 Name_set::iterator::operator++() {
1164 1160 if (node != 0) {
1165 1161 if (node->right != 0) {
1166 1162 node = node->right;
1167 1163 while (node->left != 0) {
1168 1164 node = node->left;
1169 1165 }
1170 1166 } else {
1171 1167 while ((node->parent != 0) && (node->parent->right == node)) {
1172 1168 node = node->parent;
1173 1169 }
1174 1170 node = node->parent;
1175 1171 }
1176 1172 }
1177 1173 return *this;
1178 1174 }
↓ open down ↓ |
1139 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX