mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-30 10:22:34 +01:00
* "unknow" -> "unknown" * "occured" -> "occurred" Remove some entries from PO files where these entries contain spelling errors and there are other entries that are identical except for these mistakes. Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
217 lines
8.1 KiB
Bash
Executable File
217 lines
8.1 KiB
Bash
Executable File
#!/bin/sh
|
|
###########################################################################
|
|
#
|
|
# Window Maker window manager
|
|
#
|
|
# Copyright (c) 2014 Christophe CURIS
|
|
# Copyright (c) 2014 Window Maker Team
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along
|
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
#
|
|
###########################################################################
|
|
#
|
|
# nested-func-to-macro.sh:
|
|
# from a C source file specified with "-i", convert the functions
|
|
# specified with "-f" into preprocessor macros ("#define") and save the
|
|
# result as the file specified with "-o"
|
|
#
|
|
# The goal is to process nested functions (functions defined inside other
|
|
# functions), because some compilers do not support that, despite the
|
|
# advantages against macros:
|
|
# - there is no side effect on arguments, like what macros does;
|
|
# - the compiler can check the type used for arguments;
|
|
# - the compiler can decide wether it is best to inline them or not;
|
|
# - they are better handled by text editors, mainly for indentation but
|
|
# also because there is no more '\' at end of lines;
|
|
# - generaly, error message from the compiler are a lot clearer.
|
|
#
|
|
# As opposed to simple static functions, there is a strong benefit because
|
|
# they can access the local variables of the function in which they are
|
|
# defined without needing extra arguments that may get complicated.
|
|
#
|
|
# These added values are important for developpement because they help keep
|
|
# code simple (and so maintainable and with lower bug risk).
|
|
#
|
|
# Because this script convert them to macros (only if 'configure' detected
|
|
# that the compiler does not support nested functions, see the macro
|
|
# WM_PROG_CC_NESTEDFUNC), there are a few constraints when writing such
|
|
# nested functions in the code:
|
|
#
|
|
# - you cannot use the function's address (example: callback), but that
|
|
# would be a bad idea anyway (in best case there's a penalty issue, in
|
|
# worst case it can crash the program);
|
|
#
|
|
# - you should be careful on what you're doing with the arguments of the
|
|
# function, otherwise the macro's side effects will re-appear;
|
|
#
|
|
# - you may need some extra '{}' when calling the function in an
|
|
# if/for/while/... construct, because of the difference between a function
|
|
# call and the macro that will be replaced (the macro will contain its own
|
|
# pair of '{}' which will be followed by the ';' you use for the function
|
|
# call;
|
|
#
|
|
# - the prototype of the function must be on a single line, it must not
|
|
# spread across multiple lines or replace will fail;
|
|
#
|
|
# - you should follow the project's coding style, as hacky stuff may
|
|
# make the script generate crap. And you don't want that to happen.
|
|
#
|
|
###########################################################################
|
|
#
|
|
# Please note that this script is writen in sh+awk on purpose: this script
|
|
# is gonna be run on the machine of the person who is trying to compile
|
|
# WindowMaker, and as such we cannot be sure to find any scripting language
|
|
# in a known version and that works (python/ruby/tcl/perl/php/you-name-it).
|
|
#
|
|
# So for portability, we stick to the same sh+awk constraint as Autotools
|
|
# to limit the problem, see for example:
|
|
# http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Portable-Shell.html
|
|
#
|
|
###########################################################################
|
|
|
|
# Report an error on stderr and exit with status 1 to tell make could not work
|
|
arg_error() {
|
|
echo "$0: $@" >&2
|
|
exit 1
|
|
}
|
|
|
|
# print help and exit with success status
|
|
print_help() {
|
|
echo "$0: convert nested functions into macros in C source"
|
|
echo "Usage: $0 [options...] input_file"
|
|
echo "valid options are:"
|
|
echo " -f name : add 'name' to the list of function to process"
|
|
echo " -o file : set output file"
|
|
exit 0
|
|
}
|
|
|
|
# Extract command line arguments
|
|
while [ $# -gt 0 ]; do
|
|
case $1 in
|
|
-f)
|
|
shift
|
|
echo "$1" | grep -q '^[A-Z_a-z][A-Z_a-z0-9]*$' || arg_error "function name \"$1\" is not valid"
|
|
function_list="$function_list $1"
|
|
;;
|
|
|
|
-h|-help|--help) print_help ;;
|
|
-o) shift ; output_file="$1" ;;
|
|
-*) arg_error "unknown option '$1'" ;;
|
|
|
|
*)
|
|
[ "x$input_file" = "x" ] || arg_error "only 1 input file can be specified, not \"$input_file\" and \"$1\""
|
|
input_file="$1"
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
# Check consistency of command-line
|
|
[ "x$input_file" = "x" ] && arg_error "no source file given"
|
|
[ "x$function_list" = "x" ] && arg_error "no function name were given, nothing to do"
|
|
[ "x$output_file" = "x" ] && arg_error "no output file name specified"
|
|
|
|
[ -r "$input_file" ] || arg_error "source file \"$input_file\" is not readable"
|
|
|
|
# Declare a function that takes care of converting the function code into a
|
|
# macro definition. All the code is considered part of the C function's body
|
|
# until we have matched the right number of {} pairs
|
|
awk_function_handler='
|
|
function replace_definition(func_name)
|
|
{
|
|
# Isolate the list of arguments from the rest of the line
|
|
# This code could be updated to handle arg list over multiple lines, but
|
|
# it would add unnecessary complexity because a function that big should
|
|
# probably be global static
|
|
arg_start = index($0, "(");
|
|
arg_end = index($0, ")");
|
|
argsubstr = substr($0, arg_start + 1, arg_end - arg_start - 1);
|
|
remain = substr($0, arg_end);
|
|
|
|
$0 = "#define " func_name "("
|
|
|
|
# Remove the types from the list of arguments
|
|
split(argsubstr, arglist, /,/);
|
|
separator = "";
|
|
for (i = 1; i <= length(arglist); i++) {
|
|
argname = substr(arglist[i], match(arglist[i], /[A-Z_a-z][A-Z_a-z0-9]*$/));
|
|
$0 = $0 separator argname;
|
|
separator = ", ";
|
|
}
|
|
delete arglist;
|
|
$0 = $0 remain;
|
|
|
|
# Count the number of pairs of {} and take next line until we get our matching count
|
|
is_first_line = 1;
|
|
nb_pair = 0;
|
|
while (1) {
|
|
# Count the opening braces
|
|
split($0, dummy, /\{/);
|
|
nb_pair = nb_pair + (length(dummy) - 1);
|
|
delete dummy;
|
|
|
|
# Count the closing braces
|
|
split($0, dummy, /\}/);
|
|
nb_pair = nb_pair - (length(dummy) - 1);
|
|
delete dummy;
|
|
|
|
# If we found the end of the function, stop now
|
|
if (nb_pair <= 0 && !is_first_line) {
|
|
# Note that we count on awk that is always executing the match-all
|
|
# pattern to print the current line in the $0 pattern
|
|
break;
|
|
}
|
|
|
|
# Otherwise, print current line with the macro continuation mark and grab
|
|
# next line to process it
|
|
$0 = $0 " \\";
|
|
print;
|
|
getline;
|
|
is_first_line = 0;
|
|
}
|
|
|
|
# We mark the current macro as defined so it can be undefined at the end
|
|
func_defined[func_name] = 1;
|
|
}'
|
|
|
|
# Build the list of awk pattern matching for each function:
|
|
# The regular expression matches function definition by the name of the function
|
|
# that must be preceeded by at least one keyword (likely the return type), but
|
|
# nothing like a math operator or other esoteric sign
|
|
for function in $function_list ; do
|
|
awk_function_handler="$awk_function_handler
|
|
/^[\\t ]*([A-Za-z][A-Za-z_0-9]*[\\t ])+${function}[\\t ]*\\(/ {
|
|
replace_definition(\"${function}\");
|
|
}"
|
|
done
|
|
|
|
# Finishing, undefine the macro at the most appropriate place we can easily
|
|
# guess
|
|
awk_function_handler="$awk_function_handler
|
|
/^\\}/ {
|
|
# If we are at the end of a function definition, undefine all macros that
|
|
# have been defined so far
|
|
for (func_name in func_defined) {
|
|
print \"#undef \" func_name;
|
|
delete func_defined[func_name];
|
|
}
|
|
}
|
|
# Print all other lines as-is
|
|
{ print }
|
|
"
|
|
|
|
# Find the specified functions and transform them into macros
|
|
awk "$awk_function_handler" < "$input_file" > "$output_file"
|