Ignore:
Timestamp:
Oct 1, 2007, 7:15:26 AM (18 years ago)
Author:
bird
Message:

Added a $(which ) function. takes any number of args, with or without commas between them.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/function.c

    r1124 r1171  
    26802680  return (char *)"strptime is not implemented";
    26812681}
    2682 # endif 
     2682# endif
    26832683/* Check if the string is all blanks or not. */
    26842684static int
     
    26922692}
    26932693
    2694 /* The first argument is the strftime format string, a iso 
     2694/* The first argument is the strftime format string, a iso
    26952695   timestamp is the default if nothing is given.
    26962696
     
    27092709  /* determin the format - use a single word as the default. */
    27102710  format = !strcmp (funcname, "date-utc")
    2711          ? "%Y-%m-%dT%H:%M:%SZ" 
     2711         ? "%Y-%m-%dT%H:%M:%SZ"
    27122712         : "%Y-%m-%dT%H:%M:%S";
    27132713  if (!all_blanks (argv[0]))
     
    27222722      if (!p || *p != '\0')
    27232723        {
    2724           error (NILF, _("$(%s): strptime(%s,%s,) -> %s\n"), funcname, 
     2724          error (NILF, _("$(%s): strptime(%s,%s,) -> %s\n"), funcname,
    27252725                 argv[1], input_format, p ? p : "<null>");
    27262726          return variable_buffer_output (o, "", 1);
     
    27372737    }
    27382738
    2739   /* format it. note that zero isn't necessarily an error, so we'll 
     2739  /* format it. note that zero isn't necessarily an error, so we'll
    27402740     have to keep shut about failures. */
    27412741  buf_size = 64;
     
    27572757
    27582758#ifdef CONFIG_WITH_FILE_SIZE
    2759 /* Prints the size of the specified file. Only one file is 
     2759/* Prints the size of the specified file. Only one file is
    27602760   permitted, notthing is stripped. -1 is returned if stat
    27612761   fails. */
     
    27702770#endif
    27712771
     2772#ifdef CONFIG_WITH_WHICH
     2773/* Checks if the specified file exists an is executable.
     2774   On systems employing executable extensions, the name may
     2775   be modified to include the extension. */
     2776static int func_which_test_x (char *file)
     2777{
     2778  struct stat st;
     2779# if defined(WINDOWS32) || defined(__OS2__)
     2780  char *ext;
     2781  char *slash;
     2782
     2783  /* fix slashes first. */
     2784  slash = file;
     2785  while ((slash = strchr (slash, '\\')) != NULL)
     2786    *slash++ = '/';
     2787
     2788  /* straight */
     2789  if (stat (file, &st) == 0
     2790    && S_ISREG (st.st_mode))
     2791    return 1;
     2792
     2793  /* don't try add an extension if there already is one */
     2794  ext = strchr (file, '\0');
     2795  if (ext - file >= 4
     2796   && (   !stricmp (ext - 4, ".exe")
     2797       || !stricmp (ext - 4, ".cmd")
     2798       || !stricmp (ext - 4, ".bat")
     2799       || !stricmp (ext - 4, ".com")))
     2800    return 0;
     2801
     2802  /* try the extensions. */
     2803  strcpy (ext, ".exe");
     2804  if (stat (file, &st) == 0
     2805    && S_ISREG (st.st_mode))
     2806    return 1;
     2807
     2808  strcpy (ext, ".cmd");
     2809  if (stat (file, &st) == 0
     2810    && S_ISREG (st.st_mode))
     2811    return 1;
     2812
     2813  strcpy (ext, ".bat");
     2814  if (stat (file, &st) == 0
     2815    && S_ISREG (st.st_mode))
     2816    return 1;
     2817
     2818  strcpy (ext, ".com");
     2819  if (stat (file, &st) == 0
     2820    && S_ISREG (st.st_mode))
     2821    return 1;
     2822
     2823  return 0;
     2824
     2825# else
     2826
     2827  return access (file, X_OK) == 0
     2828     && stat (file, &st) == 0
     2829     && S_ISREG (st.st_mode);
     2830# endif
     2831}
     2832
     2833/* Searches for the specified programs in the PATH and print
     2834   their full location if found. Prints nothing if not found. */
     2835static char *
     2836func_which (char *o, char **argv, const char *funcname)
     2837{
     2838  const char *path;
     2839  struct variable *path_var;
     2840  unsigned i;
     2841  PATH_VAR (buf);
     2842
     2843  path_var = lookup_variable ("PATH", 4);
     2844  if (path_var)
     2845    path = path_var->value;
     2846  else
     2847    path = ".";
     2848
     2849  /* iterate input */
     2850  for (i = 0; argv[i]; i++)
     2851    {
     2852      unsigned int len;
     2853      const char *iterator = argv[i];
     2854      char *cur;
     2855
     2856      while ((cur = find_next_token (&iterator, &len)))
     2857        {
     2858          /* if there is a separator, don't walk the path. */
     2859          if (memchr (cur, '/', len)
     2860#ifdef HAVE_DOS_PATHS
     2861           || memchr (cur, '\\', len)
     2862           || memchr (cur, ':', len)
     2863#endif
     2864             )
     2865            {
     2866              if (len + 1 + 4 < GET_PATH_MAX) /* +4 for .exe */
     2867                {
     2868                  memcpy (buf, cur, len);
     2869                  buf[len] = '\0';
     2870                  if (func_which_test_x (buf))
     2871                    o = variable_buffer_output (o, buf, strlen (buf));
     2872                }
     2873            }
     2874          else
     2875            {
     2876              const char *comp = path;
     2877              for (;;)
     2878                {
     2879                  const char *src = comp;
     2880                  const char *end = strchr (comp, PATH_SEPARATOR_CHAR);
     2881                  size_t comp_len = end ? end - comp : strlen (comp);
     2882                  if (!comp_len)
     2883                    {
     2884                      comp_len = 1;
     2885                      src = ".";
     2886                    }
     2887                  if (len + comp_len + 2 + 4 < GET_PATH_MAX) /* +4 for .exe */
     2888                    {
     2889                      memcpy (buf, comp, comp_len);
     2890                      buf [comp_len] = '/';
     2891                      memcpy (&buf[comp_len + 1], cur, len);
     2892                      buf[comp_len + 1 + len] = '\0';
     2893
     2894                      if (func_which_test_x (buf))
     2895                        {
     2896                          o = variable_buffer_output (o, buf, strlen (buf));
     2897                          break;
     2898                        }
     2899                    }
     2900
     2901                  /* next */
     2902                  if (!end)
     2903                    break;
     2904                  comp = end + 1;
     2905                }
     2906            }
     2907        }
     2908    }
     2909
     2910  return variable_buffer_output (o, "", 1);
     2911}
     2912#endif
    27722913
    27732914#ifdef CONFIG_WITH_STACK
     
    32573398  { STRING_SIZE_TUPLE("file-size"),     1,  1,  1,  func_file_size},
    32583399#endif
     3400#ifdef CONFIG_WITH_WHICH
     3401  { STRING_SIZE_TUPLE("which"),         0,  0,  1,  func_which},
     3402#endif
    32593403#ifdef CONFIG_WITH_STACK
    32603404  { STRING_SIZE_TUPLE("stack-push"),    2,  2,  1,  func_stack_push},
Note: See TracChangeset for help on using the changeset viewer.