File-Locate

 view release on metacpan or  search on metacpan

Locate.xs  view on Meta::CPAN

    DEFSV = sv_2mortal(newSVpvn(path, strlen(path)));
    PUTBACK;
    (void) call_sv(coderef, G_DISCARD);
    
    FREETMPS;
    LEAVE;
}
#define WARN fprintf(stderr, "%i\n", __LINE__);

MODULE = File::Locate		PACKAGE = File::Locate		

INCLUDE: const-xs.inc

BOOT:
    {
	UID = getuid();
	GID = getgid();
    }

void
_locate (pathpart, ...) 
        char *pathpart;
    PROTOTYPE: DISABLE
    PREINIT:
        char *dbfile = NULL;
        SV   *coderef = NULL;
        FILE *fp;           /* The pathname database.  */
        int c;              /* An input byte.  */
        int nread;          /* Number of bytes read from an entry.  */
        boolean globflag;   /* true if PATHPART contains globbing 
                               metacharacters.  */
        char *patend;       /* The end of the last glob-free subpattern 
                               in PATHPART.  */
        char *path;         /* The current input database entry.  */
        size_t pathsize;    /* Amount allocated for it.  */
        int count = 0;      /* The length of the prefix shared with 
                               the previous database entry.  */
        char *cutoff;       /* Where in `path' to stop the backward search for
                               the last character in the subpattern.  Set
                               according to `count'.  */
        boolean prev_fast_match = false;    /* true if we found a fast match
                                               (of patend) on the previous
                                               path.  */
        int printed = 0;                    /* The return value.  */
        boolean old_format = false;         /* true if reading a bigram-encoded
                                               database.  */
        char bigram1[128], bigram2[128];    /* For the old database format, the
                                               first and second characters of
                                               the most common bigrams.  */
	/* regex stuff */
	int REGEX = 0;
	int NOCASE = 0;
	int EXTENDED = 0;
	int reg_res;
	int nmatch = 32;
	regex_t *preg = NULL;
	char errbuf[1024];
	regmatch_t pmatch[32];
        STRLEN n_a;
	register int i;
    PPCODE:
    
	for (i = 1; i < items; i++) {
            if (SvROK(ST(i)) && SvTYPE((SV*)SvRV(ST(i))) == SVt_PVCV) {
                coderef = newSVsv(ST(i));
            }
            else {
		char *key = SvPV(ST(i), n_a);
		if (*key == '-') {
		    if (strnEQ(key+1, "rexopt", 6)) {
			char *val;
			i++;
			val = SvPV(ST(i), n_a);
			if (strchr(val, (int)'e'))
			    EXTENDED = 1;
			if (strchr(val, (int)'i'))
			    NOCASE = 1;
			continue;
		    }
		    else if (strnEQ(key+1, "rex", 3)) {
			i++;
			REGEX = SvTRUE(ST(i));
			continue;
		    }
		}
		if (!dbfile) {
		    dbfile = savepv(key);
		}
	    }
        }
    
	if (!dbfile) 
	    croak("No database (shouldn't happen)");

        if ((fp = fopen (dbfile, "r")) == NULL) 
            XSRETURN_UNDEF;

        pathsize = 1026;		/* Increased as necessary by getstr.  */
	New(0, path, pathsize, char);

        nread = fread (path, 1, sizeof (LOCATEDB_MAGIC), fp);
        if (nread != sizeof (LOCATEDB_MAGIC) || 
            memcmp (path, LOCATEDB_MAGIC, sizeof (LOCATEDB_MAGIC))) {
            int i;
            /* Read the list of the most common bigrams in the database.  */
            fseek (fp, 0, 0);
            for (i = 0; i < 128; i++) {
                bigram1[i] = getc (fp);
                bigram2[i] = getc (fp);
            }
            old_format = true;
        }

        globflag =  strchr (pathpart, '*') || 
                    strchr (pathpart, '?') || 
                    strchr (pathpart, '[');

        patend = last_literal_end (pathpart);
	
	if (REGEX) {
	    int flags = 0;

Locate.xs  view on Meta::CPAN

        }
	
	Safefree(dbfile);
        Safefree(path);

        fclose(fp);
        
        if(GIMME_V == G_ARRAY)
            XSRETURN(printed);
        else if (printed && GIMME_V == G_SCALAR)
            XSRETURN_YES;

        XSRETURN_NO;

void
_slocate (str, ...)
	char *str;
    PREINIT:
	char *dbfile = NULL;
	SV *coderef = NULL;
	int fd;
	short code_num;
	int pathlen=0;
	register char ch;
	int jump=0;
	int first=1;
	char *codedpath=NULL;
	char *code_ptr;
	int printit=0;
	int globflag=0;
	char *globptr1;
	struct stat statres;
	regex_t *preg=NULL;
	char errbuf[1024];
	int nmatch=32;
	regmatch_t pmatch[32];
	int reg_res;
	int bytes = -1;
	int ptr_offset;
	char one_char[1];
	char *begin_ptr;
        int begin_offset=0;
	int tot_size = MIN_BLK;
	int cur_size;
	int code_tot_size = MIN_BLK;

	char *bucket_of_holding=NULL;
	STRLEN n_a;
	/* these vars were global in slocate/main.c */
	int REGEX = 0;
	int NOCASE  = 0;
	int EXTENDED = 0;

	char slevel = '1';
	int res = 0;

        boolean prev_fast_match = false;    /* true if we found a fast match
                                               (of patend) on the previous
                                               path.  */
	register int i;
    PPCODE:
    {
	for (i = 1; i < items; i++) {
            if (SvROK(ST(i)) && SvTYPE((SV*)SvRV(ST(i))) == SVt_PVCV) {
                coderef = newSVsv(ST(i));
            }
            else {
		char *key = SvPV(ST(i), n_a);
		if (*key == '-') {
		    if (strnEQ(key+1, "rexopt", 6)) {
			char *val;
			i++;
			val = SvPV(ST(i), n_a);
			if (strchr(val, (int)'e'))
			    EXTENDED = 1;
			if (strchr(val, (int)'i'))
			    NOCASE = 1;
			continue;
		    }
		    else if (strnEQ(key+1, "rex", 3)) {
			i++;
			REGEX = SvTRUE(ST(i));
			continue;
		    }
		}
		if (!dbfile) {
		    dbfile = savepv(key);
		}
	    }
        }

	if (!dbfile) 
	    croak("No database (shouldn't happen)");
		    
	if ((fd = open(dbfile,O_RDONLY)) == -1) {
	    croak("Can't open dbfile '%s': %s\n", dbfile, strerror(errno));
	}
	
	lstat(dbfile,&statres);
	
	if (S_ISDIR(statres.st_mode)) {
	    croak("Database '%s' is a directory\n", dbfile); 
	}
	
	read(fd,one_char,1);
	slevel = *one_char;

	New(0, codedpath, MIN_BLK, char);
	*codedpath = 0;
	code_ptr = codedpath;

	if ((globptr1 = strchr(str,'*'))  != NULL ||
	    (globptr1 = strchr(str,'?'))  != NULL ||
	    ((globptr1 = strchr(str,'[')) != NULL && 
	    strchr(str,']') != NULL))
	    globflag = 1;

	if (REGEX) {
	    New(0, preg, 1, regex_t);
	    if ((reg_res = regcomp(preg, str, NOCASE ? REG_ICASE : 0)) != 0) {
		    regerror(reg_res, preg, errbuf,1024);



( run in 1.197 second using v1.01-cache-2.11-cpan-71847e10f99 )