VirtualBox

Changeset 986 in kBuild for trunk/src


Ignore:
Timestamp:
May 29, 2007 2:59:06 AM (18 years ago)
Author:
bird
Message:

New function 'nanots', no arguments.

Location:
trunk/src/kmk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/Makefile.am

    r937 r986  
    109109        -DCONFIG_WITH_MATH \
    110110        -DCONFIG_WITH_XARGS \
     111        -DCONFIG_WITH_NANOTS \
    111112        -DCONFIG_PRETTY_COMMAND_PRINTING \
    112113        \
  • trunk/src/kmk/Makefile.kmk

    r953 r986  
    111111        CONFIG_WITH_MATH \
    112112        CONFIG_WITH_XARGS \
     113        CONFIG_WITH_NANOTS \
    113114        CONFIG_PRETTY_COMMAND_PRINTING \
    114115        \
  • trunk/src/kmk/function.c

    r940 r986  
    4242#endif
    4343#include <assert.h> /* bird */
     44
     45#if defined (CONFIG_WITH_MATH) || defined (CONFIG_WITH_NANOTS) /* bird */
     46# include <ctype.h>
     47# ifdef _MSC_VER
     48typedef __int64 math_int;
     49# else
     50#  include <stdint.h>
     51typedef int64_t math_int;
     52# endif
     53#endif
     54
     55#ifdef CONFIG_WITH_NANOTS /* bird */
     56# ifdef WINDOWS32
     57#  include <Windows.h>
     58# endif
     59#endif
    4460
    4561
     
    26642680func_stack_push (char *o, char **argv, const char *funcname)
    26652681{
    2666     do_variable_definition(NILF, argv[0], argv[1], o_file, f_append, 0 /* !target_var */);
    2667     return o;
     2682  do_variable_definition(NILF, argv[0], argv[1], o_file, f_append, 0 /* !target_var */);
     2683  return o;
    26682684}
    26692685
     
    26732689func_stack_pop_top (char *o, char **argv, const char *funcname)
    26742690{
    2675     struct variable *stack_var;
    2676     const char *stack = argv[0];
    2677     const int return_item = argv[0][sizeof("stack-pop") - 1] == '\0';
    2678 
    2679     stack_var = lookup_variable (stack, strlen (stack) );
    2680     if (stack_var)
    2681       {
    2682         unsigned int len;
    2683         const char *iterator = stack_var->value;
    2684         char *lastitem = NULL;
    2685         char *cur;
    2686 
    2687         while ((cur = find_next_token (&iterator, &len)))
    2688           lastitem = cur;
    2689 
    2690         if (lastitem != NULL)
    2691           {
    2692             if (strcmp (funcname, "stack-popv") != 0)
    2693               o = variable_buffer_output (o, lastitem, len);
    2694             if (strcmp (funcname, "stack-top") != 0)
    2695               {
    2696                 *lastitem = '\0';
    2697                 while (lastitem > stack_var->value && isspace (lastitem[-1]))
    2698                   *--lastitem = '\0';
     2691  struct variable *stack_var;
     2692  const char *stack = argv[0];
     2693  const int return_item = argv[0][sizeof("stack-pop") - 1] == '\0';
     2694
     2695  stack_var = lookup_variable (stack, strlen (stack) );
     2696  if (stack_var)
     2697    {
     2698      unsigned int len;
     2699      const char *iterator = stack_var->value;
     2700      char *lastitem = NULL;
     2701      char *cur;
     2702
     2703      while ((cur = find_next_token (&iterator, &len)))
     2704        lastitem = cur;
     2705
     2706      if (lastitem != NULL)
     2707        {
     2708          if (strcmp (funcname, "stack-popv") != 0)
     2709            o = variable_buffer_output (o, lastitem, len);
     2710          if (strcmp (funcname, "stack-top") != 0)
     2711            {
     2712              *lastitem = '\0';
     2713              while (lastitem > stack_var->value && isspace (lastitem[-1]))
     2714                *--lastitem = '\0';
    26992715#ifdef CONFIG_WITH_VALUE_LENGTH
    2700                 stack_var->value_length = lastitem - stack_var->value;
    2701 #endif
    2702               }
    2703           }
    2704       }
    2705     return o;
     2716              stack_var->value_length = lastitem - stack_var->value;
     2717#endif
     2718            }
     2719        }
     2720    }
     2721  return o;
    27062722}
    27072723#endif /* CONFIG_WITH_STACK */
    27082724
     2725#if defined (CONFIG_WITH_MATH) || defined (CONFIG_WITH_NANOTS)
     2726/* outputs the number (as a string) into the variable buffer. */
     2727static char *
     2728math_int_to_variable_buffer (char *o, math_int num)
     2729{
     2730  static const char xdigits[17] = "0123456789abcdef";
     2731  int negative;
     2732  char strbuf[24]; /* 16 hex + 2 prefix + sign + term => 20
     2733                              or 20 dec + sign + term => 22 */
     2734  char *str = &strbuf[sizeof (strbuf) - 1];
     2735
     2736  negative = num < 0;
     2737  if (negative)
     2738    num = -num;
     2739
     2740  *str = '\0';
     2741
     2742  do
     2743    {
     2744#ifdef HEX_MATH_NUMBERS
     2745      *--str = xdigits[num & 0xf];
     2746      num >>= 4;
     2747#else
     2748      *--str = xdigits[num % 10];
     2749      num /= 10;
     2750#endif
     2751    }
     2752  while (num);
     2753
     2754#ifdef HEX_MATH_NUMBERS
     2755  *--str = 'x';
     2756  *--str = '0';
     2757#endif
     2758
     2759  if (negative)
     2760    *--str = '-';
     2761
     2762  return variable_buffer_output (o, str, &strbuf[sizeof (strbuf) - 1] - str);
     2763}
     2764#endif /* CONFIG_WITH_MATH || CONFIG_WITH_NANOTS */
     2765
    27092766#ifdef CONFIG_WITH_MATH
    2710 
    2711 #include <ctype.h>
    2712 #ifdef _MSC_VER
    2713 typedef __int64 math_int;
    2714 #else
    2715 # include <stdint.h>
    2716 typedef int64_t math_int;
    2717 #endif
    27182767
    27192768/* Converts a string to an integer, causes an error if the format is invalid. */
     
    27212770math_int_from_string (const char *str)
    27222771{
    2723     const char *start;
    2724     unsigned base = 0;
    2725     int      negative = 0;
    2726     math_int num = 0;
    2727 
    2728     /* strip spaces */
    2729     while (isspace (*str))
    2730       str++;
    2731     if (!*str)
    2732       {
    2733         error (NILF, _("bad number: empty\n"));
    2734         return 0;
    2735       }
    2736     start = str;
    2737 
    2738     /* check for +/- */
    2739     while (*str == '+' || *str == '-' || isspace (*str))
    2740         if (*str++ == '-')
    2741           negative = !negative;
    2742 
    2743     /* check for prefix - we do not accept octal numbers, sorry. */
    2744     if (*str == '0' && (str[1] == 'x' || str[1] == 'X'))
    2745       {
    2746         base = 16;
    2747         str += 2;
    2748       }
    2749     else
    2750       {
    2751         /* look for a hex digit, if not found treat it as decimal */
    2752         const char *p2 = str;
    2753         for ( ; *p2; p2++)
    2754           if (isxdigit (*p2) && !isdigit (*p2) && isascii (*p2) )
    2755             {
    2756               base = 16;
    2757               break;
    2758             }
    2759         if (base == 0)
    2760           base = 10;
    2761       }
    2762 
    2763     /* must have at least one digit! */
    2764     if (    !isascii (*str)
    2765         ||  !(base == 16 ? isxdigit (*str) : isdigit (*str)) )
    2766       {
    2767         error (NILF, _("bad number: '%s'\n"), start);
    2768         return 0;
    2769       }
    2770 
    2771     /* convert it! */
    2772     while (*str && !isspace (*str))
    2773       {
    2774         int ch = *str++;
    2775         if (ch >= '0' && ch <= '9')
    2776           ch -= '0';
    2777         else if (base == 16 && ch >= 'a' && ch <= 'f')
    2778           ch -= 'a' - 10;
    2779         else if (base == 16 && ch >= 'A' && ch <= 'F')
    2780           ch -= 'A' - 10;
    2781         else
     2772  const char *start;
     2773  unsigned base = 0;
     2774  int      negative = 0;
     2775  math_int num = 0;
     2776
     2777  /* strip spaces */
     2778  while (isspace (*str))
     2779    str++;
     2780  if (!*str)
     2781    {
     2782      error (NILF, _("bad number: empty\n"));
     2783      return 0;
     2784    }
     2785  start = str;
     2786
     2787  /* check for +/- */
     2788  while (*str == '+' || *str == '-' || isspace (*str))
     2789      if (*str++ == '-')
     2790        negative = !negative;
     2791
     2792  /* check for prefix - we do not accept octal numbers, sorry. */
     2793  if (*str == '0' && (str[1] == 'x' || str[1] == 'X'))
     2794    {
     2795      base = 16;
     2796      str += 2;
     2797    }
     2798  else
     2799    {
     2800      /* look for a hex digit, if not found treat it as decimal */
     2801      const char *p2 = str;
     2802      for ( ; *p2; p2++)
     2803        if (isxdigit (*p2) && !isdigit (*p2) && isascii (*p2) )
    27822804          {
    2783             error (NILF, _("bad number: '%s' (base=%d, pos=%d)\n"), start, base, str - start);
    2784             return 0;
     2805            base = 16;
     2806            break;
    27852807          }
    2786         num *= base;
    2787         num += ch;
    2788       }
    2789 
    2790     /* check trailing spaces. */
    2791     while (isspace (*str))
    2792       str++;
    2793     if (*str)
    2794       {
    2795         error (NILF, _("bad number: '%s'\n"), start);
    2796         return 0;
    2797       }
    2798 
    2799     return negative ? -num : num;
    2800 }
    2801 
    2802 /* outputs the number (as a string) into the variable buffer. */
    2803 static char *
    2804 math_int_to_variable_buffer (char *o, math_int num)
    2805 {
    2806     static const char xdigits[17] = "0123456789abcdef";
    2807     int negative;
    2808     char strbuf[24]; /* 16 hex + 2 prefix + sign + term => 20 */
    2809     char *str = &strbuf[sizeof (strbuf) - 1];
    2810 
    2811     negative = num < 0;
    2812     if (negative)
    2813       num = -num;
    2814 
    2815     *str-- = '\0';
    2816 
    2817     do
    2818       {
    2819         *str-- = xdigits[num & 0xf];
    2820         num >>= 4;
    2821       }
    2822     while (num);
    2823 
    2824     *str-- = 'x';
    2825     *str = '0';
    2826 
    2827     if (negative)
    2828         *--str = '-';
    2829 
    2830     return variable_buffer_output (o, str, &strbuf[sizeof (strbuf) - 1] - str);
     2808      if (base == 0)
     2809        base = 10;
     2810    }
     2811
     2812  /* must have at least one digit! */
     2813  if (    !isascii (*str)
     2814      ||  !(base == 16 ? isxdigit (*str) : isdigit (*str)) )
     2815    {
     2816      error (NILF, _("bad number: '%s'\n"), start);
     2817      return 0;
     2818    }
     2819
     2820  /* convert it! */
     2821  while (*str && !isspace (*str))
     2822    {
     2823      int ch = *str++;
     2824      if (ch >= '0' && ch <= '9')
     2825        ch -= '0';
     2826      else if (base == 16 && ch >= 'a' && ch <= 'f')
     2827        ch -= 'a' - 10;
     2828      else if (base == 16 && ch >= 'A' && ch <= 'F')
     2829        ch -= 'A' - 10;
     2830      else
     2831        {
     2832          error (NILF, _("bad number: '%s' (base=%d, pos=%d)\n"), start, base, str - start);
     2833          return 0;
     2834        }
     2835      num *= base;
     2836      num += ch;
     2837    }
     2838
     2839  /* check trailing spaces. */
     2840  while (isspace (*str))
     2841    str++;
     2842  if (*str)
     2843    {
     2844      error (NILF, _("bad number: '%s'\n"), start);
     2845      return 0;
     2846    }
     2847
     2848  return negative ? -num : num;
    28312849}
    28322850
     
    28352853func_int_add (char *o, char **argv, const char *funcname)
    28362854{
    2837     math_int num;
    2838     int i;
    2839 
    2840     num = math_int_from_string (argv[0]);
    2841     for (i = 1; argv[i]; i++)
    2842       num += math_int_from_string (argv[i]);
    2843 
    2844     return math_int_to_variable_buffer (o, num);
     2855  math_int num;
     2856  int i;
     2857
     2858  num = math_int_from_string (argv[0]);
     2859  for (i = 1; argv[i]; i++)
     2860    num += math_int_from_string (argv[i]);
     2861
     2862  return math_int_to_variable_buffer (o, num);
    28452863}
    28462864
     
    28492867func_int_sub (char *o, char **argv, const char *funcname)
    28502868{
    2851     math_int num;
    2852     int i;
    2853 
    2854     num = math_int_from_string (argv[0]);
    2855     for (i = 1; argv[i]; i++)
    2856       num -= math_int_from_string (argv[i]);
    2857 
    2858     return math_int_to_variable_buffer (o, num);
     2869  math_int num;
     2870  int i;
     2871
     2872  num = math_int_from_string (argv[0]);
     2873  for (i = 1; argv[i]; i++)
     2874    num -= math_int_from_string (argv[i]);
     2875
     2876  return math_int_to_variable_buffer (o, num);
    28592877}
    28602878
     
    28632881func_int_mul (char *o, char **argv, const char *funcname)
    28642882{
    2865     math_int num;
    2866     int i;
    2867 
    2868     num = math_int_from_string (argv[0]);
    2869     for (i = 1; argv[i]; i++)
    2870       num *= math_int_from_string (argv[i]);
    2871 
    2872     return math_int_to_variable_buffer (o, num);
     2883  math_int num;
     2884  int i;
     2885
     2886  num = math_int_from_string (argv[0]);
     2887  for (i = 1; argv[i]; i++)
     2888    num *= math_int_from_string (argv[i]);
     2889
     2890  return math_int_to_variable_buffer (o, num);
    28732891}
    28742892
     
    28772895func_int_div (char *o, char **argv, const char *funcname)
    28782896{
    2879     math_int num;
    2880     math_int divisor;
    2881     int i;
    2882 
    2883     num = math_int_from_string (argv[0]);
    2884     for (i = 1; argv[i]; i++)
    2885       {
    2886         divisor = math_int_from_string (argv[i]);
    2887         if (!divisor)
    2888           {
    2889             error (NILF, _("divide by zero ('%s')\n"), argv[i]);
    2890             return math_int_to_variable_buffer (o, 0);
    2891           }
    2892         num /= divisor;
    2893       }
    2894 
    2895     return math_int_to_variable_buffer (o, num);
     2897  math_int num;
     2898  math_int divisor;
     2899  int i;
     2900
     2901  num = math_int_from_string (argv[0]);
     2902  for (i = 1; argv[i]; i++)
     2903    {
     2904      divisor = math_int_from_string (argv[i]);
     2905      if (!divisor)
     2906        {
     2907          error (NILF, _("divide by zero ('%s')\n"), argv[i]);
     2908          return math_int_to_variable_buffer (o, 0);
     2909        }
     2910      num /= divisor;
     2911    }
     2912
     2913  return math_int_to_variable_buffer (o, num);
    28962914}
    28972915
     
    29012919func_int_mod (char *o, char **argv, const char *funcname)
    29022920{
    2903     math_int num;
    2904     math_int divisor;
    2905 
    2906     num = math_int_from_string (argv[0]);
    2907     divisor = math_int_from_string (argv[1]);
    2908     if (!divisor)
    2909       {
    2910         error (NILF, _("divide by zero ('%s')\n"), argv[1]);
    2911         return math_int_to_variable_buffer (o, 0);
    2912       }
    2913     num %= divisor;
    2914 
    2915     return math_int_to_variable_buffer (o, num);
     2921  math_int num;
     2922  math_int divisor;
     2923
     2924  num = math_int_from_string (argv[0]);
     2925  divisor = math_int_from_string (argv[1]);
     2926  if (!divisor)
     2927    {
     2928      error (NILF, _("divide by zero ('%s')\n"), argv[1]);
     2929      return math_int_to_variable_buffer (o, 0);
     2930    }
     2931  num %= divisor;
     2932
     2933  return math_int_to_variable_buffer (o, num);
    29162934}
    29172935
     
    29202938func_int_not (char *o, char **argv, const char *funcname)
    29212939{
    2922     math_int num;
    2923 
    2924     num = math_int_from_string (argv[0]);
    2925     num = ~num;
    2926 
    2927     return math_int_to_variable_buffer (o, num);
     2940  math_int num;
     2941
     2942  num = math_int_from_string (argv[0]);
     2943  num = ~num;
     2944
     2945  return math_int_to_variable_buffer (o, num);
    29282946}
    29292947
     
    29322950func_int_and (char *o, char **argv, const char *funcname)
    29332951{
    2934     math_int num;
    2935     int i;
    2936 
    2937     num = math_int_from_string (argv[0]);
    2938     for (i = 1; argv[i]; i++)
    2939       num &= math_int_from_string (argv[i]);
    2940 
    2941     return math_int_to_variable_buffer (o, num);
     2952  math_int num;
     2953  int i;
     2954
     2955  num = math_int_from_string (argv[0]);
     2956  for (i = 1; argv[i]; i++)
     2957    num &= math_int_from_string (argv[i]);
     2958
     2959  return math_int_to_variable_buffer (o, num);
    29422960}
    29432961
     
    29462964func_int_or (char *o, char **argv, const char *funcname)
    29472965{
    2948     math_int num;
    2949     int i;
    2950 
    2951     num = math_int_from_string (argv[0]);
    2952     for (i = 1; argv[i]; i++)
    2953       num |= math_int_from_string (argv[i]);
    2954 
    2955     return math_int_to_variable_buffer (o, num);
     2966  math_int num;
     2967  int i;
     2968
     2969  num = math_int_from_string (argv[0]);
     2970  for (i = 1; argv[i]; i++)
     2971    num |= math_int_from_string (argv[i]);
     2972
     2973  return math_int_to_variable_buffer (o, num);
    29562974}
    29572975
     
    29602978func_int_xor (char *o, char **argv, const char *funcname)
    29612979{
    2962     math_int num;
    2963     int i;
    2964 
    2965     num = math_int_from_string (argv[0]);
    2966     for (i = 1; argv[i]; i++)
    2967       num ^= math_int_from_string (argv[i]);
    2968 
    2969     return math_int_to_variable_buffer (o, num);
     2980  math_int num;
     2981  int i;
     2982
     2983  num = math_int_from_string (argv[0]);
     2984  for (i = 1; argv[i]; i++)
     2985    num ^= math_int_from_string (argv[i]);
     2986
     2987  return math_int_to_variable_buffer (o, num);
    29702988}
    29712989
     
    29993017
    30003018#endif /* CONFIG_WITH_MATH */
     3019
     3020#ifdef CONFIG_WITH_NANOTS
     3021/* Returns the current timestamp as nano seconds. The time
     3022   source is a high res monotone one if the platform provides
     3023   this (and we know about it).
     3024
     3025   Tip. Use this with int-sub to profile makefile reading
     3026        and similar. */
     3027static char *
     3028func_nanots (char *o, char **argv, const char *funcname)
     3029{
     3030  math_int ts;
     3031
     3032#if defined (WINDOWS32)
     3033  static int s_state = -1;
     3034  static LARGE_INTEGER s_freq;
     3035
     3036  if (s_state == -1)
     3037    s_state = QueryPerformanceFrequency (&s_freq);
     3038  if (s_state)
     3039    {
     3040      LARGE_INTEGER pc;
     3041      if (!QueryPerformanceCounter (&pc))
     3042        {
     3043          s_state = 0;
     3044          return func_nanots (o, argv, funcname);
     3045        }
     3046      ts = (math_int)((long double)pc.QuadPart / (long double)s_freq.QuadPart * 1000000000);
     3047    }
     3048  else
     3049    {
     3050      /* fall back to low resolution system time. */
     3051      LARGE_INTEGER bigint;
     3052      FILETIME ft = {0,0};
     3053      GetSystemTimeAsFileTime (&ft);
     3054      bigint.u.LowPart = ft.dwLowDateTime;
     3055      bigint.u.HighPart = ft.dwLowDateTime;
     3056      ts = bigint.QuadPart * 10000;
     3057    }
     3058
     3059/* FIXME: Linux and others has the realtime clock_* api, detect and use it. */
     3060
     3061#elif HAVE_GETTIMEOF_DAY
     3062  struct timeval tv;
     3063  if (!gettimeofday (&tv, NULL))
     3064    ts = (math_int)tv.tv_sec * 1000000000
     3065       + tv.tv_usec * 1000;
     3066  else
     3067    {
     3068      error (NILF, _("$(nanots): gettimeofday failed"));
     3069      ts = 0;
     3070    }
     3071
     3072#else
     3073# error "PORTME"
     3074#endif
     3075
     3076  return math_int_to_variable_buffer (o, ts);
     3077}
     3078#endif
    30013079
    30023080
     
    30983176  { STRING_SIZE_TUPLE("int-le"),        2,  2,  1,  func_int_cmp},
    30993177#endif
     3178#ifdef CONFIG_WITH_NANOTS
     3179  { STRING_SIZE_TUPLE("nanots"),        0,  0,  0,  func_nanots},
     3180#endif
    31003181#ifdef KMK_HELPERS
    31013182  { STRING_SIZE_TUPLE("kb-src-tool"),   1,  1,  0,  func_kbuild_source_tool},
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette