Deleted Added
full compact
MKlib_gen.sh (66963) MKlib_gen.sh (76726)
1#!/bin/sh
2#
3# MKlib_gen.sh -- generate sources from curses.h macro definitions
4#
1#!/bin/sh
2#
3# MKlib_gen.sh -- generate sources from curses.h macro definitions
4#
5# ($Id: MKlib_gen.sh,v 1.12 2000/07/29 16:30:11 tom Exp $)
5# ($Id: MKlib_gen.sh,v 1.13 2000/12/10 00:30:25 tom Exp $)
6#
7# The XSI Curses standard requires all curses entry points to exist as
8# functions, even though many definitions would normally be shadowed
9# by macros. Rather than hand-hack all that code, we actually
10# generate functions from the macros.
11#
12# This script accepts a file of prototypes on standard input. It discards
13# any that don't have a `generated' comment attached. It then parses each
14# prototype (relying on the fact that none of the macros take function
15# pointer or array arguments) and generates C source from it.
16#
17# Here is what the pipeline stages are doing:
18#
19# 1. sed: extract prototypes of generated functions
20# 2. sed: decorate prototypes with generated arguments a1. a2,...z
21# 3. awk: generate the calls with args matching the formals
22# 4. sed: prefix function names in prototypes so the preprocessor won't expand
23# them.
24# 5. cpp: macro-expand the file so the macro calls turn into C calls
25# 6. awk: strip the expansion junk off the front and add the new header
26# 7. sed: squeeze spaces, strip off gen_ prefix, create needed #undef
27#
28
29preprocessor="$1 -I../include"
30AWK="$2"
31ED1=sed1$$.sed
32ED2=sed2$$.sed
33ED3=sed3$$.sed
34AW1=awk1$$.awk
35TMP=gen$$.c
36trap "rm -f $ED1 $ED2 $ED3 $AW1 $TMP" 0 1 2 5 15
37
38(cat <<EOF
39#include <ncurses_cfg.h>
40#include <curses.h>
41
42DECLARATIONS
43
44EOF
45cat >$ED1 <<EOF1
46/^extern.*generated/{
47 h
48 s/^.*generated:\([^ *]*\).*/P_#if_USE_\1_SUPPORT/p
49 g
50 s/^extern \([^;]*\);.*/\1/p
51 g
52 s/^.*generated:\([^ *]*\).*/P_#endif/p
53}
54EOF1
55
56cat >$ED2 <<EOF2
57/^P_/b nc
58/(void)/b nc
59 s/,/ a1% /
60 s/,/ a2% /
61 s/,/ a3% /
62 s/,/ a4% /
63 s/,/ a5% /
64 s/,/ a6% /
65 s/,/ a7% /
66 s/,/ a8% /
67 s/,/ a9% /
68 s/,/ a10% /
69 s/,/ a11% /
70 s/,/ a12% /
71 s/,/ a13% /
72 s/,/ a14% /
73 s/,/ a15% /
74 s/*/ * /g
75 s/%/ , /g
76 s/)/ z)/
77:nc
78 /(/s// ( /
79 s/)/ )/
80EOF2
81
82cat >$ED3 <<EOF3
83/^P_/{
84 s/^P_#if_/#if /
85 s/^P_//
86 b done
87}
88 s/ */ /g
89 s/ */ /g
90 s/ ,/,/g
91 s/ )/)/g
92 s/ gen_/ /
93 s/^M_/#undef /
94 /^%%/s// /
95:done
96EOF3
97
98cat >$AW1 <<\EOF1
99BEGIN {
100 skip=0;
101 }
102 /^P_#if/ {
103 print "\n"
104 print $0
105 skip=0;
106 }
107 /^P_#endif/ {
108 print $0
109 skip=1;
110 }
111 $0 !~ /^P_/ {
112 if (skip)
113 print "\n"
114 skip=1;
115
116 if ( $1 == "chtype" ) {
117 returnType = "Char";
118 } else {
119 returnType = "Code";
120 }
121 print "M_" $2
122 print $0;
123 print "{";
124 argcount = 1;
125 if (NF == 5 && $4 == "void")
126 argcount = 0;
127 if (argcount != 0) {
128 for (i = 1; i <= NF; i++)
129 if ($i == ",")
130 argcount++;
131 }
132
133 # suppress trace-code for functions that we cannot do properly here,
134 # since they return data.
135 dotrace = 1;
136 if ($2 == "innstr")
137 dotrace = 0;
138
139 call = "%%T((T_CALLED(\""
140 args = ""
141 comma = ""
142 num = 0;
143 pointer = 0;
144 argtype = ""
145 for (i = 1; i <= NF; i++) {
146 ch = $i;
147 if ( ch == "*" )
148 pointer = 1;
149 else if ( ch == "va_list" )
150 pointer = 1;
151 else if ( ch == "char" )
152 argtype = "char";
153 else if ( ch == "int" )
154 argtype = "int";
155 else if ( ch == "short" )
156 argtype = "short";
157 else if ( ch == "chtype" )
158 argtype = "chtype";
159 else if ( ch == "attr_t" || ch == "NCURSES_ATTR_T" )
160 argtype = "attr";
161
162 if ( ch == "," || ch == ")" ) {
163 if (pointer) {
164 if ( argtype == "char" ) {
165 call = call "%s"
166 comma = comma "_nc_visbuf2(" num ","
167 pointer = 0;
168 } else
169 call = call "%p"
170 } else if (argcount != 0) {
171 if ( argtype == "int" || argtype == "short" ) {
172 call = call "%d"
173 argtype = ""
174 } else if ( argtype != "" ) {
175 call = call "%s"
176 comma = comma "_trace" argtype "2(" num ","
177 } else {
178 call = call "%#lx"
179 comma = comma "(long)"
180 }
181 }
182 if (ch == ",")
183 args = args comma "a" ++num;
184 else if (argcount != 0)
185 args = args comma "z"
186 call = call ch
187 if (pointer == 0 && argcount != 0 && argtype != "" )
188 args = args ")"
189 if (args != "")
190 comma = ", "
191 pointer = 0;
192 argtype = ""
193 }
194 if ( i == 2 || ch == "(" )
195 call = call ch
196 }
197 call = call "\")"
198 if (args != "")
199 call = call ", " args
200 call = call ")); "
201
202 if (dotrace)
203 printf "%s", call
204
205 if (match($0, "^void"))
206 call = ""
207 else if (dotrace)
208 call = sprintf("return%s( ", returnType);
209 else
210 call = "%%return ";
211
212 call = call $2 "(";
213 for (i = 1; i < argcount; i++)
214 call = call "a" i ", ";
215 if (argcount != 0)
216 call = call "z";
217 if (!match($0, "^void"))
218 call = call ") ";
219 if (dotrace)
220 call = call ")";
221 print call ";"
222
223 if (match($0, "^void"))
224 print "%%returnVoid;"
225 print "}";
226}
227EOF1
228
6#
7# The XSI Curses standard requires all curses entry points to exist as
8# functions, even though many definitions would normally be shadowed
9# by macros. Rather than hand-hack all that code, we actually
10# generate functions from the macros.
11#
12# This script accepts a file of prototypes on standard input. It discards
13# any that don't have a `generated' comment attached. It then parses each
14# prototype (relying on the fact that none of the macros take function
15# pointer or array arguments) and generates C source from it.
16#
17# Here is what the pipeline stages are doing:
18#
19# 1. sed: extract prototypes of generated functions
20# 2. sed: decorate prototypes with generated arguments a1. a2,...z
21# 3. awk: generate the calls with args matching the formals
22# 4. sed: prefix function names in prototypes so the preprocessor won't expand
23# them.
24# 5. cpp: macro-expand the file so the macro calls turn into C calls
25# 6. awk: strip the expansion junk off the front and add the new header
26# 7. sed: squeeze spaces, strip off gen_ prefix, create needed #undef
27#
28
29preprocessor="$1 -I../include"
30AWK="$2"
31ED1=sed1$$.sed
32ED2=sed2$$.sed
33ED3=sed3$$.sed
34AW1=awk1$$.awk
35TMP=gen$$.c
36trap "rm -f $ED1 $ED2 $ED3 $AW1 $TMP" 0 1 2 5 15
37
38(cat <<EOF
39#include <ncurses_cfg.h>
40#include <curses.h>
41
42DECLARATIONS
43
44EOF
45cat >$ED1 <<EOF1
46/^extern.*generated/{
47 h
48 s/^.*generated:\([^ *]*\).*/P_#if_USE_\1_SUPPORT/p
49 g
50 s/^extern \([^;]*\);.*/\1/p
51 g
52 s/^.*generated:\([^ *]*\).*/P_#endif/p
53}
54EOF1
55
56cat >$ED2 <<EOF2
57/^P_/b nc
58/(void)/b nc
59 s/,/ a1% /
60 s/,/ a2% /
61 s/,/ a3% /
62 s/,/ a4% /
63 s/,/ a5% /
64 s/,/ a6% /
65 s/,/ a7% /
66 s/,/ a8% /
67 s/,/ a9% /
68 s/,/ a10% /
69 s/,/ a11% /
70 s/,/ a12% /
71 s/,/ a13% /
72 s/,/ a14% /
73 s/,/ a15% /
74 s/*/ * /g
75 s/%/ , /g
76 s/)/ z)/
77:nc
78 /(/s// ( /
79 s/)/ )/
80EOF2
81
82cat >$ED3 <<EOF3
83/^P_/{
84 s/^P_#if_/#if /
85 s/^P_//
86 b done
87}
88 s/ */ /g
89 s/ */ /g
90 s/ ,/,/g
91 s/ )/)/g
92 s/ gen_/ /
93 s/^M_/#undef /
94 /^%%/s// /
95:done
96EOF3
97
98cat >$AW1 <<\EOF1
99BEGIN {
100 skip=0;
101 }
102 /^P_#if/ {
103 print "\n"
104 print $0
105 skip=0;
106 }
107 /^P_#endif/ {
108 print $0
109 skip=1;
110 }
111 $0 !~ /^P_/ {
112 if (skip)
113 print "\n"
114 skip=1;
115
116 if ( $1 == "chtype" ) {
117 returnType = "Char";
118 } else {
119 returnType = "Code";
120 }
121 print "M_" $2
122 print $0;
123 print "{";
124 argcount = 1;
125 if (NF == 5 && $4 == "void")
126 argcount = 0;
127 if (argcount != 0) {
128 for (i = 1; i <= NF; i++)
129 if ($i == ",")
130 argcount++;
131 }
132
133 # suppress trace-code for functions that we cannot do properly here,
134 # since they return data.
135 dotrace = 1;
136 if ($2 == "innstr")
137 dotrace = 0;
138
139 call = "%%T((T_CALLED(\""
140 args = ""
141 comma = ""
142 num = 0;
143 pointer = 0;
144 argtype = ""
145 for (i = 1; i <= NF; i++) {
146 ch = $i;
147 if ( ch == "*" )
148 pointer = 1;
149 else if ( ch == "va_list" )
150 pointer = 1;
151 else if ( ch == "char" )
152 argtype = "char";
153 else if ( ch == "int" )
154 argtype = "int";
155 else if ( ch == "short" )
156 argtype = "short";
157 else if ( ch == "chtype" )
158 argtype = "chtype";
159 else if ( ch == "attr_t" || ch == "NCURSES_ATTR_T" )
160 argtype = "attr";
161
162 if ( ch == "," || ch == ")" ) {
163 if (pointer) {
164 if ( argtype == "char" ) {
165 call = call "%s"
166 comma = comma "_nc_visbuf2(" num ","
167 pointer = 0;
168 } else
169 call = call "%p"
170 } else if (argcount != 0) {
171 if ( argtype == "int" || argtype == "short" ) {
172 call = call "%d"
173 argtype = ""
174 } else if ( argtype != "" ) {
175 call = call "%s"
176 comma = comma "_trace" argtype "2(" num ","
177 } else {
178 call = call "%#lx"
179 comma = comma "(long)"
180 }
181 }
182 if (ch == ",")
183 args = args comma "a" ++num;
184 else if (argcount != 0)
185 args = args comma "z"
186 call = call ch
187 if (pointer == 0 && argcount != 0 && argtype != "" )
188 args = args ")"
189 if (args != "")
190 comma = ", "
191 pointer = 0;
192 argtype = ""
193 }
194 if ( i == 2 || ch == "(" )
195 call = call ch
196 }
197 call = call "\")"
198 if (args != "")
199 call = call ", " args
200 call = call ")); "
201
202 if (dotrace)
203 printf "%s", call
204
205 if (match($0, "^void"))
206 call = ""
207 else if (dotrace)
208 call = sprintf("return%s( ", returnType);
209 else
210 call = "%%return ";
211
212 call = call $2 "(";
213 for (i = 1; i < argcount; i++)
214 call = call "a" i ", ";
215 if (argcount != 0)
216 call = call "z";
217 if (!match($0, "^void"))
218 call = call ") ";
219 if (dotrace)
220 call = call ")";
221 print call ";"
222
223 if (match($0, "^void"))
224 print "%%returnVoid;"
225 print "}";
226}
227EOF1
228
229sed -n -f $ED1 | sed -f $ED2 \
229sed -n -f $ED1 \
230| sed -e 's/NCURSES_EXPORT(\(.*\)) \(.*\) (\(.*\))/\1 \2(\3)/' \
231| sed -f $ED2 \
230| $AWK -f $AW1 ) \
231| sed \
232 -e '/^\([a-z_][a-z_]*\) /s//\1 gen_/' >$TMP
233 $preprocessor $TMP 2>/dev/null \
234| $AWK '
235BEGIN {
236 print "/*"
237 print " * DO NOT EDIT THIS FILE BY HAND!"
238 print " * It is generated by MKlib_gen.sh."
239 print " *"
240 print " * This is a file of trivial functions generated from macro"
241 print " * definitions in curses.h to satisfy the XSI Curses requirement"
242 print " * that every macro also exist as a callable function."
243 print " *"
244 print " * It will never be linked unless you call one of the entry"
245 print " * points with its normal macro definition disabled. In that"
246 print " * case, if you have no shared libraries, it will indirectly"
247 print " * pull most of the rest of the library into your link image."
248 print " */"
249 print "#include <curses.priv.h>"
250 print ""
251 }
252/^DECLARATIONS/ {start = 1; next;}
253 {if (start) print $0;}
254' \
255| sed -f $ED3 \
256| sed \
257 -e 's/^.*T_CALLED.*returnCode( \([a-z].*) \));/ return \1;/' \
232| $AWK -f $AW1 ) \
233| sed \
234 -e '/^\([a-z_][a-z_]*\) /s//\1 gen_/' >$TMP
235 $preprocessor $TMP 2>/dev/null \
236| $AWK '
237BEGIN {
238 print "/*"
239 print " * DO NOT EDIT THIS FILE BY HAND!"
240 print " * It is generated by MKlib_gen.sh."
241 print " *"
242 print " * This is a file of trivial functions generated from macro"
243 print " * definitions in curses.h to satisfy the XSI Curses requirement"
244 print " * that every macro also exist as a callable function."
245 print " *"
246 print " * It will never be linked unless you call one of the entry"
247 print " * points with its normal macro definition disabled. In that"
248 print " * case, if you have no shared libraries, it will indirectly"
249 print " * pull most of the rest of the library into your link image."
250 print " */"
251 print "#include <curses.priv.h>"
252 print ""
253 }
254/^DECLARATIONS/ {start = 1; next;}
255 {if (start) print $0;}
256' \
257| sed -f $ED3 \
258| sed \
259 -e 's/^.*T_CALLED.*returnCode( \([a-z].*) \));/ return \1;/' \
258 -e 's/^.*T_CALLED.*returnCode( \((wmove.*) \));/ return \1;/'
260 -e 's/^.*T_CALLED.*returnCode( \((wmove.*) \));/ return \1;/' \
261| sed \
262 -e 's/^\(.*\) \(.*\) (\(.*\))$/NCURSES_EXPORT(\1) \2 (\3)/'
259
263