diff options
author | Ting-Wei Lan <lantw44@gmail.com> | 2014-02-12 23:54:22 +0800 |
---|---|---|
committer | Ting-Wei Lan <lantw44@gmail.com> | 2014-02-12 23:54:22 +0800 |
commit | e1a6bb4cc192e9ae5d808b13bad4e122b759fbc1 (patch) | |
tree | f4bf5dd3cf9275d3c68c611e1b7fca5aa90c1113 | |
parent | 8cc9deef211881d186a2b02c0423d2644f2c3526 (diff) | |
download | wspkg-e1a6bb4cc192e9ae5d808b13bad4e122b759fbc1.tar wspkg-e1a6bb4cc192e9ae5d808b13bad4e122b759fbc1.tar.gz wspkg-e1a6bb4cc192e9ae5d808b13bad4e122b759fbc1.tar.bz2 wspkg-e1a6bb4cc192e9ae5d808b13bad4e122b759fbc1.tar.lz wspkg-e1a6bb4cc192e9ae5d808b13bad4e122b759fbc1.tar.xz wspkg-e1a6bb4cc192e9ae5d808b13bad4e122b759fbc1.tar.zst wspkg-e1a6bb4cc192e9ae5d808b13bad4e122b759fbc1.zip |
先前找 ports directory 的 script 效能太差,已用 C 重寫
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | freebsd.ports.find.c | 139 | ||||
-rwxr-xr-x | freebsd.ports.sh | 29 |
3 files changed, 145 insertions, 29 deletions
@@ -4,7 +4,7 @@ all: debian freebsd -.pkg.list: packages.h +.pkg.list: packages.h packages.sh @echo "==> Generating list file $@" ./packages.sh `echo "$<" | cut -d . -f 1` | sort | uniq > "$@" || rm -f "$@" @@ -13,9 +13,11 @@ debian.control: debian.list freebsd: freebsd.makefile freebsd.makefile: freebsd.list freebsd.ports -freebsd.ports: freebsd.list +freebsd.ports: freebsd.list freebsd.ports.sh freebsd.ports.find @echo "==> Generating $@" ./freebsd.ports.sh freebsd.list > "$@" || rm -f "$@" +freebsd.ports.find: freebsd.ports.find.c + c99 -DHASH_TABLE_SIZE=50000 "$<" -o "$@" clean: rm -f *.control *.makefile *.ports *.list diff --git a/freebsd.ports.find.c b/freebsd.ports.find.c new file mode 100644 index 0000000..309ea89 --- /dev/null +++ b/freebsd.ports.find.c @@ -0,0 +1,139 @@ +#define _POSIX_C_SOURCE 200809L +#include <stdbool.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <search.h> + +#ifndef HASH_TABLE_SIZE +# define HASH_TABLE_SIZE 50000 +#endif + +#define msg(...) fprintf(stderr, __VA_ARGS__) +#define msgstr(x) fputs((x), stderr) + +static void write_maps (const char* list_file) { + FILE* fp = fopen (list_file, "r"); + if (fp == NULL) { + msg ("Cannot open list file %s\n", list_file); + perror ("fopen"); + exit (3); + } + + char* line = NULL; + size_t len = 0; + unsigned n; + + for (n = 0; getline (&line, &len, fp) >= 0; n++) { + strtok (line, "\n"); + + ENTRY hfind = { + .key = line, + .data = NULL + }; + ENTRY* hresult = hsearch (hfind, FIND); + if (hresult == NULL) { + msg ("Cannot find origin for %s\n", line); + exit (4); + } + + printf ("%-32s %s\n", line, hresult->data); + line = NULL; + len = 0; + } + + if (!feof (fp)) { + msgstr ("Fail to read the whole list file\n"); + perror ("getline"); + exit (6); + } + + msg ("=> %u packages entries processed\n", n); + fclose (fp); +} + +static void read_entries (const char* index_file) { + FILE* fp = fopen (index_file, "r"); + if (fp == NULL) { + msg ("Cannot open index file %s\n", index_file); + perror ("fopen"); + exit (3); + } + + char* line = NULL; + size_t len = 0; + unsigned n; + + for (n = 0; getline (&line, &len, fp) >= 0; n++) { + strtok (line, "\n"); + + char* pkgname = strtok (line, "|"); + if (pkgname == NULL) { + msgstr ("Malformed index file - no package name\n"); + exit (4); + } + + char* pkgname_end = strrchr (line, '-'); + if (pkgname_end != NULL) { + *pkgname_end = '\0'; + } + + char* fullpath = strtok (NULL, "|"); + if (fullpath == NULL) { + msgstr ("Malformed index file - no path\n"); + exit (4); + } + + bool dir_sp_got = false; + for (char* p = fullpath + strlen (fullpath); p >= fullpath; p--) { + if (*p == '/') { + if (dir_sp_got) { + fullpath = p + 1; + break; + } else { + dir_sp_got = true; + } + } + } + + ENTRY hentry = { + .key = pkgname, + .data = fullpath + }; + if (hsearch (hentry, ENTER) == NULL) { + msgstr ("The hash table is full!\n"); + exit (5); + } + + line = NULL; + len = 0; + } + + if (!feof (fp)) { + msgstr ("Fail to read the whole index file\n"); + perror ("getline"); + exit (6); + } + + msg ("=> %u ports entries read\n", n); + fclose (fp); +} + +int main (int argc, char* argv[]) { + if (argc < 3) { + msg ("Usage: %s list_file index_file\n", argv[0]); + return 1; + } + + if (!hcreate (HASH_TABLE_SIZE)) { + msg ("Cannot create a hash table with size %d\n", HASH_TABLE_SIZE); + perror ("hcreate"); + return 2; + } + + read_entries (argv[2]); + write_maps (argv[1]); + + return 0; +} diff --git a/freebsd.ports.sh b/freebsd.ports.sh index ed7b89d..1ef3dc7 100755 --- a/freebsd.ports.sh +++ b/freebsd.ports.sh @@ -4,20 +4,6 @@ msg () { echo "$@" 1>&2 } -get_origin () { - grep "^$1" "${index}" | ( - IFS="${IFS}|" - while read pkgnamever fullpath trash; do - pkgname="${pkgnamever%-*}" - if [ "${pkgname}" = "$1" ]; then - this_origin="`echo "${fullpath}" | sed 's|^.*/\(.*/.*\)$|\1|'`" - echo "${this_origin}" - break - fi - done - ) -} - [ -z "$1" ] && msg "Usage: $0 list_file" && exit 1 : ${FREEBSD_VERSION:="`uname -r | sed 's|^\([0-9]*\).*$|\1|'`"} : ${PORTSDIR:="/usr/ports"} @@ -27,18 +13,7 @@ msg "==> FreeBSD version is ${FREEBSD_VERSION}" msg "==> FreeBSD ports tree is ${PORTSDIR}" msg "==> FreeBSD ports index file is ${index}" -exec 3< "$1" # list file - -while read pkgname 0<&3; do - msg "=> Processing package ${pkgname}" - origin="`get_origin ${pkgname}`" - [ -z "${origin}" ] && \ - msg "==> Cannot find origin for ${pkgname} in your index file" && \ - msg "==> Exit now!" && exit 1 - msg "=> Processing package ${pkgname} - ${origin}" - printf "%-32s %s\n" "${pkgname}" "${origin}" -done - -exec 3<&- +msg "==> Running freebsd.ports.find" +./freebsd.ports.find "$1" "${index}" msg "==> Done!" |