Nп/п : 68 из 100
 От   : Kaz Kylheku                         2:5075/128        12 сен 23 06:47:05
 К    : Kaz Kylheku                                           12 сен 23 09:49:02
 Тема : Re: Wrapper for glob() that implements /**/ sub-pattern.
----------------------------------------------------------------------------------
                                                                                 
@MSGID: <20230911234401.851@kylheku.com> 32d1c8e9
@REPLY: <20230911202309.171@kylheku.com> fbc96f34
@REPLYADDR Kaz Kylheku <864-117-4973@kylheku.com>
@REPLYTO 2:5075/128 Kaz Kylheku
@CHRS: CP866 2
@RFC: 1 0
@RFC-Message-ID: <20230911234401.851@kylheku.com>
@RFC-References: <20230911202309.171@kylheku.com>
@TZUTC: -0000
@PID: slrn/pre1.0.4-9 (Linux)
@TID: FIDOGATE-5.12-ge4e8b94
On 2023-09-12, Kaz Kylheku <864-117-4973@kylheku.com> wrote:
> The real function should handle patterns starting with "**/" and also
> ending in "/**", as well as when "**" is the entire pattern.

I fixed this in the prototype.

#include 
#include 
#include 
#include 

static int super_glob_rec(const char *pattern, int flags,
                          int (*errfunc) (const char *epath, int eerrno),
                          glob_t *pglob, size_t star_limit)
{
  const char *dblstar = 0;

  if (strncmp(pattern, "**/", 3) == 0 || strcmp(pattern, "**") == 0) {
    dblstar = pattern;
  } else if ((dblstar = strstr(pattern, "/**/")) != 0) {
    dblstar++;
  } else if (strlen(pattern) >= 3) {
    const char *end = pattern + strlen(pattern);
    if (strcmp(end - 3, "/**") == 0)
      dblstar = end - 2;
  }

  if (dblstar == 0) {
    return glob(pattern, flags, errfunc, pglob);
  } else {
    size_t i, base_len = strlen(pattern);
    size_t ds_off = dblstar - pattern;
    size_t tail_off = ds_off + 2;
    size_t limit = star_limit > 10 ? 10 : star_limit;

    for (i = 0; i < limit; i++) {
      size_t space = base_len - 3 + i * 2;
      char *pat_copy = malloc(space + 2);
      size_t j;
      char *out = pat_copy + ds_off;
      int res;

      strncpy(pat_copy, pattern, ds_off);

      for (j = 0; j < i; j++) {
        *out++ = `*`;
        if (j < i - 1)
          *out++ = `/`;
      }

      strcpy(out, pattern + tail_off);

      if (i > 0)
        flags |= GLOB_APPEND;

      res = super_glob_rec(pat_copy, flags, errfunc, pglob, star_limit - i);

      free(pat_copy);

      if (res && res != GLOB_NOMATCH)
        return res;
    }

    return 0;
  }
}

static int super_glob(const char *pattern, int flags,
                      int (*errfunc) (const char *epath, int eerrno),
                      glob_t *pglob)
{
  return super_glob_rec(pattern, flags, errfunc, pglob, 48);
}


int main(int argc, char **argv)
{
  int status = EXIT_FAILURE;

  if (argc == 2) {
    glob_t glb;
    int res = super_glob(argv[1], 0, NULL, &glb);
    if (res && res != GLOB_NOMATCH) {
      fprintf(stderr, "%s: glob failed with %d
", argv[0], res);
    } else {
      for (size_t i = 0; i < glb.gl_pathc; i++)
        puts(glb.gl_pathv[i]);
    }
    globfree(&glb);
  } else if (argc == 1) {
    fprintf(stderr, "%s: specify one glob pattern argument
", argv[0]);
  }

  return status;
}
--- slrn/pre1.0.4-9 (Linux)
 * Origin: A noiseless patient Spider (2:5075/128)
SEEN-BY: 5001/100 5005/49 5010/352 5015/255 5019/40
5020/715 848 1042 4441
SEEN-BY: 5020/12000 5030/49 1081 5075/128
@PATH: 5075/128 5020/1042 4441



   GoldED+ VK   │                                                 │   09:55:30    
                                                                                
В этой области больше нет сообщений.

Остаться здесь
Перейти к списку сообщений
Перейти к списку эх