Splux Linux

source-based Linux using SPS

SPS · log · files · refs · tags · releases · people · languages · GitHub · file

lib/relations.awk


Awk

2712 bytes at 2909919 · GitHub

# Reverse dependency and path queries. These only need package names, not
# version constraint evaluation.

function rel_err(msg,    c) {
    c = "cat >&2"
    print (program == "" ? "sget" : program) ": " msg | c
    close(c)
    failed = 1
}

function rel_dep_name(spec,    p) {
    gsub(/^[ \t]+|[ \t]+$/, "", spec)
    p = match(spec, />=|<=|=|>|</)
    if (p) spec = substr(spec, 1, RSTART - 1)
    return spec
}

function rel_add_edges(pkg, list,    n, a, i, d, key) {
    if (list == "") return
    n = split(list, a, /,/)
    for (i = 1; i <= n; i++) {
        d = rel_dep_name(a[i])
        key = pkg SUBSEP d
        if (d != "" && !(key in edge)) {
            edge[key] = 1
            child_count[pkg]++
            child[pkg SUBSEP child_count[pkg]] = d
        }
    }
}

function rel_sort(a, n,    gap,i,j,x) {
    gap=int(n/2)
    while (gap>0) {
        for (i=gap+1;i<=n;i++) {
            x=a[i]; j=i
            while (j>gap && a[j-gap]>x) { a[j]=a[j-gap]; j-=gap }
            a[j]=x
        }
        gap=int(gap/2)
    }
}

function rel_find(cur, target,    i,d) {
    if (cur == target) return 1
    seen[cur]=1
    for (i = 1; i <= child_count[cur]; i++) {
        d=child[cur SUBSEP i]
        if (seen[d]) continue
        parent[d]=cur
        if (rel_find(d,target)) return 1
    }
    return 0
}

BEGIN { FS=OFS="\t" }
/^$/ { next }
{
    if (NF != 12 && NF != 13) { rel_err(FILENAME ":" FNR ": malformed index record"); next }
    name=$1; prio=$9+0
    if (!(name in selected) || prio > priority[name]) {
        selected[name]=1
        priority[name]=prio
        runtime[name]=$5
        build[name]=$6
    }
}
END {
    if (failed) exit 2
    for (pkg in selected) {
        rel_add_edges(pkg, runtime[pkg])
        if (include_build+0) rel_add_edges(pkg, build[pkg])
    }

    if (action == "dependees") {
        if (!(query in selected)) { rel_err("package '" query "' not found"); exit 3 }
        n=0
        for (k in edge) {
            split(k,p,SUBSEP)
            if (p[2] == query && !out[p[1]]++) names[++n]=p[1]
        }
        rel_sort(names,n)
        for (i=1;i<=n;i++) print names[i]
    } else if (action == "why") {
        if (!(root in selected)) { rel_err("package '" root "' not found"); exit 3 }
        if (!(query in selected)) { rel_err("package '" query "' not found"); exit 3 }
        if (!rel_find(root,query)) {
            rel_err("'" root "' does not depend on '" query "'")
            exit 5
        }
        n=0; cur=query; path[++n]=cur
        while (cur != root) { cur=parent[cur]; path[++n]=cur }
        for (i=n;i>=1;i--) print path[i]
    } else {
        rel_err("unknown relation action '" action "'")
        exit 2
    }
}