- Timestamp:
- Jan 19, 2007, 2:29:43 AM (19 years ago)
- Location:
- trunk/src/gmake
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gmake/Makefile.kmk
r750 r763 40 40 CONFIG_WITH_COMPARE \ 41 41 CONFIG_WITH_STACK \ 42 CONFIG_WITH_MATH \ 42 43 EXPERIMENTAL \ 43 44 \ … … 290 291 CONFIG_WITH_TOUPPER_TOLOWER \ 291 292 EXPERIMENTAL 292 293 293 294 kmk_gmake_SOURCES = \ 294 295 main.c \ … … 341 342 include $(PATH_KBUILD)/footer.kmk 342 343 343 344 344 345 # 345 346 # Use checked in config.h instead of running ./Configure for it. 346 # 347 # 347 348 config.h.$(BUILD_TARGET) := config.h.$(BUILD_TARGET) 348 349 config.h.win := config.h.W32 … … 407 408 test_stack: 408 409 $(MAKE) -f testcase-stack.kmk 410 411 test_math: 412 $(MAKE) -f testcase-math.kmk 413 414 415 test_all: test_math test_stack test_shell -
trunk/src/gmake/function.c
r750 r763 19 19 #ifdef CONFIG_WITH_OPTIMIZATION_HACKS 20 20 # include <assert.h> 21 #endif 21 #endif 22 22 #include "make.h" 23 23 #include "filedef.h" … … 38 38 #ifdef KMK_HELPERS 39 39 # include "kbuild.h" 40 #endif 40 #endif 41 41 42 42 … … 268 268 269 269 #ifdef CONFIG_WITH_OPTIMIZATION_HACKS 270 /* The maximum length of a function, once reached there is 270 /* The maximum length of a function, once reached there is 271 271 it can't be function and we can skip the hash lookup drop out. */ 272 272 … … 275 275 #else 276 276 # define MAX_FUNCTION_LENGTH 10 277 #endif 277 #endif 278 278 279 279 /* Look up a function by name. */ … … 905 905 p[len] = save; 906 906 } 907 #endif 907 #endif 908 908 909 909 result = allocated_variable_expand (body); … … 1433 1433 if (v) 1434 1434 #ifdef CONFIG_WITH_VALUE_LENGTH 1435 o = variable_buffer_output (o, v->value, 1435 o = variable_buffer_output (o, v->value, 1436 1436 v->value_length >= 0 ? v->value_length : strlen(v->value)); 1437 1437 #else 1438 1438 o = variable_buffer_output (o, v->value, strlen(v->value)); 1439 #endif 1439 #endif 1440 1440 1441 1441 return o; … … 1937 1937 #else 1938 1938 static char * 1939 #endif 1939 #endif 1940 1940 abspath (const char *name, char *apath) 1941 1941 { … … 2147 2147 #else 2148 2148 if (path[0] != '/' && cwd) 2149 #endif 2149 #endif 2150 2150 { 2151 2151 /* relative path, prefix with cwd. */ … … 2181 2181 return o; 2182 2182 } 2183 #endif 2183 #endif 2184 2184 2185 2185 #ifdef CONFIG_WITH_TOUPPER_TOLOWER … … 2227 2227 2228 2228 /* Worker for func_comp_vars() which is called if the comparision failed. 2229 It will do the slow command by command comparision of the commands 2229 It will do the slow command by command comparision of the commands 2230 2230 when there invoked as comp-cmds. */ 2231 static char * 2232 comp_vars_ne (char *o, const char *s1, const char *e1, const char *s2, const char *e2, 2231 static char * 2232 comp_vars_ne (char *o, const char *s1, const char *e1, const char *s2, const char *e2, 2233 2233 char *ne_retval, const char *funcname) 2234 2234 { … … 2253 2253 break; 2254 2254 2255 /* 2255 /* 2256 2256 * Inner compare loop which compares one line. 2257 2257 * FIXME: parse quoting! … … 2276 2276 2277 2277 /* 2278 * If we exited because of a difference try to end-of-command 2278 * If we exited because of a difference try to end-of-command 2279 2279 * comparision, e.g. ignore trailing spaces. 2280 2280 */ … … 2328 2328 } 2329 2329 2330 /* 2330 /* 2331 2331 $(comp-vars var1,var2,not-equal-return) 2332 or 2332 or 2333 2333 $(comp-cmds cmd-var1,cmd-var2,not-equal-return) 2334 2334 2335 Compares the two variables (that's given by name to avoid unnecessary 2335 Compares the two variables (that's given by name to avoid unnecessary 2336 2336 expanding) and return the string in the third argument if not equal. 2337 2337 If equal, nothing is returned. 2338 2338 2339 comp-vars will to an exact comparision only stripping leading and 2339 comp-vars will to an exact comparision only stripping leading and 2340 2340 trailing spaces. 2341 2341 2342 comp-cmds will compare command by command, ignoring not only leading 2342 comp-cmds will compare command by command, ignoring not only leading 2343 2343 and trailing spaces on each line but also leading one leading '@' and '-'. 2344 2344 */ … … 2463 2463 return o; 2464 2464 } 2465 #endif 2465 #endif 2466 2466 2467 2467 … … 2507 2507 #ifdef CONFIG_WITH_VALUE_LENGTH 2508 2508 stack_var->value_length = lastitem - stack_var->value; 2509 #endif 2509 #endif 2510 2510 } 2511 2511 } … … 2514 2514 } 2515 2515 #endif /* CONFIG_WITH_STACK */ 2516 2517 #ifdef CONFIG_WITH_MATH 2518 2519 #include <ctype.h> 2520 #ifdef _MSC_VER 2521 typedef __int64 math_int; 2522 #else 2523 # include <stdint.h> 2524 typedef int64_t math_int; 2525 #endif 2526 2527 /* Converts a string to an integer, causes an error if the format is invalid. */ 2528 static math_int 2529 math_int_from_string (const char *str) 2530 { 2531 const char *start; 2532 unsigned base = 0; 2533 int negative = 0; 2534 math_int num = 0; 2535 2536 /* strip spaces */ 2537 while (isspace (*str)) 2538 str++; 2539 if (!*str) 2540 { 2541 error (NILF, _("bad number: empty\n")); 2542 return 0; 2543 } 2544 start = str; 2545 2546 /* check for +/- */ 2547 while (*str == '+' || *str == '-' || isspace (*str)) 2548 if (*str++ == '-') 2549 negative = !negative; 2550 2551 /* check for prefix - we do not accept octal numbers, sorry. */ 2552 if (*str == '0' && (str[1] == 'x' || str[1] == 'X')) 2553 { 2554 base = 16; 2555 str += 2; 2556 } 2557 else 2558 { 2559 /* look for a hex digit, if not found treat it as decimal */ 2560 const char *p2 = str; 2561 for ( ; *p2; p2++) 2562 if (isxdigit (*p2) && !isdigit (*p2) && isascii (*p2) ) 2563 { 2564 base = 16; 2565 break; 2566 } 2567 if (base == 0) 2568 base = 10; 2569 } 2570 2571 /* must have at least one digit! */ 2572 if ( !isascii (*str) 2573 || !(base == 16 ? isxdigit (*str) : isdigit (*str)) ) 2574 { 2575 error (NILF, _("bad number: '%s'\n"), start); 2576 return 0; 2577 } 2578 2579 /* convert it! */ 2580 while (*str && !isspace (*str)) 2581 { 2582 int ch = *str++; 2583 if (ch >= '0' && ch <= '9') 2584 ch -= '0'; 2585 else if (base == 16 && ch >= 'a' && ch <= 'f') 2586 ch -= 'a' - 10; 2587 else if (base == 16 && ch >= 'A' && ch <= 'F') 2588 ch -= 'A' - 10; 2589 else 2590 { 2591 error (NILF, _("bad number: '%s' (base=%d, pos=%d)\n"), start, base, str - start); 2592 return 0; 2593 } 2594 num *= base; 2595 num += ch; 2596 } 2597 2598 /* check trailing spaces. */ 2599 while (isspace (*str)) 2600 str++; 2601 if (*str) 2602 { 2603 error (NILF, _("bad number: '%s'\n"), start); 2604 return 0; 2605 } 2606 2607 return negative ? -num : num; 2608 } 2609 2610 /* outputs the number (as a string) into the variable buffer. */ 2611 static char * 2612 math_int_to_variable_buffer (char *o, math_int num) 2613 { 2614 static const char xdigits[17] = "0123456789abcdef"; 2615 int negative; 2616 char strbuf[24]; /* 16 hex + 2 prefix + sign + term => 20 */ 2617 char *str = &strbuf[sizeof (strbuf) - 1]; 2618 2619 negative = num < 0; 2620 if (negative) 2621 num = -num; 2622 2623 *str-- = '\0'; 2624 2625 do 2626 { 2627 *str-- = xdigits[num & 0xf]; 2628 num >>= 4; 2629 } 2630 while (num); 2631 2632 *str-- = 'x'; 2633 *str = '0'; 2634 2635 if (negative) 2636 *--str = '-'; 2637 2638 return variable_buffer_output (o, str, &strbuf[sizeof (strbuf) - 1] - str); 2639 } 2640 2641 /* Add two or more integer numbers. */ 2642 static char * 2643 func_int_add (char *o, char **argv, const char *funcname) 2644 { 2645 math_int num; 2646 int i; 2647 2648 num = math_int_from_string (argv[0]); 2649 for (i = 1; argv[i]; i++) 2650 num += math_int_from_string (argv[i]); 2651 2652 return math_int_to_variable_buffer (o, num); 2653 } 2654 2655 /* Subtract two or more integer numbers. */ 2656 static char * 2657 func_int_sub (char *o, char **argv, const char *funcname) 2658 { 2659 math_int num; 2660 int i; 2661 2662 num = math_int_from_string (argv[0]); 2663 for (i = 1; argv[i]; i++) 2664 num -= math_int_from_string (argv[i]); 2665 2666 return math_int_to_variable_buffer (o, num); 2667 } 2668 2669 /* Multiply two or more integer numbers. */ 2670 static char * 2671 func_int_mul (char *o, char **argv, const char *funcname) 2672 { 2673 math_int num; 2674 int i; 2675 2676 num = math_int_from_string (argv[0]); 2677 for (i = 1; argv[i]; i++) 2678 num *= math_int_from_string (argv[i]); 2679 2680 return math_int_to_variable_buffer (o, num); 2681 } 2682 2683 /* Divide an integer number by one or more divisors. */ 2684 static char * 2685 func_int_div (char *o, char **argv, const char *funcname) 2686 { 2687 math_int num; 2688 math_int divisor; 2689 int i; 2690 2691 num = math_int_from_string (argv[0]); 2692 for (i = 1; argv[i]; i++) 2693 { 2694 divisor = math_int_from_string (argv[i]); 2695 if (!divisor) 2696 { 2697 error (NILF, _("divide by zero ('%s')\n"), argv[i]); 2698 return math_int_to_variable_buffer (o, 0); 2699 } 2700 num /= divisor; 2701 } 2702 2703 return math_int_to_variable_buffer (o, num); 2704 } 2705 2706 2707 /* Divide and return the remainder. */ 2708 static char * 2709 func_int_mod (char *o, char **argv, const char *funcname) 2710 { 2711 math_int num; 2712 math_int divisor; 2713 2714 num = math_int_from_string (argv[0]); 2715 divisor = math_int_from_string (argv[1]); 2716 if (!divisor) 2717 { 2718 error (NILF, _("divide by zero ('%s')\n"), argv[1]); 2719 return math_int_to_variable_buffer (o, 0); 2720 } 2721 num %= divisor; 2722 2723 return math_int_to_variable_buffer (o, num); 2724 } 2725 2726 /* 2-complement. */ 2727 static char * 2728 func_int_not (char *o, char **argv, const char *funcname) 2729 { 2730 math_int num; 2731 2732 num = math_int_from_string (argv[0]); 2733 num = ~num; 2734 2735 return math_int_to_variable_buffer (o, num); 2736 } 2737 2738 /* Bitwise AND (two or more numbers). */ 2739 static char * 2740 func_int_and (char *o, char **argv, const char *funcname) 2741 { 2742 math_int num; 2743 int i; 2744 2745 num = math_int_from_string (argv[0]); 2746 for (i = 1; argv[i]; i++) 2747 num &= math_int_from_string (argv[i]); 2748 2749 return math_int_to_variable_buffer (o, num); 2750 } 2751 2752 /* Bitwise OR (two or more numbers). */ 2753 static char * 2754 func_int_or (char *o, char **argv, const char *funcname) 2755 { 2756 math_int num; 2757 int i; 2758 2759 num = math_int_from_string (argv[0]); 2760 for (i = 1; argv[i]; i++) 2761 num |= math_int_from_string (argv[i]); 2762 2763 return math_int_to_variable_buffer (o, num); 2764 } 2765 2766 /* Bitwise XOR (two or more numbers). */ 2767 static char * 2768 func_int_xor (char *o, char **argv, const char *funcname) 2769 { 2770 math_int num; 2771 int i; 2772 2773 num = math_int_from_string (argv[0]); 2774 for (i = 1; argv[i]; i++) 2775 num ^= math_int_from_string (argv[i]); 2776 2777 return math_int_to_variable_buffer (o, num); 2778 } 2779 2780 /* Compare two integer numbers. Returns make boolean (true="1"; false=""). */ 2781 static char * 2782 func_int_cmp (char *o, char **argv, const char *funcname) 2783 { 2784 math_int num1; 2785 math_int num2; 2786 int rc; 2787 2788 num1 = math_int_from_string (argv[0]); 2789 num2 = math_int_from_string (argv[1]); 2790 2791 funcname += sizeof ("int-") - 1; 2792 if (!strcmp (funcname, "eq")) 2793 rc = num1 == num2; 2794 else if (!strcmp (funcname, "ne")) 2795 rc = num1 != num2; 2796 else if (!strcmp (funcname, "gt")) 2797 rc = num1 > num2; 2798 else if (!strcmp (funcname, "ge")) 2799 rc = num1 >= num2; 2800 else if (!strcmp (funcname, "lt")) 2801 rc = num1 < num2; 2802 else /*if (!strcmp (funcname, "le"))*/ 2803 rc = num1 <= num2; 2804 2805 return variable_buffer_output (o, rc ? "1" : "", rc); 2806 } 2807 2808 2809 #endif /* CONFIG_WITH_MATH */ 2516 2810 2517 2811 /* Lookup table for builtin functions. … … 2578 2872 #ifdef CONFIG_WITH_ABSPATHEX 2579 2873 { STRING_SIZE_TUPLE("abspathex"), 0, 2, 1, func_abspathex}, 2580 #endif 2874 #endif 2581 2875 #if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE) 2582 2876 { STRING_SIZE_TUPLE("comp-vars"), 3, 3, 1, func_comp_vars}, … … 2588 2882 { STRING_SIZE_TUPLE("stack-popv"), 1, 1, 1, func_stack_pop_top}, 2589 2883 { STRING_SIZE_TUPLE("stack-top"), 1, 1, 1, func_stack_pop_top}, 2884 #endif 2885 #ifdef CONFIG_WITH_MATH 2886 { STRING_SIZE_TUPLE("int-add"), 2, 0, 1, func_int_add}, 2887 { STRING_SIZE_TUPLE("int-sub"), 2, 0, 1, func_int_sub}, 2888 { STRING_SIZE_TUPLE("int-mul"), 2, 0, 1, func_int_mul}, 2889 { STRING_SIZE_TUPLE("int-div"), 2, 0, 1, func_int_div}, 2890 { STRING_SIZE_TUPLE("int-mod"), 2, 2, 1, func_int_mod}, 2891 { STRING_SIZE_TUPLE("int-not"), 1, 1, 1, func_int_not}, 2892 { STRING_SIZE_TUPLE("int-and"), 2, 0, 1, func_int_and}, 2893 { STRING_SIZE_TUPLE("int-or"), 2, 0, 1, func_int_or}, 2894 { STRING_SIZE_TUPLE("int-xor"), 2, 0, 1, func_int_xor}, 2895 { STRING_SIZE_TUPLE("int-eq"), 2, 2, 1, func_int_cmp}, 2896 { STRING_SIZE_TUPLE("int-ne"), 2, 2, 1, func_int_cmp}, 2897 { STRING_SIZE_TUPLE("int-gt"), 2, 2, 1, func_int_cmp}, 2898 { STRING_SIZE_TUPLE("int-ge"), 2, 2, 1, func_int_cmp}, 2899 { STRING_SIZE_TUPLE("int-lt"), 2, 2, 1, func_int_cmp}, 2900 { STRING_SIZE_TUPLE("int-le"), 2, 2, 1, func_int_cmp}, 2590 2901 #endif 2591 2902 #ifdef KMK_HELPERS … … 2595 2906 { STRING_SIZE_TUPLE("kb-src-prop"), 4, 4, 0, func_kbuild_source_prop}, 2596 2907 { STRING_SIZE_TUPLE("kb-src-one"), 0, 1, 0, func_kbuild_source_one}, 2597 #endif 2908 #endif 2598 2909 }; 2599 2910 … … 2859 3170 assert(function_table_init[i].len <= MAX_FUNCTION_LENGTH); 2860 3171 } 2861 #endif 2862 } 3172 #endif 3173 }
Note:
See TracChangeset
for help on using the changeset viewer.