summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xgeany_tagger.sh111
1 files changed, 111 insertions, 0 deletions
diff --git a/geany_tagger.sh b/geany_tagger.sh
new file mode 100755
index 0000000..abccc76
--- /dev/null
+++ b/geany_tagger.sh
@@ -0,0 +1,111 @@
1#!/bin/zsh
2#
3# Author: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
4# License: GPL v2 or later
5#
6# Create a C tags file for Geany from a C/C++ header file
7#
8
9header="$1"
10tagfile="$2"
11
12progname="$(basename $0)"
13if [[ -z $header ]] || [[ -z $tagfile ]];then
14 echo "Usage: $progname header_file tag_file"
15 exit
16elif [[ "${tagfile/.c.tags}" = "$tagfile" ]];then
17 echo "tag_file must end with .c.tags!"
18 exit
19fi
20
21stdheaders=(assert.h complex.h ctype.h errno.h fenv.h float.h inttypes.h iso646.h limits.h locale.h math.h setjmp.h signal.h stdarg.h stdbool.h stddef.h stdint.h stdio.h stdlib.h string.h time.h wchar.h wctype.h)
22
23grab_headers(){
24 echo -e "***Finding more headers from: ${new[@]}\n"
25 list=(${updates[@]})
26 updates=()
27 for h in ${list[@]};do
28 echo -e "\t***Grabbing headers from $h"
29 new=($(sed -n 's/^#include ["<]\(.*\)[">]/\1/p' "$h"|awk '{print $1}'))
30 [[ -z "${new[@]}" ]] && continue
31 #remove c99 headers
32 for x in ${stdheaders[@]};do
33 new=(${new[@]/#%$x})
34 done
35 [[ -z "${new[@]}" ]] && continue
36 echo -e "\t***Pruning pre-existing headers from new list [1/2]..."
37 for x in ${headers[@]};do
38# echo $x
39 new=(${new[@]/#%$x})
40 done
41 [[ -z "${new[@]}" ]] && continue
42 echo -e "\t***Pruning pre-existing headers from new list [2/2]..."
43 for x in ${new[@]};do
44# echo $x
45 if (echo "${headers[@]}"|grep -q $x) ; then
46 new=(${new[@]/#%$x})
47 fi
48 done
49 [[ -z "${new[@]}" ]] && continue
50 #remove duplicates
51 echo -e "\t***Removing duplicates from new list..."
52 new=($(printf "%s\n" ${new[@]}|sort -u))
53 [[ -z "${new[@]}" ]] && continue
54 echo -e "\t***Mapping the following headers to absolute paths: ${new[@]}\n"
55 for x in ${new[@]};do
56 #if already mapped, ignore
57 [[ -f $x ]] && continue
58
59 if [[ "$(dirname $h)" != "/usr/include" ]] && ! echo $x | grep -q '^/' ; then
60 if echo $x|grep -q /; then
61 y=$(find "$(dirname $h)" -path "$x" |head -n1)
62 else
63 y=$(find "$(dirname $h)" -name "$x" |head -n1)
64 fi
65 fi
66
67 #try looking only in /usr/include after
68 [[ -n "$y" && -f "$y" ]] || y=$(find /usr/include -mindepth 1 -path "*/$x"|head -n1)
69 #replace with absolute path
70 [[ -n "$y" && -f "$y" ]] && new=(${new[@]/#%$x/$y})
71 done
72 for x in ${new[@]};do
73 [[ -f $x ]] && continue
74 t=$(find /usr/include -mindepth 1 -path "*/$x"|head -n1)
75 [[ -n "$t" && -f "$t" ]] && new=(${new[@]/#%$x/$t})
76 done
77 echo -e "\t***Added ${new[@]}"
78 updates+=(${new[@]})
79 done
80 updates=($(printf "%s\n" ${updates[@]}|sort -u))
81 headers+=(${updates[@]})
82}
83
84#grab initial headers to include
85if [[ ! -f $(readlink -f $header) ]];then
86 echo "ERROR: $progname requires the header to be passed with its absolute path"
87 exit 1
88fi
89updates=($header)
90headers=(${new[@]})
91#run at least twice
92grab_headers
93grab_headers
94#run while grabbing is still possible
95prev_headers=()
96while [[ -n "${updates[@]}" ]];do
97 grab_headers
98done
99echo -e "\t***Removing nonexistent filenames..."
100for x in ${headers[@]};do
101 [[ -f $x ]] && continue
102 echo -e "\t\tRemoved $x"
103 headers=(${headers[@]/#%$x})
104done
105headers=($(printf "%s\n" ${headers[@]}|sort -u))
106echo -e "***Generating tags for the following headers: ${headers[@]}\n"
107geany -P -g "$tagfile" ${headers[@]}
108
109#remove static variables
110sed -i '/^_/d' "$tagfile"
111