[libzomg] Metadata_win32.cpp::getUserName_ansi(): Only check for NULLs if cbUsername...
[~korth/gens-gs-ii.git] / git_version.sh
1 #!/bin/sh
2 #
3 # Generate some basic versioning information which can be piped to a header.
4 #
5 # Copyright (c) 2006-2007 Luc Verhaegen <libv@skynet.be>
6 # Copyright (C) 2007-2008 Hans Ulrich Niedermann <hun@n-dimensional.de>
7 #
8 # Permission is hereby granted, free of charge, to any person obtaining a
9 # copy of this software and associated documentation files (the "Software"),
10 # to deal in the Software without restriction, including without limitation
11 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 # and/or sell copies of the Software, and to permit persons to whom the
13 # Software is furnished to do so, subject to the following conditions:
14 #
15 # The above copyright notice and this permission notice shall be included in
16 # all copies or substantial portions of the Software.
17 #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 # THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 # OTHER DEALINGS IN THE SOFTWARE.
25 #
26 # This script is based on the one written for xf86-video-unichrome by
27 # Luc Verhaegen, but was rewritten almost completely by Hans Ulrich
28 # Niedermann. The script contains a few bug fixes from Egbert Eich,
29 # Matthias Hopf, Joerg Sonnenberger, and possibly others.
30 #
31 # The author thanks the nice people on #git for the assistance.
32 #
33 # Simple testing of this script:
34 # /sbin/busybox sh git_version.sh --example > moo.c \
35 # && gcc -Wall -Wextra -Wno-unused -o moo moo.c \
36 # && ./moo
37 # (bash should also do)
38 #
39 # For how to hook this up to your automake- and/or imake-based build
40 # system, best take a look at how the RadeonHD.am and/or RadeonHD.tmpl
41 # work in the xf86-video-radeonhd build system. For non-recursive make,
42 # you can probably make things a little bit simpler.
43 #
44 # Requires git >= 1.3.0 for the 'git foo' (with space) syntax,
45 # and git >= 1.4 for some specific commands.
46
47 # Help messages
48 USAGE="[<option>...]"
49 LONG_USAGE="\
50 Options:
51 -h, --help Print this help message.
52
53 -k, --keep-if-no-repo Keep old output file if no git repo found.
54 -o, --output FILENAME Set output file name.
55 -q, --quiet Quiet output.
56 -s, --srcdir DIRNAME Set source tree dir name.
57 -x, --example Print complete example program."
58
59 # The caller may have set these for us
60 SED="${SED-sed}"
61 GIT="${GIT-git}"
62
63 # Initialize
64 working_dir=`pwd`
65
66 # Who am I?
67 self=`basename "$0"`
68
69 # Defaults
70 ifndef_symbol="GIT_VERSION_H"
71 outfile="-"
72 print_example=false
73 keep_if_no_repo=no
74 quiet=false
75 srcdir=`pwd`
76
77 # Parse command line parameter, affecting defaults
78 while [ "x$1" != "x" ]
79 do
80 case "$1" in
81 -x|--example)
82 print_example=:
83 ;;
84 -o|--output)
85 if shift; then
86 outfile="$1"
87 if [ "x$outfile" = "x-" ]; then
88 : # keep default ifndef_symbol
89 else
90 ifndef_symbol=`basename "$outfile" | $SED 's|\.|_|g; s|[^A-Za-z0-9_]||g' | tr a-z A-Z`
91 fi
92 else
93 echo "$self: Fatal: \"$1\" option requires parameter." >&2
94 exit 1
95 fi
96 ;;
97 -q|--quiet)
98 quiet=:
99 ;;
100 -h|--help)
101 echo "Usage: ${self} $USAGE"
102 [ -n "$LONG_USAGE" ] && echo "$LONG_USAGE"
103 exit
104 ;;
105 -k|--keep-if-no-repo)
106 keep_if_no_repo=yes
107 ;;
108 -s|--srcdir)
109 if shift; then
110 if test -d "$1"; then
111 srcdir="$1"
112 else
113 echo "$self: Fatal: \"$1\" not a directory." >&2
114 exit 1
115 fi
116 else
117 echo "$self: Fatal: \"$1\" option requires directory parameter." >&2
118 exit 1
119 fi
120 ;;
121 *)
122 echo "$self: Fatal: Invalid command line paramenter: \"$1\"" >&2
123 exit 1
124 ;;
125 esac
126 shift
127 done
128
129 # If not printing to stdout, redirect stdout to output file?
130 rename_new_output=false
131 if [ "x$outfile" = "x-" ]
132 then
133 : # keep using stdout
134 else
135 exec 1> "${outfile}.new"
136 fi
137
138 # Done with creating output files, so we can change to source dir
139 abs_srcdir=`cd "$srcdir" && pwd`
140 cd "$srcdir"
141
142 # Write program header
143 cat<<EOF
144 /*
145 * Basic versioning gathered from the git repository.
146 * Automatically generated by $0.
147 */
148
149 #ifndef ${ifndef_symbol}
150 #define ${ifndef_symbol} 1
151
152 /* whether this is a dist tarball or not */
153 #undef GIT_IS_DIST
154
155 EOF
156
157 # Detect git tool (should work with old and new git versions)
158 git_found=yes
159 if [ "x$GIT" = "xgit" ] && [ "x`which $GIT 2>/dev/null`" = "x" ]; then
160 git_found="'$GIT' not found"
161 break
162 fi
163 # If git_found=yes, we can now use $() substitutions (as git does). Hooray!
164
165 # Determine git specific defines
166 unset git_errors ||:
167 if [ "x$git_found" = "xyes" ]; then
168 git_version=`$GIT --version`
169 if [ "x$git_version" = "x" ]; then
170 git_errors="${git_errors+${git_errors}; }error running '$GIT --version'"
171 fi
172 fi
173
174 git_repo=no
175 # "git-rev-parse --git-dir" since git-0.99.7
176 git_repo_dir="$($GIT rev-parse --git-dir 2> /dev/null || true)"
177 abs_repo_dir="$(cd "$git_repo_dir" && pwd)"
178 # Only accept the found git repo iff it is in our top srcdir, as determined
179 # by comparing absolute pathnames created by running pwd in the respective dir.
180 if [ "x$git_repo_dir" != "x" ] && [ "x${abs_repo_dir}" = "x${abs_srcdir}/.git" ]; then
181 git_repo=yes
182 if [ "x$git_found" = "xyes" ]; then
183 # git-1.4 and probably earlier understand "git-rev-parse HEAD"
184 git_shaid=`$GIT rev-parse HEAD | $SED -n 's/^\(.\{8\}\).*/\1/p'`
185 if [ "x$git_shaid" = "x" ]; then
186 git_errors="${git_errors+${git_errors}; }error running '$GIT rev-parse HEAD'"
187 fi
188 # git-1.4 and probably earlier understand "git-symbolic-ref HEAD"
189 git_branch=`$GIT symbolic-ref HEAD | $SED -n 's|^refs/heads/||p'`
190 if [ "x$git_branch" = "x" ]; then
191 # This happens, is OK, and "(no branch)" is what "git branch" prints.
192 git_branch="(no branch)"
193 fi
194 git_dirty=yes
195 # git-1.4 does not understand "git-diff-files --quiet"
196 # git-1.4 does not understand "git-diff-index --cached --quiet HEAD"
197 if [ "x$($GIT diff-files)" = "x" ] && [ "x$($GIT diff-index --cached HEAD)" = "x" ]; then
198 git_dirty=no
199 fi
200 fi
201 fi
202
203 # Write git specific defines
204 if [ "x$git_errors" = "x" ]; then
205 echo "/* No errors occured while running git */"
206 echo "#undef GIT_ERRORS"
207 else
208 echo "/* Some errors occured while running git */"
209 echo "#define GIT_ERRORS \"${git_errors}\""
210 fi
211 echo ""
212
213 if [ "x$git_found" = "xyes" ]; then
214 echo "/* git utilities found */"
215 echo "#undef GIT_NOT_FOUND"
216 echo "#define GIT_VERSION \"${git_version}\""
217 else
218 echo "/* git utilities not found */"
219 echo "#define GIT_NOT_FOUND \"${git_found}\""
220 echo "#undef GIT_VERSION"
221 fi
222 echo ""
223
224 if :; then # debug output
225 cat<<EOF
226 /* The following helps debug why we sometimes do not find ".git/":
227 * abs_repo_dir="${abs_repo_dir}" (should be "/path/to/.git")
228 * abs_srcdir="${abs_srcdir}" (absolute top source dir "/path/to")
229 * git_repo_dir="${git_repo_dir}" (usually ".git" or "/path/to/.git")
230 * PWD="${PWD}"
231 * srcdir="${srcdir}"
232 * working_dir="${working_dir}"
233 */
234
235 EOF
236 fi
237
238 if [ "x$git_repo" = "xno" ]; then
239 echo "/* No git repo found, probably building from dist tarball */"
240 echo "#undef GIT_REPO"
241 else
242 echo "/* git repo found */"
243 echo "#define GIT_REPO 1"
244 echo ""
245 if [ "x$git_found" = "xyes" ]; then
246 echo "/* Git SHA ID of last commit */"
247 echo "#define GIT_SHAID \"${git_shaid}\""
248 echo ""
249
250 echo "/* Branch this tree is on */"
251 echo "#define GIT_BRANCH \"$git_branch\""
252 echo ""
253
254 # Any uncommitted changes we should know about?
255 # Or technically: Are the working tree or index dirty?
256 if [ "x$git_dirty" = "xno" ]; then
257 echo "/* SHA-ID uniquely defines the state of this code */"
258 echo "#undef GIT_DIRTY"
259 else
260 echo "/* Local changes might be breaking things */"
261 echo "#define GIT_DIRTY 1"
262 fi
263 fi
264 fi
265
266 # Define a few immediately useful message strings
267 cat<<EOF
268
269 /* Define GIT_MESSAGE such that
270 * printf("%s: built from %s", argv[0], GIT_MESSAGE);
271 * forms a proper sentence.
272 */
273
274 #ifdef GIT_DIRTY
275 # define GIT_DIRTY_MSG " + changes"
276 #else /* !GIT_DIRTY */
277 # define GIT_DIRTY_MSG ""
278 #endif /* GIT_DIRTY */
279
280 #ifdef GIT_ERRORS
281 # define GIT_ERROR_MSG " with error: " GIT_ERRORS
282 #else /* !GIT_ERRORS */
283 # define GIT_ERROR_MSG ""
284 #endif /* GIT_ERRORS */
285
286 #ifdef GIT_IS_DIST
287 # define GIT_DIST_MSG "dist of "
288 #else /* !GIT_IS_DIST */
289 # define GIT_DIST_MSG ""
290 #endif /* GIT_IS_DIST */
291
292 #ifdef GIT_REPO
293 # ifdef GIT_NOT_FOUND
294 # define GIT_MESSAGE GIT_DIST_MSG "git sources without git: " GIT_NOT_FOUND
295 # else /* !GIT_NOT_FOUND */
296 # define GIT_MESSAGE \\
297 GIT_DIST_MSG \\
298 "git branch " GIT_BRANCH ", " \\
299 "commit " GIT_SHAID GIT_DIRTY_MSG \\
300 GIT_ERROR_MSG
301 # endif /* GIT_NOT_FOUND */
302 #else /* !GIT_REPO */
303 # define GIT_MESSAGE GIT_DIST_MSG "non-git sources" GIT_ERROR_MSG
304 #endif /* GIT_REPO */
305
306 #endif /* ${ifndef_symbol} */
307 EOF
308
309 # Example program
310 if "$print_example"
311 then
312 cat<<EOF
313
314 /* example program demonstrating the use of git_version.sh output */
315 #include <stdio.h>
316 #include <string.h>
317
318 #ifdef HAVE_CONFIG_H
319 # include "config.h"
320 #endif
321
322 int main(int argc, char *argv[])
323 {
324 const char *const idx = strrchr(argv[0], '/');
325 const char *const prog = (idx)?(idx+1):(argv[0]);
326 #ifdef PACKAGE_VERSION
327 printf("%s: version %s, built from %s\n", prog, PACKAGE_VERSION, GIT_MESSAGE);
328 #elif defined(GIT_MESSAGE)
329 printf("%s: built from %s\n", prog, GIT_MESSAGE);
330 #endif
331 return 0;
332 }
333 EOF
334 fi
335
336 # Change back to working dir for the remaining output file manipulations.
337 cd "$working_dir"
338
339 # If necessary, overwrite outdated output file with new one
340 if [ "x$outfile" != "x-" ]
341 then
342 if [ -f "$outfile" ]; then
343 if [ "x$keep_if_no_repo" = "xyes" ] && [ "x$git_repo" = "xno" ]; then
344 "$quiet" || echo "$self: Not a git repo, keeping existing $outfile" >&2
345 rm -f "$outfile.new"
346 elif cmp "$outfile" "$outfile.new" > /dev/null; then
347 "$quiet" || echo "$self: Output is unchanged, keeping $outfile" >&2
348 rm -f "$outfile.new"
349 else
350 echo "$self: Output has changed, updating $outfile" >&2
351 mv -f "$outfile.new" "$outfile"
352 fi
353 else
354 echo "$self: Output is new file, creating $outfile" >&2
355 mv -f "$outfile.new" "$outfile"
356 fi
357 fi
358
359 # THE END.