From owner-p4-projects@FreeBSD.ORG Thu May 28 08:11:53 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 3FCC81065677; Thu, 28 May 2009 08:11:52 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D6ECE1065670 for ; Thu, 28 May 2009 08:11:51 +0000 (UTC) (envelope-from dforsyth@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id C4E558FC13 for ; Thu, 28 May 2009 08:11:51 +0000 (UTC) (envelope-from dforsyth@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n4S8BpKj073440 for ; Thu, 28 May 2009 08:11:51 GMT (envelope-from dforsyth@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n4S8Bp9e073438 for perforce@freebsd.org; Thu, 28 May 2009 08:11:51 GMT (envelope-from dforsyth@FreeBSD.org) Date: Thu, 28 May 2009 08:11:51 GMT Message-Id: <200905280811.n4S8Bp9e073438@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to dforsyth@FreeBSD.org using -f From: David Forsythe To: Perforce Change Reviews Cc: Subject: PERFORCE change 162929 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 May 2009 08:11:53 -0000 http://perforce.freebsd.org/chv.cgi?CH=162929 Change 162929 by dforsyth@squirrel on 2009/05/28 08:11:31 Added tailq for subdir list. Affected files ... .. //depot/projects/soc2009/dforsyth_libpkg/pkg.c#2 edit .. //depot/projects/soc2009/dforsyth_libpkg/pkg.h#1 add .. //depot/projects/soc2009/dforsyth_libpkg/pkgdb.c#2 edit Differences ... ==== //depot/projects/soc2009/dforsyth_libpkg/pkg.c#2 (text+ko) ==== @@ -11,7 +11,6 @@ char *pkg_comment; char *cwd; int pkg_rev; - }; /* Create a new pkg. */ ==== //depot/projects/soc2009/dforsyth_libpkg/pkgdb.c#2 (text+ko) ==== @@ -15,8 +15,8 @@ char *db_root; int sd_count; + struct pkgdb_subdir *sd_curr; TAILQ_HEAD(sd_head, pkgdb_subdir) *sd_headp; - struct pkgdb_subdir *sd_curr; /* Callbacks */ /* tuuuummmmbbbllleeewwwweeeedddddd*/ @@ -64,13 +64,14 @@ } strcpy(db->db_root, db_root); - db->sd_headp = malloc(sizeof(struct sd_head)); + db->sd_headp = malloc(sizeof(*db->sd_headp)); if (db->sd_headp == NULL) { pkgdb_free_hierdb(db); return (NULL); } + memset(db->sd_headp, 0, sizeof(*db->sd_headp)); + TAILQ_INIT(db->sd_headp); - db->sd_count = 0; db->dirty = 1; @@ -109,82 +110,61 @@ /* Read in the names of all subdirectories in db->db_root, and add them to * the db's package list. Set the current package to the head of the * list. The packages in db's package list are not verified. Returns the - * number of packages in teh database. */ + * number of subdirectories in the database. */ -struct pkgdb * +int pkgdb_reset(struct pkgdb *db) { + int i; struct pkgdb_subdir *sd; + struct dirent **ents; if (db == NULL) - return (db); + return (-1); if (db->dirty == 0) { /* No changes since the last reset, don't bother walking the * database again. */ db->sd_curr = TAILQ_FIRST(db->sd_headp); - return (db); + return (db->sd_count); } - /* Should there be another function to set this? */ - db->sd_count = pkgdb_subdir_count(db); + db->sd_count = scandir(db->db_root, &ents, subdir_sel, alphasort); - if (db->sd_count == 0) - return (db); - - db->sd_curr = pkgdb_subdir_hash(db); + /* Clear out old list. */ + pkgdb_free_pkgdb_subdir_list(db); - /* - TAILQ_FOREACH(sd, db->sd_headp, next) { - printf("%s\n", sd->name); + TAILQ_INIT(db->sd_headp); + for (i = 0; i < db->sd_count; ++i) { + sd = pkgdb_read_subdir(db, ents[i]->d_name); + if (sd == NULL) { + pkgdb_free_pkgdb_subdir_list(db); + return (-1); + } + TAILQ_INSERT_TAIL(db->sd_headp, sd, next); + free(ents[i]); } - exit(0); - */ db->dirty = 0; - return (db); + + db->sd_curr = TAILQ_FIRST(db->sd_headp); + + return (db->sd_count); } -/* Rebuild dbs pkg_list linked list. */ - -struct pkgdb_subdir * -pkgdb_subdir_hash(struct pkgdb *db) +int +subdir_sel(struct dirent *ent) { - /* Immediate TODO: Sort on insert. */ - DIR *db_root_dirp; - struct dirent *ent; - - struct pkgdb_subdir *sd_head; - struct pkgdb_subdir *sd_ent; - - if (db == NULL) - return (NULL); - - db_root_dirp = opendir(db->db_root); - if (db_root_dirp == NULL) - return (NULL); - - TAILQ_INIT(db->sd_headp); - while ((ent = readdir(db_root_dirp)) != NULL) { - if (strcmp(ent->d_name, ".") == 0 || - strcmp(ent->d_name, "..") == 0) - continue; - sd_ent = pkgdb_read_subdir(db, ent->d_name); - if (sd_ent == NULL) { - pkgdb_free_pkg_list(db); - return (NULL); - } - TAILQ_INSERT_TAIL(db->sd_headp, sd_ent, next); - } - - return (TAILQ_FIRST(db->sd_headp)); + if (strcmp(ent->d_name, ".") != 0 && strcmp(ent->d_name, "..") != 0) + return (1); + return (0); } struct pkgdb_subdir * pkgdb_read_subdir(struct pkgdb *db, const char *name) { struct pkgdb_subdir *sd; - + sd = malloc(sizeof(*sd)); if (sd == NULL) return (NULL); @@ -199,50 +179,28 @@ return (sd); } -/* Move the current package pointer to the next package in db's package - * list. If there are no more left, return NULL. */ +/* Move the current subdir pointer to the next one in the list. Return + * the previous subdir. Return NULL if there are no more left. */ struct pkg * pkgdb_next_pkg(struct pkgdb *db) { struct pkg *p; struct pkgdb_subdir *sd; - char *pkg_name; if (db == NULL) return (NULL); sd = db->sd_curr; - if (sd == NULL) + if (db->sd_curr == NULL) return (NULL); - - db->sd_curr = TAILQ_NEXT(sd, next); + + db->sd_curr = TAILQ_NEXT(db->sd_curr, next); p = pkg_new(sd->name); - return (p); } -/* Wrapped per advice (non-portable code). Count the number of - * subdirectories in db->db_root by counting the number of hard links to - * it. */ - -int -pkgdb_subdir_count(struct pkgdb *db) -{ - int s; - struct stat sb; - - if (db == NULL) - return (-1); - - s = stat(db->db_root, &sb); - if (s != 0) - return (-1); - - return (sb.st_nlink - 2); -} - /* Free a hierdb. */ void @@ -250,58 +208,47 @@ { if (db == NULL) return; - + free(db->db_root); - pkgdb_free_pkg_list(db); + pkgdb_free_pkgdb_subdir_list(db); free(db); } void -pkgdb_free_pkgdb_subdir(struct pkgdb_subdir *sd) +pkgdb_free_pkgdb_subdir_list(struct pkgdb *db) { - if (sd == NULL) - return; + struct pkgdb_subdir *sd; + struct pkgdb_subdir *sdn; - free(sd->name); - free(sd); + sd = TAILQ_FIRST(db->sd_headp); + while (sd != NULL) { + sdn = TAILQ_NEXT(sd, next); + pkgdb_free_pkgdb_subdir(sd); + sd = sdn; + } + TAILQ_INIT(db->sd_headp); } void -pkgdb_free_pkg_list(struct pkgdb *db) +pkgdb_free_pkgdb_subdir(struct pkgdb_subdir *sd) { - if (db == NULL) + if (sd == NULL) return; - // meh - return; + free(sd->name); + free(sd); } -/* Free the package list in a pkgdb. */ - void -free_cstr_array(char **arr) +free_ptr_array(void **arr, int c) { - char *ent; + int i; if (arr == NULL) return; - while((ent = *arr++) != NULL) - free(ent); + for (i = 0; i < c; ++i) + free(arr[i]); free(arr); } - -/* Comparison function for package list sorting. */ - -int -pkg_strcmp(const void *a, const void *b) -{ - const char *str1; - const char *str2; - - str1 = *(char * const *)a; - str2 = *(char * const *)b; - - return (strcmp(str1, str2)); -}