aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTing-Wei Lan <lantw44@gmail.com>2014-02-12 23:54:22 +0800
committerTing-Wei Lan <lantw44@gmail.com>2014-02-12 23:54:22 +0800
commite1a6bb4cc192e9ae5d808b13bad4e122b759fbc1 (patch)
treef4bf5dd3cf9275d3c68c611e1b7fca5aa90c1113
parent8cc9deef211881d186a2b02c0423d2644f2c3526 (diff)
downloadwspkg-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--Makefile6
-rw-r--r--freebsd.ports.find.c139
-rwxr-xr-xfreebsd.ports.sh29
3 files changed, 145 insertions, 29 deletions
diff --git a/Makefile b/Makefile
index a6af80c..d0837c2 100644
--- a/Makefile
+++ b/Makefile
@@ -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!"