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