1#!/bin/sh
2#
3# Copyright (C) 2014 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18# Pull out types.
19cat $1 |
20  # Mark tables and section boundaries.
21  sed 's/^[0-9][0-9]*\([.][0-9][0-9]*\)\+.*$/_SECTION_BOUNDARY/' |
22  sed 's/^Table [0-9]* . Definition of .*Types[^.]*$/_TYPES/' |
23  # Keep only table sections.
24  awk '/^_TYPES$/,/^_SECTION_BOUNDARY$/ { print $0; }' |
25  sed 's/^_TYPES$//' |
26  sed 's/^_SECTION_BOUNDARY$//' |
27  # Remove headers and footers.
28  sed 's/^.*Trusted Platform Module Library.*$//' |
29  sed 's/^.*Part 2: Structures.*$//' |
30  sed 's/^.*Family .2.0..*$//' |
31  sed 's/^.*Level 00 Revision.*$//' |
32  sed 's/^.*Published.*$//' |
33  sed 's/^.*Copyright.*$//' |
34  sed 's/^.*Page [0-9].*$//' |
35  sed 's/^.*October 31, 2013.*$//' |
36  # Remove table headers.
37  sed 's/^Type$//' | sed 's/^Name$//' | sed 's/^Description$//' |
38  # Remove leading spaces.
39  sed 's/^[ ][ ]*//' |
40  # Remove empty lines.
41  sed '/^$/d' |
42  # Mark begin and end and filter types.
43  awk '
44    BEGIN { print "_BEGIN_TYPES"; state = 0; }
45    /^[^ ]*$/ { if (!state) { print "_OLD_TYPE " $0; state = 1; }
46                else { print "_NEW_TYPE " $0; state = 0; } }
47    END { print "_END"; }
48  ' |
49  # Sanity check.  The format should now follow this grammar:
50  # Format:Begin||Typedef*||End
51  # Begin:_BEGIN_TYPES\n
52  # End:_END\n
53  # Typedef:OldType||NewType
54  # OldType:_OLD_TYPE <type>\n
55  # NewType:_NEW_TYPE <type>\n
56  awk '
57    BEGIN { RS = ""; }
58    $0 !~ /_BEGIN_TYPES\n(_OLD_TYPE[^\n]*\n_NEW_TYPE[^\n]*\n)*_END/ {
59      print "_ERROR: Format check failed."; }
60    { print $0; }
61  '
62
63# Pull out interface types.
64cat $1 |
65  awk '
66    BEGIN { print "_BEGIN_TYPES"; FS = "[ ()]+"; }
67    /^Table [0-9]* . Definition of \([A-Z_]*\) TPMI_.* Type[^.]*$/ {
68      print "_OLD_TYPE " $6;
69      print "_NEW_TYPE " $7; }
70    /^Table [0-9]* . Definition of \{.*\} \([A-Z_]*\) TPMI_.* Type[^.]*$/ {
71      print "_OLD_TYPE " $7;
72      print "_NEW_TYPE " $8; }
73    /^Table [0-9]* . Definition of \([A-Z_]*\) \{.*\} TPMI_.* Type[^.]*$/ {
74      print "_OLD_TYPE " $6;
75      print "_NEW_TYPE " $8; }
76    END { print "_END"; }
77  ' |
78  # Sanity check.  The format should now follow this grammar:
79  # Format:Begin||Typedef*||End
80  # Begin:_BEGIN_TYPES\n
81  # End:_END\n
82  # Typedef:OldType||NewType
83  # OldType:_OLD_TYPE <type>\n
84  # NewType:_NEW_TYPE <type>\n
85  awk '
86    BEGIN { RS = ""; }
87    $0 !~ /_BEGIN_TYPES\n(_OLD_TYPE[^\n]*\n_NEW_TYPE[^\n]*\n)*_END/ {
88      print "_ERROR: Format check failed."; }
89    { print $0; }
90  '
91
92# Pull out attribute types.
93cat $1 |
94  awk '
95    BEGIN { print "_BEGIN_TYPES"; FS = "[ ()]+"; }
96    /^Table [0-9]* . Definition of \([A-Z_0-9]*\) TPM[A-Z_]* Bits[^.]*$/ {
97      print "_OLD_TYPE " $6;
98      print "_NEW_TYPE " $7; }
99    END { print "_END"; }
100  ' |
101  # Sanity check.  The format should now follow this grammar:
102  # Format:Begin||Typedef*||End
103  # Begin:_BEGIN_TYPES\n
104  # End:_END\n
105  # Typedef:OldType||NewType
106  # OldType:_OLD_TYPE <type>\n
107  # NewType:_NEW_TYPE <type>\n
108  awk '
109    BEGIN { RS = ""; }
110    $0 !~ /_BEGIN_TYPES\n(_OLD_TYPE[^\n]*\n_NEW_TYPE[^\n]*\n)*_END/ {
111      print "_ERROR: Format check failed."; }
112    { print $0; }
113  '
114
115# Pull out constant values.
116cat $1 |
117  # Mark tables and section boundaries.
118  sed 's/^[0-9][0-9]*\([.][0-9][0-9]*\)\+.*$/_SECTION_BOUNDARY/' |
119  sed 's/^Table [0-9]* . Definition of \(.*\) Constants[^.]*$/_CONSTANTS \1/' |
120  # Keep only table sections.
121  awk '/^_CONSTANTS .*$/,/^_SECTION_BOUNDARY$/ { print $0; }' |
122  sed 's/^_SECTION_BOUNDARY$//' |
123  # Remove headers and footers.
124  sed 's/^.*Trusted Platform Module Library.*$//' |
125  sed 's/^.*Part 2: Structures.*$//' |
126  sed 's/^.*Family .2.0..*$//' |
127  sed 's/^.*Level 00 Revision.*$//' |
128  sed 's/^.*Published.*$//' |
129  sed 's/^.*Copyright.*$//' |
130  sed 's/^.*Page [0-9].*$//' |
131  sed 's/^.*October 31, 2013.*$//' |
132  # Remove table headers.
133  sed 's/^Name$//' | sed 's/^Value$//' | sed 's/^Comments$//' |
134  # Remove leading spaces.
135  sed 's/^[ ][ ]*//' |
136  # Remove empty lines.
137  sed '/^$/d' |
138  # Mark begin and end.
139  awk '
140    BEGIN { print "_BEGIN_CONSTANTS"; }
141    { print $0; }
142    END { print "_END"; }
143  ' |
144  # Mark type.
145  awk '
146    BEGIN { FS = "[ ()]+"; }
147    { print $0; }
148    /^_CONSTANTS \(\w*\) .*$/ { print "_TYPE " $2; }
149  ' |
150  # Mark names.
151  sed 's/^\(TPM_[_A-Z0-9a]*\)$/_NAME \1/' |
152  sed 's/^\(TPM_CC_[_A-Z0-9a-z]*\)$/_NAME \1/' |
153  sed 's/^\(RC_[_A-Z0-9]*\)$/_NAME \1/' |
154  sed 's/^\(PT_[_A-Z0-9]*\)$/_NAME \1/' |
155  sed 's/^\(HR_[_A-Z0-9]*\)$/_NAME \1/' |
156  sed 's/^\([_A-Z0-9]*FIRST\)$/_NAME \1/' |
157  sed 's/^\([_A-Z0-9]*LAST\)$/_NAME \1/' |
158  sed 's/^\(PLATFORM_PERSISTENT\)$/_NAME \1/' |
159  # Mark values and throw away everything else.
160  awk '
161    BEGIN { last_line_was_name = 0; }
162    /^_.*$/      { if ($0 !~ /^_NAME .*$/) { print $0; } }
163    /^_NAME .*$/ { if (last_line_was_name) {
164                     last_line_was_name = 0;
165                     if ($0 !~ /[A-Z_0-9x +]*/) { print "_ERROR: Invalid value"; }
166                     print "_VALUE " $2; }
167                   else { last_line_was_name = 1; print $0; } }
168    /^[^_].*$/   { if (last_line_was_name) {
169                     last_line_was_name = 0;
170                     if ($0 !~ /[A-Z_0-9x +]*/) { print "_ERROR: Invalid value"; }
171                     print "_VALUE " $0; } }
172  ' |
173  # Sanity check.  The format should now follow this grammar:
174  # Format:Begin||TableBlock*||End
175  # Begin:_BEGIN_CONSTANTS\n
176  # End:_END\n
177  # TableBlock:TableTag||Type||Constant*
178  # TableTag:_CONSTANTS <name>\n
179  # Constant:Name||Value
180  # Type:_TYPE <type>\n
181  # Name:_NAME <name>\n
182  # Value:_VALUE <value>\n
183  awk '
184    BEGIN { RS = ""; }
185    $0 !~ /_BEGIN_CONSTANTS\n(_CONSTANTS[^\n]*\n_TYPE[^\n]*\n(_NAME[^\n]*\n_VALUE[^\n]*\n)*)*_END/ {
186      print "_ERROR: Format check failed."; }
187    { print $0; }
188  '
189
190# Pull out structures.
191cat $1 |
192  # Mark tables and section boundaries.
193  sed 's/^[0-9][0-9]*\([.][0-9][0-9]*\)\+.*$/_SECTION_BOUNDARY/' |
194  sed 's/^Table [0-9]* . Definition of \(.*\) Structure[^.]*$/_STRUCTURE \1/' |
195  # Keep only table sections.
196  awk '/^_STRUCTURE .*$/,/^_SECTION_BOUNDARY$/ { print $0; }' |
197  sed 's/^_SECTION_BOUNDARY$//' |
198  # Remove headers and footers.
199  sed 's/^.*Trusted Platform Module Library.*$//' |
200  sed 's/^.*Part 2: Structures.*$//' |
201  sed 's/^.*Family .2.0..*$//' |
202  sed 's/^.*Level 00 Revision.*$//' |
203  sed 's/^.*Published.*$//' |
204  sed 's/^.*Copyright.*$//' |
205  sed 's/^.*Page [0-9].*$//' |
206  sed 's/^.*October 31, 2013.*$//' |
207  # Remove table headers.
208  sed 's/^Parameter$//' | sed 's/^Type$//' | sed 's/^Description$//' |
209  # Remove leading spaces.
210  sed 's/^[ ][ ]*//' |
211  # Remove empty lines.
212  sed '/^$/d' |
213  # Mark begin and end.
214  awk '
215    BEGIN { print "_BEGIN_STRUCTURES"; }
216    { print $0; }
217    END { print "_END"; }
218  ' |
219  # Mark field types.
220  sed 's/^\(+*TPM[_A-Z0-9+]*\)$/_TYPE \1/' |
221  sed 's/^\(UINT[0-9]*\)$/_TYPE \1/' |
222  sed 's/^\(BYTE*\)$/_TYPE \1/' |
223  # Mark field names and throw away everything else.
224  awk '
225    BEGIN { last_line = ""; }
226    /^_.*$/      { print $0; }
227    /^_TYPE .*$/ { if (last_line != "") { print "_NAME " last_line; }
228                   else { print "_ERROR: Type with no name"; }
229                   last_line = ""; }
230    /^[^_].*$/   { last_line = $0; }
231  ' |
232  # Change 'value [size] {:max}' to 'value[max]'.
233  sed 's/^\(_NAME \w*\).*\[\w*\].*[{][:] *\([a-zA-Z0-9_()/]*\)[}]$/\1[\2]/' |
234  # Strip off other modifiers.
235  sed 's/^\(_NAME \w*\)[ {].*/\1/' |
236  sed 's/^_TYPE +\(.*\)$/_TYPE \1/' |
237  sed 's/^_TYPE \(.*\)+$/_TYPE \1/' |
238  sed 's/^_NAME \/*\[.*\] *\(.*\)$/_NAME \1/' |
239  sed 's/^\(_NAME \w*\)=/\1/' |
240  sed 's/^_STRUCTURE \((.*) \)*{.*} \(.*\)/_STRUCTURE \2/' |
241  # Sanity check.  The format should now follow this grammar:
242  # Format:Begin||TableBlock*||End
243  # Begin:_BEGIN_STRUCTURES\n
244  # End:_END\n
245  # TableBlock:TableTag||Field*
246  # TableTag:_STRUCTURE <name>\n
247  # Field:Type||Name
248  # Type:_TYPE <type>\n
249  # Name:_NAME <name>\n
250  awk '
251    BEGIN { RS = ""; }
252    $0 !~ /_BEGIN_STRUCTURES\n(_STRUCTURE[^\n]*\n(_TYPE[^\n]*\n_NAME[^\n]*\n)*)*_END/ {
253      print "_ERROR: Format check failed."; }
254    { print $0; }
255  '
256
257# Pull out unions.
258cat $1 |
259  # Mark tables and section boundaries.
260  sed 's/^[0-9][0-9]*\([.][0-9][0-9]*\)\+.*$/_SECTION_BOUNDARY/' |
261  sed 's/^Table [0-9]* . Definition of \(.*\) Union[^.]*$/_UNION \1/' |
262  # Keep only table sections.
263  awk '/^_UNION .*$/,/^_SECTION_BOUNDARY$/ { print $0; }' |
264  sed 's/^_SECTION_BOUNDARY$//' |
265  # Remove headers and footers.
266  sed 's/^.*Trusted Platform Module Library.*$//' |
267  sed 's/^.*Part 2: Structures.*$//' |
268  sed 's/^.*Family .2.0..*$//' |
269  sed 's/^.*Level 00 Revision.*$//' |
270  sed 's/^.*Published.*$//' |
271  sed 's/^.*Copyright.*$//' |
272  sed 's/^.*Page [0-9].*$//' |
273  sed 's/^.*October 31, 2013.*$//' |
274  # Remove table headers.
275  sed 's/^Parameter$//' | sed 's/^Type$//' | sed 's/^Selector$//' |
276  sed 's/^Description$//' |
277  # Remove leading spaces.
278  sed 's/^[ ][ ]*//' |
279  # Remove empty lines.
280  sed '/^$/d' |
281  # Mark begin and end.
282  awk '
283    BEGIN { print "_BEGIN_UNIONS"; }
284    { print $0; }
285    END { print "_END"; }
286  ' |
287  # Mark field types.
288  sed 's/^\(+*TPM[_A-Z0-9+a]*\)$/_TYPE \1/' |
289  sed 's/^\(UINT[0-9]*\)$/_TYPE \1/' |
290  sed 's/^\(BYTE*\)$/_TYPE \1/' |
291  # Mark field names and throw away everything else.
292  awk '
293    BEGIN { last_line = ""; }
294    /^_.*$/      { if ($0 !~ /^_TYPE .*$/) { last_line = ""; print $0; } }
295    /^_TYPE .*$/ { if (last_line !~ /^_TYPE .*$/) {
296                     if (last_line != "" &&
297                         last_line != "null" &&
298                         last_line != "NOTE") {
299                       print $0;
300                       print "_NAME " last_line; }
301                     else if (last_line == "") {
302                       print "_ERROR: Type with no name"; }
303                     last_line = $0; } }
304    /^[^_].*$/   { last_line = $0; }
305  ' |
306  # Change 'value [size] {:max}' to 'value[max]'.
307  sed 's/^\(_NAME \w*\).*\[\w*\].*[{][:] *\([a-zA-Z0-9_()/]*\)[}]$/\1[\2]/' |
308  # Strip off other modifiers.
309  sed 's/^\(_NAME \w*\) \(\[.*\]\)/\1\2/' |
310  sed 's/^\(_NAME \w*\)\( {|{\).*/\1/' |
311  sed 's/^_TYPE +\(.*\)$/_TYPE \1/' |
312  # Sanity check.  The format should now follow this grammar:
313  # Format:Begin||TableBlock*||End
314  # Begin:_BEGIN_UNIONS\n
315  # End:_END\n
316  # TableBlock:TableTag||Field*
317  # TableTag:_UNION <name>\n
318  # Field:Type||Name
319  # Type:_TYPE <type>\n
320  # Name:_NAME <name>\n
321  awk '
322    BEGIN { RS = ""; }
323    $0 !~ /_BEGIN_UNIONS\n(_UNION[^\n]*\n(_TYPE[^\n]*\n_NAME[^\n]*\n)*)*_END/ {
324      print "_ERROR: Format check failed."; }
325    { print $0; }
326  '
327
328# Pull out default defines.
329cat $1 |
330  sed 's/^[A-Z]\([.][0-9][0-9]*\)\+.*$/_SECTION_BOUNDARY/' |
331  sed 's/^Table [0-9]* . Defines for \([^.]*\)$/_DEFINES \1/' |
332  sed 's/^_DEFINES Implemented Commands$//' |
333  sed 's/^_DEFINES Implemented Algorithms$//' |
334  awk '/^_DEFINES .*$/,/^_SECTION_BOUNDARY$/ { print $0; }' |
335  sed 's/^_SECTION_BOUNDARY$//' |
336  # Remove headers and footers.
337  sed 's/^.*Trusted Platform Module Library.*$//' |
338  sed 's/^.*Part 2: Structures.*$//' |
339  sed 's/^.*Family .2.0..*$//' |
340  sed 's/^.*Level 00 Revision.*$//' |
341  sed 's/^.*Published.*$//' |
342  sed 's/^.*Copyright.*$//' |
343  sed 's/^.*Page [0-9].*$//' |
344  sed 's/^.*October 31, 2013.*$//' |
345  # Remove table headers.
346  sed 's/^Name$//' | sed 's/^Value$//' | sed 's/^Description$//' |
347  # Remove most comments.
348  sed 's/^.*[g-wyz?]\+.*$//' |
349  # Remove leading spaces.
350  sed 's/^[ ][ ]*//' |
351  # Remove empty lines.
352  sed '/^$/d' |
353  # Mark begin and end.
354  awk '
355    BEGIN { print "_BEGIN_DEFINES"; }
356    { print $0; }
357    END { print "_END"; }
358  ' |
359  # Mark define names.
360  sed 's/^\([A-Z][_A-Z0-9]*\)$/_NAME \1/' |
361  sed 's/^_NAME NOTE$//' |
362  # Mark values and throw away everything else.
363  awk '
364    BEGIN { last_line_was_name = 0; }
365    /^_.*$/      { if ($0 !~ /^_NAME .*$/) { print $0; } }
366    /^_NAME .*$/ { if (last_line_was_name) {
367                     last_line_was_name = 0;
368                     if ($0 !~ /[A-Z_0-9x +()]*/) {
369                       print "_ERROR: Invalid value"; }
370                     print "_VALUE " $2; }
371                   else { last_line_was_name = 1; print $0; } }
372    /^[^_].*$/   { if (last_line_was_name) {
373                     last_line_was_name = 0;
374                     if ($0 !~ /[A-Z_0-9x +()]*/) {
375                       print "_ERROR: Invalid value"; }
376                     print "_VALUE " $0; } }
377  ' |
378  # Sanity check.  The format should now follow this grammar:
379  # Format:Begin||Define*||End
380  # Begin:_BEGIN_DEFINES\n
381  # End:_END\n
382  # Define:Name||Value
383  # Name:_NAME <name>\n
384  # Value:_VALUE <value>\n
385  awk '
386    BEGIN { RS = ""; }
387    $0 !~ /_BEGIN_DEFINES\n(_NAME[^\n]*\n_VALUE[^\n]*\n)*_END/ {
388      print "_ERROR: Format check failed."; }
389    { print $0; }
390  '
391
392exit 0
393