示例#1
0
文件: myglob.c 项目: g4idrijs/jhead
//--------------------------------------------------------------------------------
// The main program.
//--------------------------------------------------------------------------------
int main (int argc, char **argv)
 {
    int argn;
    char * arg;
    int Subdirs = 0;

    for (argn=1;argn<argc;argn++){
        arg = argv[argn];
        if (arg[0] != '-') break; // Filenames from here on.
        if (!strcmp(arg,"-r")){
            printf("do recursive\n");
            Subdirs = 1;
        }else{
            fprintf(stderr, "Argument '%s' not understood\n",arg);
        }
    }
    if (argn == argc){
        fprintf(stderr,"Error: Must supply a file name\n");
    }

    for (;argn<argc;argn++){
        MyGlob(argv[argn], ShowName);
    }
    return EXIT_SUCCESS;
}
示例#2
0
value
myglob (value v_pat, value v_fun)
{
    CAMLparam2(v_pat,v_fun);
    const char * pat = String_val(v_pat);
    MyGlob (pat, v_fun);
    CAMLreturn(Val_int(0));
}
示例#3
0
文件: myglob.c 项目: g4idrijs/jhead
//--------------------------------------------------------------------------------
// Decide how a particular pattern should be handled, and call function for each.
//--------------------------------------------------------------------------------
void MyGlob(const char * Pattern , void (*FileFuncParm)(const char * FileName))
{
    char BasePattern[_MAX_PATH];
    char MatchPattern[_MAX_PATH];
    char PatCopy[_MAX_PATH*2+1];

    int a;

    int MatchFiles, MatchDirs;
    int BaseEnd, PatternEnd;
    int SawPat;
    int RecurseAt;

    strcpy(PatCopy, Pattern);

    #ifdef DEBUGGING
        printf("Called with '%s'\n",Pattern);
    #endif

DoRecursion:
    MatchFiles = FALSE;
    MatchDirs = TRUE;
    BaseEnd = 0;
    PatternEnd = 0;

    SawPat = FALSE;
    RecurseAt = -1;

    // Split the path into base path and pattern to match against using findfirst.
    for (a=0;;a++){
        if (PatCopy[a] == '*' || PatCopy[a] == '?'){
            SawPat = TRUE;
        }

        if (PatCopy[a] == '*' && PatCopy[a+1] == '*'){
            if (a == 0 || PatCopy[a-1] == '\\' || PatCopy[a-1] == ':'){
                if (PatCopy[a+2] == '\\' || PatCopy[a+2] == '\0'){
                    // x\**\y  ---> x\y  x\*\**\y
                    RecurseAt = a;
                    if (PatCopy[a+2]){
                        memcpy(PatCopy+a, PatCopy+a+3, strlen(PatCopy)-a-1);
                    }else{
                        PatCopy[a+1] = '\0';
                    }
                }
            }
        }

        if (PatCopy[a] == '\\' || (PatCopy[a] == ':' && PatCopy[a+1] != '\\')){
            PatternEnd = a;
            if (SawPat) break; // Findfirst can only match one level of wildcard at a time.
            BaseEnd = a+1;
        }
        if (PatCopy[a] == '\0'){
            PatternEnd = a;
            MatchFiles = TRUE;
            MatchDirs = FALSE;
            break;
        }
    }

    if (!SawPat){
        // No pattern.  This should refer to a file.
        FileFuncParm(PatCopy);
        return;
    }

    strncpy(BasePattern, PatCopy, BaseEnd);
    BasePattern[BaseEnd] = 0;

    strncpy(MatchPattern, PatCopy, PatternEnd);
    MatchPattern[PatternEnd] = 0;

    #ifdef DEBUGGING
        printf("Base:%s  Pattern:%s Files:%d dirs:%d\n",BasePattern, MatchPattern, MatchFiles, MatchDirs);
    #endif

    {
        FileEntry * FileList = NULL;
        int NumAllocated = 0;
        int NumHave = 0;
        
        struct _finddata_t finddata;
        long find_handle;

        find_handle = _findfirst(MatchPattern, &finddata);

        for (;;){
            if (find_handle == -1) break;

            // Eliminate the obvious patterns.
            if (!memcmp(finddata.name, ".",2)) goto next_file;
            if (!memcmp(finddata.name, "..",3)) goto next_file;

            if (finddata.attrib & _A_SUBDIR){
                if (!MatchDirs) goto next_file;
            }else{
                if (!MatchFiles) goto next_file;
            }

            // Add it to the list.
            if (NumAllocated <= NumHave){
                NumAllocated = NumAllocated+10+NumAllocated/2;
                FileList = realloc(FileList, NumAllocated * sizeof(FileEntry));
                if (FileList == NULL) goto nomem;
            }
            a = strlen(finddata.name);
            FileList[NumHave].Name = malloc(a+1);
            if (FileList[NumHave].Name == NULL){
                nomem:
                printf("malloc failure\n");
                exit(-1);
            }
            memcpy(FileList[NumHave].Name, finddata.name, a+1);
            FileList[NumHave].attrib = finddata.attrib;
            NumHave++;

            next_file:
            if (_findnext(find_handle, &finddata) != 0) break;
        }
        _findclose(find_handle);

        // Sort the list...
        qsort(FileList, NumHave, sizeof(FileEntry), CompareFunc);


        // Use the list.
        for (a=0;a<NumHave;a++){
            char CombinedName[_MAX_PATH*2+1];
            if (FileList[a].attrib & _A_SUBDIR){
                if (MatchDirs){
                    // Need more directories.
                    SplicePath(CombinedName, BasePattern, FileList[a].Name);
                    strncat(CombinedName, PatCopy+PatternEnd, _MAX_PATH*2-strlen(CombinedName));
                    MyGlob(CombinedName,FileFuncParm);
                }
            }else{
                if (MatchFiles){
                    // We need files at this level.
                    SplicePath(CombinedName, BasePattern, FileList[a].Name);
                    FileFuncParm(CombinedName);
                }
            }
            free(FileList[a].Name);
        }
        free(FileList);
    }

    if(RecurseAt >= 0){
        strcpy(MatchPattern, PatCopy+RecurseAt);
        PatCopy[RecurseAt] = 0;
        strncpy(PatCopy+RecurseAt, "*\\**\\", _MAX_PATH*2-RecurseAt);
        strncat(PatCopy, MatchPattern, _MAX_PATH*2-strlen(PatCopy));
       
        #ifdef DEBUGGING
            printf("Recurse with '%s'\n",PatCopy);
        #endif

        // As this function context is no longer needed, we can just goto back
        // to the top of it to avoid adding another context on the stack.
        goto DoRecursion;
    }
}