Add a user gallery to the site
[adesklets.git] / scripting / protoize.sh.in
blobc0d5a4c418e2798e4e11f04cc52f97234343714b
1 #! /bin/bash
3 # protoize.sh version @VERSION@
5 #-------------------------------------------------------------------------------
6 # Copyright (C) 2004, 2005 Sylvain Fourmanoit <syfou@users.sourceforge.net>
7 #
8 # Permission is hereby granted, free of charge, to any person obtaining a copy
9 # of this software and associated documentation files (the "Software"), to
10 # deal in the Software without restriction, including without limitation the
11 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12 # sell copies of the Software, and to permit persons to whom the Software is
13 # furnished to do so, subject to the following conditions:
15 # The above copyright notice and this permission notice shall be included in
16 # all copies of the Software and its documentation and acknowledgment shall be
17 # given in the documentation and software packages that this Software was
18 # used.
20 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 # THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24 # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 #-------------------------------------------------------------------------------
28 # Script used as a base to generate prototypes for all the commands
29 # of the @PACKAGE@ interpreter by parsing the code and looking
30 # at installed Imlib2 headers.
32 # To be precise, only the file C function adesklets_events_loop() in
33 # ../src/adesklets.c is directly parsed by this script. Some support
34 # is also requested from the script ../src/command_enum.sh, that reads
35 # the COMMANDS array from ../src/command.c. This script look for
36 # commands prototypes in form of commented declaration in each case
37 # clause of the switch(command.type) block from adesklets_events_loop().
38 # Those declarations have to be located precisely one line below each
39 # new case. They may be multi-lines, and should look like this valid example:
41 # case CMD_SOME_COMMAND:
42 # /* a pseudo prototype declaration for command 'some_command'
44 # prototype(int x,
45 # int y) */
47 # Output is a tab-separated three columns of the form:
49 # command_name help_string c_like_prototype
51 # c_like_prototypes follow these conventions:
53 # - All ansi-style C prototypes are considered valid.
54 # If you prefer, our prototypes set is a superset of all valids C prototypes
55 # - Therefore, arrays and strings should always be given as pointers
56 # (asterix notation), and not with the [] or & notations,
57 # as in plain old ansi C.
58 # - the [] notation encloses all arguments when the command can both be
59 # invoked 'as is' or with arguments, such as:
60 # prototype([int optional_1, char * optionnal_2])
61 # - All enumerated arguments such as in 'prototype(enum SOME_ENUM arg)'
62 # should be declared as 'const char * SOME_ENUM[]' in ../src/command.c,
63 # so that ./enums.sh get a chance to build appropriate enumerations.
64 # Look at this script for details.
65 # - All commands without arguments should have 'prototype(void)' as prototypes,
66 # and not prototype().
67 # - All commands having the prototype 'prototype(voidvoid)' will be
68 # silently dropped by this script, and no prototypes will be emitted.
70 # Warning: no attempt whatsoever, except for the last point of the previous
71 # list, will ever be made by ./protoize.sh to enforce the syntax above:
72 # prototypes will only get copied, regardless of their content.
73 # Nevertheless, prototypes will be expected to follow these rules
74 # to the letter by higher level scripts responsible to generate front-ends.
76 # Note: Although this script _should_ be portable across UNIXes,
77 # it has not been tested (successfully, of course) on anything but:
79 # - GNU Bourne-Again Shell (GNU bash) 3.00.0 and
80 # NetBSD Bourne Shell (ash) 1.6.0
81 # - GNU calculator language (GNU bc) 1.06
83 # Please also note it will not likely work without GNU sed
84 # (tested on GNU Streaming EDitor - GNU sed - 4.0.9 ), since
85 # it makes use of many GNU extensions (characters classes, \U, etc).
87 # This script is quite lenghty (and slow!) for the task at hand because
88 # it was written to depend only on these three programs - a low-end
89 # POSIX compliant shell (support for functions, test, but not arithmetic),
90 # any version of bc and GNU sed.
92 #-------------------------------------------------------------------------------
93 loop_feed () { sed -n '/switch(command.type)/,/default:/p' ../src/adesklets.c ;}
95 # Get all imlib2's prototypes
97 IMLIB2=`@CPP@ @IMLIB2_CFLAGS@ protoize.h 2> /dev/null`
98 if test "x$IMLIB2" = "x" ; then
99 echo "Could not retrieve imlib2 prototypes." 1>&2
100 exit 1
103 # Get all closing parentheses in imlib2's prototypes
105 IMLIB2_CLOSING=`echo "$IMLIB2" | sed -n '/)/='`
107 # Define function to find first line greater or equal with
108 # a matching closed parenthese.
109 imlib2_close_line() {
110 for LINE in $IMLIB2_CLOSING ; do
111 if test "$LINE" -ge "$1" ; then
112 echo "$LINE"
113 break
115 done
118 # Get all @PACKAGE@ commands
120 COMMANDS=`cd ../src; ./command_enum.sh --with-help 2> /dev/null`
121 if test "x$COMMANDS" = "x" ; then
122 echo "Could not retrieve @PACKAGE@ commands names." 1>&2
123 exit 1
126 # Read and process adesklets_events_loop():
127 # - get all cases lines
129 CASES=`loop_feed | sed -n '/case[[:space:]]\+CMD_/ ='`
130 if test "x$CASES" = "x" ; then
131 echo "adesklets events loop reading problem" 1>&2
132 exit 1
135 # - get all comments lines
137 COMMENTS=`loop_feed | sed -n '/\/\*/=;/\*\//='`
139 # - Prepare functions to get comments immediately below
140 # a case declaration */
142 commented_internal() {
143 if test "x$1" != "x" ; then
144 echo "${COMMENTS}" | sed -n '/^'`echo "$1 + 1" | bc`'$/=' | sed -n '1p'
148 commented() {
149 NEXT_LINE=`commented_internal $1`
150 if test "x$NEXT_LINE" != "x" ; then
151 echo "$COMMENTS" | sed -n "$NEXT_LINE"',+1p'
152 NEXT_LINE=
153 return 0;
154 else
155 return 1;
159 # - go through all cases one by one
162 for CASE in $CASES ; do
163 PROTO=
165 # Get command string for the case
167 CASE_STR=`loop_feed | sed -n "$CASE p" | \
168 sed 's/^.*case//;s/[[:space:]]//;s/:[[:space:]]*//'`
170 # First, try to get prototype from event loop
171 if commented $CASE 1> /dev/null ; then
172 SEDER=`echo \`commented $CASE\` | sed 's/ /,/;s/$/p/'`
173 PROTO=`loop_feed | sed -n "$SEDER"`
174 CASE_LINE=`echo "$PROTO" | \
175 sed -n '/[[:space:]]\+prototype[[:space:]]*(/='`
176 if test "x$CASE_LINE" != "x" ; then
177 # There is a prototype: extract it
178 SEDER="$CASE_LINE,`echo "$PROTO" | \
179 sed -n "$CASE_LINE"',$p' | sed -n '/)/='`p"
180 PROTO=`echo "$PROTO" | sed -n "$SEDER"`
181 else
182 PROTO=
186 # If it does not work, try to get it from imlib2
187 if test "x$PROTO" = "x" ; then
188 # 'imlibize' the command string it
190 IMLIB2_STR=`echo $CASE_STR | sed 's/^CMD/imlib/;s/.\+/\L&/'`
192 # try to match it against Imlib2 prototypes
194 IMLIB2_LINE=`echo "$IMLIB2" | \
195 sed -n '/[^[:alnum:]_]'"$IMLIB2_STR"'[[:space:]]*(/='`
196 if test "x$IMLIB2_LINE" != "x" ; then
197 # There is a match : Get prototype
198 SEDER="$IMLIB2_LINE,"`imlib2_close_line $IMLIB2_LINE`'p'
199 PROTO=`echo "$IMLIB2" | sed -n "$SEDER"`
203 # Finally, filter out the prototype, or print warning message
204 # if not found
205 if test "x$PROTO" != "x" ; then
206 PROTO=`echo "$PROTO" | \
207 sed 's/[^(]*(//;s/)[^)]*//;s/^[[:space:]]\+//;s/[[:space:]]\+/ /' | \
208 sed -n 'H;${G;x;s/\n//g;p}' | \
209 sed 's/Imlib[[:alnum:]_]\+/int/'`
210 COMMAND_NAME=`echo "$CASE_STR" | sed 's/CMD_//;s/.*/\L&/'`
211 COMMAND_HELP=`echo "$COMMANDS" | sed -n '/^'"$CASE_STR"'\t/ {s/^.*\t//;p}'`
212 test "x`echo "$PROTO" | sed 's/^voidvoid$//'`" != "x" && \
213 echo -e "$COMMAND_NAME\t$COMMAND_HELP\t$PROTO"
214 else
215 echo "error: there is not prototype for '$CASE_STR'" 1>&2
216 exit 1
218 done
220 exit 0