]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ncurses/ncurses/base/MKlib_gen.sh
This commit was generated by cvs2svn to compensate for changes in r161651,
[FreeBSD/FreeBSD.git] / contrib / ncurses / ncurses / base / MKlib_gen.sh
1 #!/bin/sh
2 #
3 # MKlib_gen.sh -- generate sources from curses.h macro definitions
4 #
5 # ($Id: MKlib_gen.sh,v 1.18 2002/04/30 00:37:55 tom Exp $)
6 #
7 ##############################################################################
8 # Copyright (c) 1998-2001,2002 Free Software Foundation, Inc.                #
9 #                                                                            #
10 # Permission is hereby granted, free of charge, to any person obtaining a    #
11 # copy of this software and associated documentation files (the "Software"), #
12 # to deal in the Software without restriction, including without limitation  #
13 # the rights to use, copy, modify, merge, publish, distribute, distribute    #
14 # with modifications, sublicense, and/or sell copies of the Software, and to #
15 # permit persons to whom the Software is furnished to do so, subject to the  #
16 # following conditions:                                                      #
17 #                                                                            #
18 # The above copyright notice and this permission notice shall be included in #
19 # all copies or substantial portions of the Software.                        #
20 #                                                                            #
21 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
22 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
23 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
24 # THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
25 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
26 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
27 # DEALINGS IN THE SOFTWARE.                                                  #
28 #                                                                            #
29 # Except as contained in this notice, the name(s) of the above copyright     #
30 # holders shall not be used in advertising or otherwise to promote the sale, #
31 # use or other dealings in this Software without prior written               #
32 # authorization.                                                             #
33 ##############################################################################
34 #
35 # The XSI Curses standard requires all curses entry points to exist as
36 # functions, even though many definitions would normally be shadowed
37 # by macros.  Rather than hand-hack all that code, we actually
38 # generate functions from the macros.
39 #
40 # This script accepts a file of prototypes on standard input.  It discards
41 # any that don't have a `generated' comment attached. It then parses each
42 # prototype (relying on the fact that none of the macros take function 
43 # pointer or array arguments) and generates C source from it.
44 #
45 # Here is what the pipeline stages are doing:
46 #
47 # 1. sed: extract prototypes of generated functions
48 # 2. sed: decorate prototypes with generated arguments a1. a2,...z
49 # 3. awk: generate the calls with args matching the formals 
50 # 4. sed: prefix function names in prototypes so the preprocessor won't expand
51 #         them.
52 # 5. cpp: macro-expand the file so the macro calls turn into C calls
53 # 6. awk: strip the expansion junk off the front and add the new header
54 # 7. sed: squeeze spaces, strip off gen_ prefix, create needed #undef
55 #
56
57 preprocessor="$1 -I../include"
58 AWK="$2"
59 USE="$3"
60
61 PID=$$
62 ED1=sed1_${PID}.sed
63 ED2=sed2_${PID}.sed
64 ED3=sed3_${PID}.sed
65 ED4=sed4_${PID}.sed
66 AW1=awk1_${PID}.awk
67 AW2=awk2_${PID}.awk
68 TMP=gen__${PID}.c
69 trap "rm -f $ED1 $ED2 $ED3 $ED4 $AW1 $AW2 $TMP" 0 1 2 5 15
70
71 ALL=$USE
72 if test "$USE" = implemented ; then
73         CALL="call_"
74         cat >$ED1 <<EOF1
75 /^extern.*implemented/{
76         h
77         s/^.*implemented:\([^   *]*\).*/P_#if_USE_\1_SUPPORT/p
78         g
79         s/^extern \([^;]*\);.*/\1/p
80         g
81         s/^.*implemented:\([^   *]*\).*/P_#endif/p
82 }
83 /^extern.*generated/{
84         h
85         s/^.*generated:\([^     *]*\).*/P_#if_USE_\1_SUPPORT/p
86         g
87         s/^extern \([^;]*\);.*/\1/p
88         g
89         s/^.*generated:\([^     *]*\).*/P_#endif/p
90 }
91 EOF1
92 else
93         CALL=""
94         cat >$ED1 <<EOF1
95 /^extern.*${ALL}/{
96         h
97         s/^.*${ALL}:\([^        *]*\).*/P_#if_USE_\1_SUPPORT/p
98         g
99         s/^extern \([^;]*\);.*/\1/p
100         g
101         s/^.*${ALL}:\([^        *]*\).*/P_#endif/p
102 }
103 EOF1
104 fi
105
106 cat >$ED2 <<EOF2
107 /^P_/b nc
108 /(void)/b nc
109         s/,/ a1% /
110         s/,/ a2% /
111         s/,/ a3% /
112         s/,/ a4% /
113         s/,/ a5% /
114         s/,/ a6% /
115         s/,/ a7% /
116         s/,/ a8% /
117         s/,/ a9% /
118         s/,/ a10% /
119         s/,/ a11% /
120         s/,/ a12% /
121         s/,/ a13% /
122         s/,/ a14% /
123         s/,/ a15% /
124         s/*/ * /g
125         s/%/ , /g
126         s/)/ z)/
127         s/\.\.\. z)/...)/
128 :nc
129         /(/s// ( /
130         s/)/ )/
131 EOF2
132
133 cat >$ED3 <<EOF3
134 /^P_/{
135         s/^P_#if_/#if /
136         s/^P_//
137         b done
138 }
139         s/              */ /g
140         s/  */ /g
141         s/ ,/,/g
142         s/( /(/g
143         s/ )/)/g
144         s/ gen_/ /
145         s/^M_/#undef /
146         /^%%/s//        /
147 :done
148 EOF3
149
150 if test "$USE" = generated ; then
151 cat >$ED4 <<EOF
152         s/^\(.*\) \(.*\) (\(.*\))\$/NCURSES_EXPORT(\1) \2 (\3)/
153 EOF
154 else
155 cat >$ED4 <<EOF
156 /^\(.*\) \(.*\) (\(.*\))\$/ {
157         h
158         s/^\(.*\) \(.*\) (\(.*\))\$/extern \1 call_\2 (\3);/
159         p
160         g
161         s/^\(.*\) \(.*\) (\(.*\))\$/\1 call_\2 (\3)/
162         }
163 EOF
164 fi
165
166 cat >$AW1 <<\EOF1
167 BEGIN   {
168                 skip=0;
169         }
170 /^P_#if/ {
171                 print "\n"
172                 print $0
173                 skip=0;
174 }
175 /^P_#endif/ {
176                 print $0
177                 skip=1;
178 }
179 $0 !~ /^P_/ {
180         if (skip)
181                 print "\n"
182         skip=1;
183
184         first=$1
185         for (i = 1; i <= NF; i++) {
186                 if ( $i != "NCURSES_CONST" ) {
187                         first = i;
188                         break;
189                 }
190         }
191         second = first + 1;
192         if ( $first == "chtype" ) {
193                 returnType = "Char";
194         } else if ( $first == "SCREEN" ) {
195                 returnType = "SP";
196         } else if ( $first == "WINDOW" ) {
197                 returnType = "Win";
198         } else if ( $second == "*" ) {
199                 returnType = "Ptr";
200         } else {
201                 returnType = "Code";
202         }
203         myfunc = second;
204         for (i = second; i <= NF; i++) {
205                 if ($i != "*") {
206                         myfunc = i;
207                         break;
208                 }
209         }
210         if (using == "generated") {
211                 print "M_" $myfunc
212         }
213         print $0;
214         print "{";
215         argcount = 1;
216         check = NF - 1;
217         if ($check == "void")
218                 argcount = 0;
219         if (argcount != 0) {
220                 for (i = 1; i <= NF; i++)
221                         if ($i == ",")
222                                 argcount++;
223         }
224
225         # suppress trace-code for functions that we cannot do properly here,
226         # since they return data.
227         dotrace = 1;
228         if ($myfunc ~ /innstr/)
229                 dotrace = 0;
230         if ($myfunc ~ /innwstr/)
231                 dotrace = 0;
232
233         # workaround functions that we do not parse properly
234         if ($myfunc ~ /ripoffline/) {
235                 dotrace = 0;
236                 argcount = 2;
237         }
238         if ($myfunc ~ /wunctrl/) {
239                 dotrace = 0;
240         }
241
242         call = "%%T((T_CALLED(\""
243         args = ""
244         comma = ""
245         num = 0;
246         pointer = 0;
247         argtype = ""
248         for (i = myfunc; i <= NF; i++) {
249                 ch = $i;
250                 if ( ch == "*" )
251                         pointer = 1;
252                 else if ( ch == "va_list" )
253                         pointer = 1;
254                 else if ( ch == "char" )
255                         argtype = "char";
256                 else if ( ch == "int" )
257                         argtype = "int";
258                 else if ( ch == "short" )
259                         argtype = "short";
260                 else if ( ch == "chtype" )
261                         argtype = "chtype";
262                 else if ( ch == "attr_t" || ch == "NCURSES_ATTR_T" )
263                         argtype = "attr";
264
265                 if ( ch == "," || ch == ")" ) {
266                         if (pointer) {
267                                 if ( argtype == "char" ) {
268                                         call = call "%s"
269                                         comma = comma "_nc_visbuf2(" num ","
270                                         pointer = 0;
271                                 } else
272                                         call = call "%p"
273                         } else if (argcount != 0) {
274                                 if ( argtype == "int" || argtype == "short" ) {
275                                         call = call "%d"
276                                         argtype = ""
277                                 } else if ( argtype != "" ) {
278                                         call = call "%s"
279                                         comma = comma "_trace" argtype "2(" num ","
280                                 } else {
281                                         call = call "%#lx"
282                                         comma = comma "(long)"
283                                 }
284                         }
285                         if (ch == ",")
286                                 args = args comma "a" ++num;
287                         else if ( argcount != 0 && $check != "..." )
288                                 args = args comma "z"
289                         call = call ch
290                         if (pointer == 0 && argcount != 0 && argtype != "" )
291                                 args = args ")"
292                         if (args != "")
293                                 comma = ", "
294                         pointer = 0;
295                         argtype = ""
296                 }
297                 if ( i == 2 || ch == "(" )
298                         call = call ch
299         }
300         call = call "\")"
301         if (args != "")
302                 call = call ", " args
303         call = call ")); "
304
305         if (dotrace)
306                 printf "%s", call
307
308         if (match($0, "^void"))
309                 call = ""
310         else if (dotrace)
311                 call = sprintf("return%s( ", returnType);
312         else
313                 call = "%%return ";
314
315         call = call $myfunc "(";
316         for (i = 1; i < argcount; i++) {
317                 if (i != 1)
318                         call = call ", ";
319                 call = call "a" i;
320         }
321         if ( argcount != 0 && $check != "..." ) {
322                 if (argcount != 1)
323                         call = call ", ";
324                 call = call "z";
325         }
326         if (!match($0, "^void"))
327                 call = call ") ";
328         if (dotrace)
329                 call = call ")";
330         print call ";"
331
332         if (match($0, "^void"))
333                 print "%%returnVoid;"
334         print "}";
335 }
336 EOF1
337
338 cat >$AW2 <<EOF1
339 BEGIN           {
340                 print "/*"
341                 print " * DO NOT EDIT THIS FILE BY HAND!"
342                 printf " * It is generated by $0 %s.\n", "$USE"
343                 if ( "$USE" == "generated" ) {
344                         print " *"
345                         print " * This is a file of trivial functions generated from macro"
346                         print " * definitions in curses.h to satisfy the XSI Curses requirement"
347                         print " * that every macro also exist as a callable function."
348                         print " *"
349                         print " * It will never be linked unless you call one of the entry"
350                         print " * points with its normal macro definition disabled.  In that"
351                         print " * case, if you have no shared libraries, it will indirectly"
352                         print " * pull most of the rest of the library into your link image."
353                 }
354                 print " */"
355                 print "#include <curses.priv.h>"
356                 print ""
357                 }
358 /^DECLARATIONS/ {start = 1; next;}
359                 {if (start) print \$0;}
360 END             {
361                 if ( "$USE" != "generated" ) {
362                         print "int main(void) { return 0; }"
363                 }
364                 }
365 EOF1
366
367 cat >$TMP <<EOF
368 #include <ncurses_cfg.h>
369 #include <curses.h>
370
371 DECLARATIONS
372
373 EOF
374
375 sed -n -f $ED1 \
376 | sed -e 's/NCURSES_EXPORT(\(.*\)) \(.*\) (\(.*\))/\1 \2(\3)/' \
377 | sed -f $ED2 \
378 | $AWK -f $AW1 using=$USE \
379 | sed -e 's/^\([a-z_][a-z_]*[ *]*\)/\1 gen_/' -e 's/  / /g' >>$TMP
380
381 $preprocessor $TMP 2>/dev/null \
382 | sed -e 's/  / /g' -e 's/^ //' \
383 | $AWK -f $AW2 \
384 | sed -f $ED3 \
385 | sed \
386         -e 's/^.*T_CALLED.*returnCode( \([a-z].*) \));/ return \1;/' \
387         -e 's/^.*T_CALLED.*returnCode( \((wmove.*) \));/        return \1;/' \
388 | sed -f $ED4