1# mkheader.awk
2# Copyright (C) 2003, 2004 g10 Code GmbH
3# 
4# This program is free software; you can redistribute it and/or
5# modify it under the terms of the GNU General Public License as
6# published by the Free Software Foundation; either version 2 of
7# the License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12# General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17#
18# As a special exception, g10 Code GmbH gives unlimited permission to
19# copy, distribute and modify the C source files that are the output
20# of mkheader.awk.  You need not follow the terms of the GNU General
21# Public License when using or distributing such scripts, even though
22# portions of the text of mkheader.awk appear in them.  The GNU
23# General Public License (GPL) does govern all other use of the material
24# that constitutes the mkheader.awk program.
25#
26# Certain portions of the mkheader.awk source text are designed to be
27# copied (in certain cases, depending on the input) into the output of
28# mkheader.awk.  We call these the "data" portions.  The rest of the
29# mkheader.awk source text consists of comments plus executable code
30# that decides which of the data portions to output in any given case.
31# We call these comments and executable code the "non-data" portions.
32# mkheader.h never copies any of the non-data portions into its output.
33#
34# This special exception to the GPL applies to versions of mkheader.awk
35# released by g10 Code GmbH.  When you make and distribute a modified version
36# of mkheader.awk, you may extend this special exception to the GPL to
37# apply to your modified version as well, *unless* your modified version
38# has the potential to copy into its output some of the text that was the
39# non-data portion of the version that you started with.  (In other words,
40# unless your change moves or copies text from the non-data portions to the
41# data portions.)  If your modification has such potential, you must delete
42# any notice of this special exception to the GPL from your modified version.
43
44# This script processes gpg-error.h.in in an awful way.
45# Its input is, one after another, the content of the err-sources.h.in file,
46# the err-codes.h.in file, the errnos.in file, and then gpg-error.h.in.
47# There is nothing fancy about this.
48#
49# An alternative would be to use getline to get the content of the first three files,
50# but then we need to pre-process gpg-error.h.in with configure to get
51# at the full path of the files in @srcdir@.
52
53BEGIN {
54  FS = "[\t]+";
55# sources_nr holds the number of error sources.
56  sources_nr = 0;
57# codes_nr holds the number of error codes.
58  codes_nr = 0;
59# errnos_nr holds the number of system errors.
60  errnos_nr = 0;
61# extra_nr holds the number of extra lines to be included.
62  extra_nr = 0
63
64# These variables walk us through our input.
65  sources_header = 1;
66  sources_body = 0;
67  between_sources_and_codes = 0;
68  codes_body = 0;
69  between_codes_and_errnos = 0;
70  errnos_body = 0;
71  extra_body = 0;
72  gpg_error_h = 0;
73
74  print "/* Output of mkheader.awk.  DO NOT EDIT.  -*- buffer-read-only: t -*- */";
75  print "";
76
77}
78
79
80sources_header {
81  if ($1 ~ /^[0123456789]+$/)
82    {
83      sources_header = 0;
84      sources_body = 1;
85    }      
86}
87
88sources_body {
89  sub (/\#.+/, "");
90  sub (/[ 	]+$/, ""); # Strip trailing space and tab characters.
91
92  if (/^$/)
93    next;
94
95  if ($1 == "")
96    {
97      sources_body = 0;
98      between_sources_and_codes = 1;
99    }
100  else
101    {
102# Remember the error source number and symbol of each error source.
103      sources_idx[sources_nr] = $1;
104      sources_sym[sources_nr] = $2;
105      sources_nr++;
106    }
107}
108
109between_sources_and_codes {
110  if ($1 ~ /^[0123456789]+$/)
111    {
112      between_sources_and_codes = 0;
113      codes_body = 1;
114    }      
115}
116
117codes_body {
118  sub (/\#.+/, "");
119  sub (/[ 	]+$/, ""); # Strip trailing space and tab characters.
120
121  if (/^$/)
122    next;
123
124  if ($1 == "")
125    {
126      codes_body = 0;
127      between_codes_and_errnos = 1;
128    }
129  else
130    {
131# Remember the error code number and symbol of each error source.
132      codes_idx[codes_nr] = $1;
133      codes_sym[codes_nr] = $2;
134      codes_nr++;
135    }
136}
137
138between_codes_and_errnos {
139  if ($1 ~ /^[0-9]/)
140    {
141      between_codes_and_errnos = 0;
142      errnos_body = 1;
143    }
144}
145
146errnos_body {
147  sub (/\#.+/, "");
148  sub (/[ 	]+$/, ""); # Strip trailing space and tab characters.
149
150  if (/^$/)
151    next;
152
153  if ($1 !~ /^[0-9]/)
154    {
155# Note that this assumes that extra_body.in doesn't start with a digit.
156      errnos_body = 0;
157      extra_body = 1;
158    }
159  else
160    {
161      errnos_idx[errnos_nr] = "GPG_ERR_SYSTEM_ERROR | " $1;
162      errnos_sym[errnos_nr] = "GPG_ERR_" $2;
163      errnos_nr++;
164    }
165}
166
167extra_body {
168  if (/^##/)
169    next
170
171  if (/^EOF/)
172    {
173      extra_body = 0;
174      gpg_error_h = 1;
175      next;
176    }
177  else
178    {
179      extra_line[extra_nr] = $0;
180      extra_nr++;
181    }
182}
183
184gpg_error_h {
185  if ($0 ~ /^@include err-sources/)
186    {
187      for (i = 0; i < sources_nr; i++)
188	{
189	  print "    " sources_sym[i] " = " sources_idx[i] ",";
190#	  print "#define " sources_sym[i] " (" sources_idx[i] ")";
191	}
192    }
193  else if ($0 ~ /^@include err-codes/)
194    {
195      for (i = 0; i < codes_nr; i++)
196	{
197	  print "    " codes_sym[i] " = " codes_idx[i] ",";
198#	  print "#define " codes_sym[i] " (" codes_idx[i] ")";
199	}
200    }
201  else if ($0 ~ /^@include errnos/)
202    {
203      for (i = 0; i < errnos_nr; i++)
204       {
205         print "    " errnos_sym[i] " = " errnos_idx[i] ",";
206#        print "#define " errnos_sym[i] " (" errnos_idx[i] ")";
207       }
208    }
209  else if ($0 ~ /^@include extra-h.in/)
210    {
211      for (i = 0; i < extra_nr; i++)
212	{
213            print extra_line[i];
214	}
215    }
216  else
217    print;
218}
219