created script to check the list of source files to handle for translation
[wmaker-crm.git] / script / check-translation-sources.sh
blob8653fe7cb5bf35201cd520218ae91fae99fe2dce
1 #!/bin/sh
2 ###########################################################################
4 # Window Maker window manager
6 # Copyright (c) 2014-2015 Christophe CURIS
7 # Copyright (c) 2015 Window Maker Team
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License along
20 # with this program; if not, write to the Free Software Foundation, Inc.,
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 ###########################################################################
25 # check-translation-sources.sh:
26 # Make sure that the list of source files given as reference in a 'po/'
27 # is aligned against the list of source files in the compilation
28 # directory;
29 # It also checks that the list of '*.po' files set in EXTRA_DIST is
30 # aligned with the list of files in the repository. This is should be
31 # checked by 'make distcheck' but today it is complicated to do that
32 # automatically, so better safe than sorry...
34 ###########################################################################
36 # For portability, we stick to the same sh+awk constraint as Autotools to
37 # limit problems, see for example:
38 # http://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Portable-Shell.html
40 ###########################################################################
42 # Report an error on stderr and exit with status 1 to tell make could not work
43 arg_error() {
44 echo "`basename $0`: $@" >&2
45 exit 1
48 # print help and exit with success status
49 print_help() {
50 echo "$0: check list of source files for translation against compiled list"
51 echo "Usage: $0 [options...] [translation_directory]"
52 echo "valid options are:"
53 echo " -s file : makefile.am for the compilation (the Source)"
54 echo " -v name : name of the variable in source makefile defining the sources"
55 echo " (the variable used in translation makefile is assumed to be 'POTFILES')"
56 exit 0
59 # Default setting
60 trans_dir="."
62 # Extract command line arguments
63 while [ $# -gt 0 ]; do
64 case $1 in
65 -s)
66 shift
67 [ -z "$src_make" ] || arg_error "only 1 Makefile can be used for source (option: -s)"
68 src_make="$1"
71 -v)
72 shift
73 echo "$1" | grep -q '^[A-Za-z][A-Z_a-z0-9]*$' || arg_error "variable name \"$1\" is not valid (option: -v)"
74 src_variables="$src_variables $1"
77 -h|-help|--help) print_help ;;
78 -*) arg_error "unknow option '$1'" ;;
81 [ "x$trans_dir" != "x" ] || arg_error "only 1 directory can be specified for translation"
82 trans_dir="$1"
84 esac
85 shift
86 done
88 # Check consistency of command-line
89 [ -z "$src_make" ] && arg_error "no makefile given for the compilation sources (option: -s)"
91 [ -r "$src_make" ] || arg_error "source makefile '$src_make' is not readable (option: -s)"
92 [ -d "$trans_dir" ] || arg_error "directory for translations is not a directory"
94 # Detect what is the Makefile to use for the translations
95 for mfile in Makefile.am Makefile.in Makefile ; do
96 if [ -r "$trans_dir/$mfile" ] ; then
97 trans_mfile="$trans_dir/$mfile"
98 break
100 done
101 [ -z "$trans_mfile" ] && arg_error "could not find a Makefile in the translation directory"
103 # Build the list of PO files that we will compare against EXTRA_DIST by the awk script
104 awk_po_file_list="`ls "$trans_dir" | grep '\.po$' | sed -e 's/^/ pofile["/ ; s/$/"] = 1;/' `"
105 [ -z "$awk_po_file_list" ] && arg_error "no \".po\" file found in translation directory, wrong path?"
107 # If the list of sources was not specified, deduce it using Automake's syntax
108 if [ -z "$src_variables" ]; then
109 src_variables="`awk '
110 /^[A-Za-z][A-Za-z_0-9]*_SOURCES[ \t]*=/ { printf " %s", $1 }
112 ' "$src_make" `"
115 # Build the list of Source files defined in the compilation makefile
116 awk_src_script='
117 function add_source_to_list()
119 # We assume the first instance is "=" and the next are "+="
120 # The script would misunderstand if the content of the variable is reset, but
121 # that would be considered bad coding style anyway
122 sub(/^[^=]*=/, "");
124 # Concatenate everything as long as there is a final back-slash on the line
125 while (sub(/\\$/, "") > 0) {
126 getline nxt;
127 $0 = $0 nxt;
130 # Generate awk command to add the file(s) to the list
131 split($0, list_src);
132 for (key in list_src) {
133 # We filter headers because it is very bad practice to include translatable strings
134 # in a header. This script does not check this validity but assumes the code is ok
135 if (list_src[key] !~ /\.h$/) {
136 print " srcfile[\"" list_src[key] "\"] = 1;";
138 delete list_src[key];
141 for variable in $src_variables ; do
142 awk_src_script="$awk_src_script
143 /^[ \t]*$variable[ \t]* \+?=/ { add_source_to_list(); }"
144 done
145 # Tell awk to not print anything other than our explicit 'print' commands
146 awk_src_script="$awk_src_script
147 { }"
149 awk_src_file_list="`awk "$awk_src_script" "$src_make" `"
151 # Generate the script that performs the check of the Makefile in the Translation directory
152 awk_trans_script='
153 function basename(filename, local_array, local_count)
155 local_count = split(filename, local_array, "/");
156 return local_array[local_count];
158 function remove_source_from_list()
160 # We make the same assumption on "=" versus "+="
161 sub(/^[^=]*=/, "");
163 # Concatenate also every line with final back-slash
164 while (sub(/\\$/, "") > 0) {
165 getline nxt;
166 $0 = $0 nxt;
169 # Remove source that are found, complain about extra files
170 split($0, list_src);
171 for (key in list_src) {
172 file = basename(list_src[key]);
174 if (srcfile[file]) {
175 delete srcfile[file];
176 } else {
177 print "Error: file \"" file "\" defined as source in Translation but is not in Compile makefile";
178 error_count++;
181 delete list_src[key];
184 function remove_dist_po_files()
186 # We make the same assumption on "=" versus "+="
187 sub(/^[^=]*=/, "");
189 # Concatenate also every line with final back-slash
190 while (sub(/\\$/, "") > 0) {
191 getline nxt;
192 $0 = $0 nxt;
195 # Remove PO files that are listed, complain about extra PO files
196 split($0, list_file);
197 for (key in list_file) {
198 if (pofile[list_file[key]]) {
199 delete pofile[list_file[key]];
200 } else if (list_file[key] ~ /\.po$/) {
201 print "Error: file \"" list_file[key] "\" defined in EXTRA_DIST but was not found in translation dir";
202 error_count++;
204 delete list_file[key];
208 awk_trans_script="$awk_trans_script
209 BEGIN {
210 error_count = 0;
211 $awk_src_file_list
212 $awk_po_file_list
214 /^[ \\t]*POTFILES[ \\t]* \\+?=/ { remove_source_from_list(); }
215 /^[ \\t]*EXTRA_DIST[ \\t]* \\+?=/ { remove_dist_po_files(); }
216 END {
217 # Make sure there is no un-translated source file
218 for (key in srcfile) {
219 print \"Error: source file \\\"\" key \"\\\" is not in the translation list\";
220 error_count++;
223 # Make sure there is no PO file left outside EXTRA_DIST
224 for (key in pofile) {
225 print \"Error: translation file \\\"\" key \"\\\" is not in EXTRA_DIST\";
226 error_count++;
229 # If error(s) occured, use non-zero status to stop 'make'
230 # We use 3 to distinguish for awk's possible own problems (status 1 or 2)
231 if (error_count > 0) { exit 3 }
234 # Run the script; we use 'exec' so we are sure the exit code seen by 'make' will
235 # come from 'awk'
236 exec awk "$awk_trans_script" "$trans_mfile"