glob method

int glob(
  1. String pattern,
  2. int flags,
  3. int errfunc(
    1. String,
    2. int
    )?,
  4. glob_t pglob,
)

Find pathnames matching a pattern.

Implementation

int glob(String pattern, int flags, int Function(String, int)? errfunc, glob_t pglob) {
  if ((flags & GLOB_APPEND) == 0) {
    pglob.gl_pathc = 0;
    pglob.gl_pathv = [];
    if ((flags & GLOB_DOOFFS) != 0) {
      for (int i = 0; i < pglob.gl_offs; i++) {
        pglob.gl_pathv.add(""); // Reserve slots
      }
    }
  }

  try {
    // Simplified pure-Dart glob implementation.
    // This will scan the current directory or the specified directory structure.
    final dirPattern = p.dirname(pattern);

    final searchDir = dirPattern == '.' ? Directory.current : Directory(dirPattern);
    if (!searchDir.existsSync()) {
      if ((flags & GLOB_NOCHECK) != 0) {
        pglob.gl_pathv.add(pattern);
        pglob.gl_pathc++;
        return 0;
      }
      return GLOB_NOMATCH;
    }

    int fnmFlags = 0;
    if ((flags & GLOB_NOESCAPE) != 0) fnmFlags |= FNM_NOESCAPE;
    // Usually glob uses FNM_PATHNAME and FNM_PERIOD semantics inherently
    fnmFlags |= FNM_PATHNAME | FNM_PERIOD;

    final entries = searchDir.listSync(recursive: pattern.contains('**'));

    int matchCount = 0;
    List<String> matches = [];

    for (var entry in entries) {
      final path = entry.path;
      final relPath = p.relative(path, from: Directory.current.path);
      final toMatch = dirPattern == '.' ? relPath : path;

      if (fnmatch(pattern, toMatch, fnmFlags) == 0) {
        String finalPath = toMatch;
        if ((flags & GLOB_MARK) != 0 && entry is Directory) {
          finalPath += '/';
        }
        matches.add(finalPath);
        matchCount++;
      }
    }

    if (matchCount == 0 && (flags & GLOB_NOCHECK) != 0) {
      matches.add(pattern);
      matchCount++;
    }

    if (matchCount == 0) {
      return GLOB_NOMATCH;
    }

    if ((flags & GLOB_NOSORT) == 0) {
      matches.sort();
    }

    pglob.gl_pathv.addAll(matches);
    pglob.gl_pathc += matchCount;

    return 0;
  } catch (e) {
    return GLOB_ABORTED;
  }
}