Root/dsv/dsv

1#!/bin/sh
2#
3# dsv - Improved data sheet viewer
4#
5# Written 2010-2014, 2016, 2018 by Werner Almesberger
6# Copyright 2010-2014, 2016, 2018 Werner Almesberger
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13
14#
15# Theory of operation:
16#
17# We download data sheets from the Internet into local caches and provide a
18# quick access mechanism for viewing the data sheets. A cache is a directory
19# called .dsv/. Caches can be hierarchical. "dsv setup" generates a cache in
20# the local directory. "dsv <component>" and "dsv ls" search the hierarchy,
21# starting with the current directory.
22#
23# Caches contain two types of files: dsv-<ref> is the name or alias with
24# which a data sheet is referenced. <ref>-<filename> is the actual data
25# sheet, with <filename> being the name of the file we downloaded.
26#
27
28DSV_DIR=.dsv
29
30
31usage()
32{
33    echo "usage: $0 [-p] [-u] <component>" 1>&2
34    echo " $0 help" 1>&2
35    echo " $0 [ls]" 1>&2
36    echo " $0 [-c] setup <info-file> ..." 1>&2
37    echo 1>&2
38    echi " -c don't check server certificates" 1>&2
39    echo " -p show the path instead of displaying the file " 1>&2
40    echo " -u show source URL instead of displaying the file " 1>&2
41    exit 1
42}
43
44
45do_wget()
46{
47    wget -nv -U "dsv/1.0" $wget_opts "$@"
48}
49
50
51up()
52{
53    old=`pwd`
54    cd ..
55    new=`pwd`
56    [ "$old" != "$new" ]
57}
58
59
60flush()
61{
62    eval nm=$name
63    nm=`echo "$nm" | sed 's/%/%25/g;s|/|%2F|g'`
64    [ -z "$nm" ] && return
65    if [ -z "$url" ]; then
66        echo "$nm: no URL" 1>&2
67        exit 1
68    fi
69    ds=$nm-`basename "$url" | tr '?&' _`
70    mkdir -p $DSV_DIR
71    if [ ! -r "$DSV_DIR/$ds" ]; then
72        if [ "$zip" ]; then
73            inside=$zip
74            zip=$ds.zip
75        else
76            inside=${url#*.[Zz][Ii][Pp] }
77        fi
78        if [ "$inside" = "$url" ]; then
79            do_wget -O "$DSV_DIR/$ds" "$url"
80            # @@@ should handle error
81        else
82            if [ -z "$zip" ]; then
83                url=${url%`echo x"$inside" | sed 's/./?/g'`}
84                zip=$nm-`basename "$url"`
85            fi
86            if [ ! -r "$DSV_DIR/$zip" ]; then
87                do_wget -O "$DSV_DIR/$zip" "$url"
88                # @@@ should handle error
89            fi
90            unzip -p "$DSV_DIR/$zip" "$inside" >"$DSV_DIR/$ds" ||
91                { rm -f "$DSV_DIR/$zip" "$DSV_DIR/$ds"; exit 1; }
92        fi
93    fi
94    eval for n in $name $alias\; do \
95        'nm=`echo "$n" | sed "s/%/%25/g;s|/|%2F|g"`;' \
96        \{ echo '"$ds"'\; echo '"$url"'\; \} '>$DSV_DIR/dsv-$nm'\; \
97        done
98    name=
99    alias=
100    url=
101    zip=
102}
103
104
105set_value()
106{
107    case "$tag" in
108        N:|n:) flush
109            name="\"$value\"";;
110        A:|a:) alias="$alias \"$value\"";;
111        D:|d:) url=$value;;
112        Z:|z:) zip=$value;;
113        "") ;; # first iteration
114        *) echo "unrecognized tag \"$tag\"" 1>&2
115            exit 1;;
116    esac
117    value=
118}
119
120
121eof()
122{
123    flush
124    tag=
125}
126
127
128setup()
129{
130    for n in "$@"; do
131        if [ ! -r "$n" ]; then
132            echo "$n: not found" 1>&2
133            continue
134        fi
135        #
136        # "read" doesn't recognize lines that don't end with a newline.
137        # The cat-sed hack below works around this problems.
138        #
139        cat -E "$n" | sed 's/[^$]$/&\n/;s/$$//' | {
140            while read line; do
141                [ "$line" = "${line###}" ] || continue
142                tmp=`echo "$line" |
143                    awk '/^[^\t ]/ { print $1 }'`
144                tail=`echo "$line" |
145                    sed 's/^[^\t ]*[\t ]*//;s/[\t ]*$//'`
146                if [ -z "$tmp" ]; then
147                    [ -z "$tail" ] || value="$value $tail"
148                else
149                    set_value
150                    tag=$tmp
151                    value=$tail
152                fi
153            done
154            set_value
155            eof
156        }
157    done
158}
159
160
161list()
162{
163    while true; do
164        if [ -d $DSV_DIR ]; then
165            ls -b -1 $DSV_DIR | sed 's/^dsv-//p;d' |
166                sed 's|%2F|/|g;s/%25/%/g'
167        fi
168        up || break
169    done | sort | uniq | column
170}
171
172
173view()
174{
175    ${DSV_VIEWER:-${DSV_PDFVIEWER:-xdg-open}} "$@"
176}
177
178
179search()
180{
181    while true; do
182        if [ -d $DSV_DIR ]; then
183            name=`echo "$1" | sed 's/%/%25/g;s|/|%2F|g'`
184            if [ -r "$DSV_DIR/dsv-$name" ]; then
185                file=`sed 1q "$DSV_DIR/dsv-$name"`
186                if [ ! -r "$DSV_DIR/$file" ]; then
187                    echo "$1 -> $file: does not exist" 1>&2
188                    exit 1
189                fi
190                if $path; then
191                    echo "`pwd`/$DSV_DIR/$file"
192                elif ! $show_url; then
193                    view "$DSV_DIR/$file"
194                fi
195                if $show_url; then
196                    url=`sed 1d "$DSV_DIR/dsv-$name"`
197                    if [ "$url" ]; then
198                        echo "$url"
199                    else
200                        echo "$DSV_DIR/dsv-$name" \
201                            "does not contain a URL" \
202                            "- please regenerate" 1>&2
203                        exit 1
204                    fi
205                fi
206                exit
207            fi
208        fi
209        if ! up; then
210            echo "no data sheet found for \"$1\"" 1>&2
211            exit 1
212        fi
213    done
214}
215
216
217path=false
218show_url=false
219wget_opts=
220
221while true; do
222    case "$1" in
223        -c) wget_opts=--no-check-certificate
224            shift;;
225        -p) path=true
226            shift;;
227        -u) show_url=true
228            shift;;
229        -*) usage;;
230        *) break;;
231    esac
232done
233
234case "$1" in
235    help|-*) usage;;
236    ""|ls) list;;
237    setup) shift
238            [ "$1" ] || usage
239            setup "$@";;
240    *) search "$@";;
241esac
242

Archive Download this file

Branches:
master



interactive