Move declarations to beginning of switch statements
[wmaker-crm.git] / script / replace-generated-content.sh
blob1bea00abdc5b313f2d6db1b37180e7c71e3ebecc
1 #!/bin/sh
2 ###########################################################################
4 # Window Maker window manager
6 # Copyright (c) 2021 Christophe CURIS
7 # Copyright (c) 2021 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, see <http://www.gnu.org/licenses/>.
22 ###########################################################################
24 # replace-generated-content.sh:
25 # Re-generate some list of things and replace it in an existing file
27 # The script can generate these kind of information:
29 # - a list of man pages (--man-pages), in which case the following fields
30 # are available for the template replacement:
31 # \1: file for the man page, with directories removed, with '.html' extension
32 # \2: name of the man page, taken from the file name
33 # \3: section of the page, taken from the file name
34 # \4: one line description, taken from the man page's NAME section
36 # The 'template' argument provides the template on how to generate one line
37 # with the new content, the '\n' being replaced with the values explained
38 # above.
40 # The 'marker' arguments tells the script where the content is to be placed
41 # in the edited file:
42 # - the beginning of generated content is located from the line containing
43 # the pattern 'start ' + the marker text
44 # - the end is marked by 'end ' + marker
45 # No content outside the start/end is modified. When inserting the content
46 # the script is re-using the indentation that was found in the line with the
47 # start marker.
49 ###########################################################################
51 # For portability, we stick to the same sh+awk constraint as Autotools to
52 # limit problems, see for example:
53 # http://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Portable-Shell.html
55 ###########################################################################
57 # Report an error on stderr and exit with status 2 to tell make that we could
58 # not do what we were asked
59 arg_error() {
60 echo "`basename $0`: $@" >&2
61 exit 2
64 # print help and exit with success status
65 print_help() {
66 echo "$0: replace lines by new content"
67 echo "Usage: $0 options... file"
68 echo "valid options are:"
69 echo " --template string : template text for generating the data"
70 echo " --man-pages list : content from the list of these man pages"
71 echo " --marker mark : comment mark surrounding the data to update"
72 exit 0
75 # Extract command line arguments
76 while [ $# -gt 0 ]; do
77 case $1 in
78 --man-pages)
79 shift
80 man_pages="$man_pages $1 "
83 --marker)
84 shift
85 [ "x$mark" = "x" ] || arg_error "only 1 marker can be specified (option: --marker)"
86 mark=$1
89 --template)
90 shift
91 [ "x$template" = "x" ] || arg_error "only 1 template can be specified (option: --template)"
92 template="$1"
95 -h|-help|--help) print_help ;;
96 -*) arg_error "unknow option '$1'" ;;
99 [ -z "$edit_file" ] || arg_error "only 1 file to modify can be specified"
100 edit_file=$1
102 esac
103 shift
104 done
106 # Check consistency of command-line
107 [ -z "$edit_file" ] && arg_error "no file to update was specified"
108 [ -f "$edit_file" ] || arg_error "file \"$edit_file\" cannot be read"
109 [ -z "$template" ] && arg_error "Template for generation not specified"
110 [ -z "$mark" ] && arg_error "No content mark specified"
111 [ -z "$man_pages" ] && arg_error "No input list provided"
113 # Make sure the file to edit contains the appropriate marks
114 grep "start $mark" "$edit_file" > /dev/null || arg_error "Start mark \"start $mark\" not found in \"$edit_file\" (option: --marker)"
115 grep "end $mark" "$edit_file" > /dev/null || arg_error "End mark \"end $mark\" not found in \"$edit_file\""
117 ###########################################################################
118 # Generate the content from the list of man pages provided
119 ###########################################################################
120 if [ -n "$man_pages" ]; then
121 parse_man_page() {
122 # Build the name of the HTML file from the man page name
123 target=`echo $1 | sed 's,[^/]*/,,g ; s/\.[^.]*$//' `.html
124 section=`echo $1 | sed 's/^.*\.\([^.]*\)$/\1/' `
126 # Extract the name and the description from the .SH NAME
127 sed -n '/^\.SH "*NAME"*$/ {
129 s/^\([^ ]*\) *\\- */'$target':\1:'$section':/
130 :append_next_line
132 /\n\./ b end_section_found
133 s/[ \t]*\n[ \t]*/ /
134 b append_next_line
135 :end_section_found
136 s/[ \t]*\n\..*$//
137 s/\\f[BIPR]//g
139 }' $1
142 content=`
143 for file in $man_pages ; do
144 parse_man_page $file
145 done
147 nb_fields=4
150 ###########################################################################
151 # Convert the content to the specified format
152 ###########################################################################
153 for i in `seq 2 $nb_fields`; do
154 sed_from="$sed_from\\([^:]*\\):"
155 done
156 sed_from="^$sed_from\\(.*\\)\$"
158 content=`echo "$content" | sed -e "s,$sed_from,$template," `
160 ###########################################################################
161 # Replace the content in the file
162 ###########################################################################
164 # We are working in 2 steps because we cannot edit in place
165 # In step one we remove the existing content from the file
166 purged_file=`sed -e "/start $mark/ {
168 :search_end
170 s/^.*\n//
171 /end $mark/! b search_end
172 }" "$edit_file"
175 # Convert the content to an AWK array
176 awk_start=`echo "$content" | awk '
177 BEGIN {
178 print "BEGIN {";
181 # Add a backslash before the double-quotes
182 line = "";
183 while (1) {
184 idx = index($0, "\"");
185 if (idx == 0) break;
186 line = line substr($0, 1, idx - 1) "\\\\\"";
187 $0 = substr($0, idx + 1);
189 print " content[" NR "] = \"" line $0 "\";";
191 END {
192 print " nb_content = " NR ";";
193 print "}";
197 # In step two we insert the generated content between the marks
198 awk_cmd='
199 # When the start mark is found, insert the generated content
200 /start '"$mark"'/ {
201 print;
203 # Isolate the indentation so it can be applied to all generated lines
204 sub(/[^ \t].*$/, "");
206 for (i = 1; i <= nb_content; i++) {
207 print $0 content[i];
210 # Thanks to the pre-processing done, the next line will be the end mark
211 next;
214 # All the rest of the file is kept as-is
215 { print }
218 echo "$purged_file" | awk "$awk_start$awk_cmd" > "$edit_file" || exit $?