1 XCOMM!/bin/sh
2 XCOMM
3 XCOMM $TOG: mdepend.cpp /main/13 1997/06/20 21:12:18 kaleb $
4 XCOMM
5 XCOMM	Do the equivalent of the 'makedepend' program, but do it right.
6 XCOMM
7 XCOMM	Usage:
8 XCOMM
9 XCOMM	makedepend [cpp-flags] [-w width] [-s magic-string] [-f makefile]
10 XCOMM	  [-o object-suffix]
11 XCOMM
12 XCOMM	Notes:
13 XCOMM
14 XCOMM	The C compiler used can be overridden with the environment
15 XCOMM	variable "CC".
16 XCOMM
17 XCOMM	The "-v" switch of the "makedepend" program is not supported.
18 XCOMM
19 XCOMM
20 XCOMM	This script should
21 XCOMM	work on both USG and BSD systems.  However, when System V.4 comes out,
22 XCOMM	USG users will probably have to change "silent" to "-s" instead of
23 XCOMM	"-" (at least, that is what the documentation implies).
24 XCOMM
25 CC=PREPROC
26 
27 silent='-'
28 
29 TMP=/tmp/mdep$$
30 CPPCMD=${TMP}a
31 DEPENDLINES=${TMP}b
32 TMPMAKEFILE=${TMP}c
33 MAGICLINE=${TMP}d
34 ARGS=${TMP}e
35 
36 trap "rm -f ${TMP}*; exit 1" 1 2 15
37 trap "rm -f ${TMP}*; exit 0" 1 2 13
38 
39 echo " \c" > $CPPCMD
40 if [ `wc -c < $CPPCMD` -eq 1 ]
41 then
42     c="\c"
43     n=
44 else
45     c=
46     n="-n"
47 fi
48 
49 echo $n "$c" >$ARGS
50 
51 files=
52 makefile=
53 magic_string='# DO NOT DELETE'
54 objsuffix='.o'
55 width=78
56 endmarker=""
57 verbose=n
58 append=n
59 
60 while [ $# != 0 ]
61 do
62     if [ "$endmarker"x != x ] && [ "$endmarker" = "$1" ]; then
63 	endmarker=""
64     else
65 	case "$1" in
66 	    -D*|-I*)
67 		echo $n " '$1'$c" >> $ARGS
68 		;;
69 
70 	    -g|-O)	# ignore so we can just pass $(CFLAGS) in
71 		;;
72 
73 	    *)
74 		if [ "$endmarker"x = x ]; then
75 		    case "$1" in
76 			-w)
77 			    width="$2"
78 			    shift
79 			    ;;
80 			-s)
81 			    magic_string="$2"
82 			    shift
83 			    ;;
84 			-f*)
85 			    if [ "$1" = "-f-" ]; then
86 				makefile="-"
87 			    else
88 				makefile="$2"
89 				shift
90 			    fi
91 			    ;;
92 			-o)
93 			    objsuffix="$2"
94 			    shift
95 			    ;;
96 
97 			--*)
98 			    echo "$1" | sed 's/^\-\-//' >${TMP}end
99 			    endmarker="`cat ${TMP}end`"
100 			    rm -f ${TMP}end
101 			    if [ "$endmarker"x = x ]; then
102 				endmarker="--"
103 			    fi
104 			    ;;
105 			-v)
106 			    verbose="y"
107 			    ;;
108 
109 			-a)
110 			    append="y"
111 			    ;;
112 
113 			-cc)
114 			    CC="$2"
115 			    shift
116 			    ;;
117 
118 			-*)
119 			    echo "Unknown option '$1' ignored" 1>&2
120 			    ;;
121 			*)
122 			    files="$files $1"
123 			    ;;
124 		    esac
125 		fi
126 		;;
127 	esac
128     fi
129     shift
130 done
131 echo ' $*' >> $ARGS
132 
133 echo "#!/bin/sh" > $CPPCMD
134 echo "exec $CC `cat $ARGS`" >> $CPPCMD
135 chmod +x $CPPCMD
136 rm $ARGS
137 
138 case "$makefile" in
139     '')
140 	if [ -r makefile ]
141 	then
142 	    makefile=makefile
143 	elif [ -r Makefile ]
144 	then
145 	    makefile=Makefile
146 	else
147 	    echo 'no makefile or Makefile found' 1>&2
148 	    exit 1
149 	fi
150 	;;
151     -)
152 	makefile=$TMPMAKEFILE
153 	;;
154 esac
155 
156 if [ "$verbose"x = "y"x ]; then
157     cat $CPPCMD
158 fi
159 
160 echo '' > $DEPENDLINES
161 for i in $files
162 do
163     $CPPCMD $i \
164       | sed -n "/^#/s;^;$i ;p"
165 done \
166   | sed -e 's|/[^/.][^/]*/\.\.||g' -e 's|/\.[^.][^/]*/\.\.||g' \
167     -e 's|"||g' -e 's| \./| |' \
168   | awk '{
169 	if ($1 != $4  &&  $2 != "#ident" && $2 != "#pragma")
170 	    {
171 	    ofile = substr ($1, 1, length ($1) - 2) "'"$objsuffix"'"
172 	    print ofile, $4
173 	    }
174 	}' \
175   | sort -u \
176   | awk '
177 	    {
178 	    newrec = rec " " $2
179 	    if ($1 != old1)
180 		{
181 		old1 = $1
182 		if (rec != "")
183 		    print rec
184 		rec = $1 ": " $2
185 		}
186 	    else if (length (newrec) > '"$width"')
187 		{
188 		print rec
189 		rec = $1 ": " $2
190 		}
191 	    else
192 		rec = newrec
193 	    }
194 	END \
195 	    {
196 	    if (rec != "")
197 		print rec
198 	    }' \
199   | egrep -v '^[^:]*:[ 	]*$' >> $DEPENDLINES
200 
201 trap "" 1 2 13 15	# Now we are committed
202 case "$makefile" in
203     $TMPMAKEFILE)
204 	;;
205     *)
206 	rm -f $makefile.bak
207 	cp $makefile $makefile.bak
208 	echo "Appending dependencies to $makefile"
209 	;;
210 esac
211 
212 XCOMM
213 XCOMM If not -a, append the magic string and a blank line so that
214 XCOMM /^$magic_string/+1,\$d can be used to delete everything from after
215 XCOMM the magic string to the end of the file.  Then, append a blank
216 XCOMM line again and then the dependencies.
217 XCOMM
218 if [ "$append" = "n" ]
219 then
220     cat >> $makefile << END_OF_APPEND
221 
222 $magic_string
223 
224 END_OF_APPEND
225     ed $silent $makefile << END_OF_ED_SCRIPT
226 /^$magic_string/+1,\$d
227 w
228 q
229 END_OF_ED_SCRIPT
230     echo '' >>$makefile
231 fi
232 
233 cat $DEPENDLINES >>$makefile
234 
235 case "$makefile" in
236     $TMPMAKEFILE)
237 	cat $TMPMAKEFILE
238 	;;
239 
240 esac
241 
242 rm -f ${TMP}*
243 exit 0
244