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