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