]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - Tools/Source/GenBuild/org/tianocore/build/pcd/action/PcdDatabase.java
Fixed grammar in messages.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / PcdDatabase.java
... / ...
CommitLineData
1/** @file\r
2 PcdDatabase class.\r
3\r
4Copyright (c) 2006, Intel Corporation\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14package org.tianocore.build.pcd.action;\r
15\r
16import java.io.BufferedReader;\r
17import java.io.File;\r
18import java.io.FileReader;\r
19import java.util.ArrayList;\r
20import java.util.Comparator;\r
21import java.util.HashMap;\r
22import java.util.List;\r
23import java.util.Map;\r
24import java.util.UUID;\r
25import org.tianocore.build.global.GlobalData;\r
26import org.tianocore.pcd.entity.DynamicTokenValue;\r
27import org.tianocore.pcd.entity.Token;\r
28import org.tianocore.pcd.exception.EntityException;\r
29\r
30/**\r
31 CStructTypeDeclaration\r
32\r
33 This class is used to store the declaration string, such as\r
34 "UINT32 PcdPlatformFlashBaseAddress", of\r
35 each memember in the C structure, which is a standard C language\r
36 feature used to implement a simple and efficient database for\r
37 dynamic(ex) type PCD entry.\r
38**/\r
39class CStructTypeDeclaration {\r
40 String key;\r
41 int alignmentSize;\r
42 String cCode;\r
43 boolean initTable;\r
44\r
45 public CStructTypeDeclaration (String key, int alignmentSize, String cCode, boolean initTable) {\r
46 this.key = key;\r
47 this.alignmentSize = alignmentSize;\r
48 this.cCode = cCode;\r
49 this.initTable = initTable;\r
50 }\r
51}\r
52\r
53/**\r
54 StringTable\r
55\r
56 This class is used to store the String in a PCD database.\r
57\r
58**/\r
59class StringTable {\r
60 private ArrayList<String> al;\r
61 private ArrayList<String> alComments;\r
62 private String phase;\r
63 int len;\r
64\r
65 public StringTable (String phase) {\r
66 this.phase = phase;\r
67 al = new ArrayList<String>();\r
68 alComments = new ArrayList<String>();\r
69 len = 0;\r
70 }\r
71\r
72 public String getSizeMacro () {\r
73 return String.format(PcdDatabase.StringTableSizeMacro, phase, getSize());\r
74 }\r
75\r
76 private int getSize () {\r
77 //\r
78 // We have at least one Unicode Character in the table.\r
79 //\r
80 return len == 0 ? 1 : len;\r
81 }\r
82\r
83 public String getExistanceMacro () {\r
84 return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
85 }\r
86\r
87 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable) {\r
88 final String stringTable = "StringTable";\r
89 final String tab = "\t";\r
90 final String newLine = "\r\n";\r
91 final String commaNewLine = ",\r\n";\r
92\r
93 CStructTypeDeclaration decl;\r
94\r
95 String cDeclCode = "";\r
96 String cInstCode = "";\r
97\r
98 //\r
99 // If we have a empty StringTable\r
100 //\r
101 if (al.size() == 0) {\r
102 cDeclCode += String.format("%-20s%s[1]; /* StringTable is empty */", "UINT16", stringTable) + newLine;\r
103 decl = new CStructTypeDeclaration (\r
104 stringTable,\r
105 2,\r
106 cDeclCode,\r
107 true\r
108 );\r
109 declaList.add(decl);\r
110\r
111 cInstCode = String.format("/* %s */", stringTable) + newLine + tab + "{ 0 }";\r
112 instTable.put(stringTable, cInstCode);\r
113 } else {\r
114\r
115 //\r
116 // If there is any String in the StringTable\r
117 //\r
118 for (int i = 0; i < al.size(); i++) {\r
119 String str = al.get(i);\r
120 String stringTableName;\r
121\r
122 if (i == 0) {\r
123 //\r
124 // StringTable is a well-known name in the PCD DXE driver\r
125 //\r
126 stringTableName = stringTable;\r
127\r
128 } else {\r
129 stringTableName = String.format("%s_%d", stringTable, i);\r
130 cDeclCode += tab;\r
131 }\r
132 cDeclCode += String.format("%-20s%s[%d]; /* %s */", "UINT16",\r
133 stringTableName, str.length() + 1,\r
134 alComments.get(i))\r
135 + newLine;\r
136\r
137 if (i == 0) {\r
138 cInstCode = "/* StringTable */" + newLine;\r
139 }\r
140\r
141 cInstCode += tab + String.format("L\"%s\" /* %s */", al.get(i), alComments.get(i));\r
142 if (i != al.size() - 1) {\r
143 cInstCode += commaNewLine;\r
144 }\r
145 }\r
146\r
147 decl = new CStructTypeDeclaration (\r
148 stringTable,\r
149 2,\r
150 cDeclCode,\r
151 true\r
152 );\r
153 declaList.add(decl);\r
154\r
155 instTable.put(stringTable, cInstCode);\r
156 }\r
157 }\r
158\r
159 public int add (String inputStr, Token token) {\r
160 int i;\r
161 int pos;\r
162\r
163 String str = inputStr;\r
164\r
165 //\r
166 // The input can be two types:\r
167 // "L\"Bootmode\"" or "Bootmode".\r
168 // We drop the L\" and \" for the first type.\r
169 if (str.startsWith("L\"") && str.endsWith("\"")) {\r
170 str = str.substring(2, str.length() - 1);\r
171 }\r
172 //\r
173 // Check if StringTable has this String already.\r
174 // If so, return the current pos.\r
175 //\r
176 for (i = 0, pos = 0; i < al.size(); i++) {\r
177 String s = al.get(i);;\r
178\r
179 if (str.equals(s)) {\r
180 return pos;\r
181 }\r
182 pos = s.length() + 1;\r
183 }\r
184\r
185 i = len;\r
186 //\r
187 // Include the NULL character at the end of String\r
188 //\r
189 len += str.length() + 1;\r
190 al.add(str);\r
191 alComments.add(token.getPrimaryKeyString());\r
192\r
193 return i;\r
194 }\r
195}\r
196\r
197/**\r
198 SizeTable\r
199\r
200 This class is used to store the Size information for\r
201 POINTER TYPE PCD entry in a PCD database.\r
202\r
203**/\r
204class SizeTable {\r
205 private ArrayList<ArrayList<Integer>> al;\r
206 private ArrayList<String> alComments;\r
207 private int len;\r
208 private String phase;\r
209\r
210 public SizeTable (String phase) {\r
211 al = new ArrayList<ArrayList<Integer>>();\r
212 alComments = new ArrayList<String>();\r
213 len = 0;\r
214 this.phase = phase;\r
215 }\r
216\r
217 public String getSizeMacro () {\r
218 return String.format(PcdDatabase.SizeTableSizeMacro, phase, getSize());\r
219 }\r
220\r
221 private int getSize() {\r
222 return len == 0 ? 1 : len;\r
223 }\r
224\r
225 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
226 final String name = "SizeTable";\r
227\r
228 CStructTypeDeclaration decl;\r
229 String cCode;\r
230\r
231 cCode = String.format(PcdDatabase.SizeTableDeclaration, phase);\r
232 decl = new CStructTypeDeclaration (\r
233 name,\r
234 2,\r
235 cCode,\r
236 true\r
237 );\r
238 declaList.add(decl);\r
239\r
240\r
241 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
242 instTable.put(name, cCode);\r
243 }\r
244\r
245 private ArrayList<String> getInstantiation () {\r
246 final String comma = ",";\r
247 ArrayList<String> Output = new ArrayList<String>();\r
248\r
249 Output.add("/* SizeTable */");\r
250 Output.add("{");\r
251 if (al.size() == 0) {\r
252 Output.add("\t0");\r
253 } else {\r
254 for (int index = 0; index < al.size(); index++) {\r
255 ArrayList<Integer> ial = al.get(index);\r
256\r
257 String str = "\t";\r
258\r
259 for (int index2 = 0; index2 < ial.size(); index2++) {\r
260 str += " " + ial.get(index2).toString();\r
261 if (index2 != ial.size() - 1) {\r
262 str += comma;\r
263 }\r
264 }\r
265\r
266 str += " /* " + alComments.get(index) + " */";\r
267\r
268 if (index != (al.size() - 1)) {\r
269 str += comma;\r
270 }\r
271\r
272 Output.add(str);\r
273\r
274 }\r
275 }\r
276 Output.add("}");\r
277\r
278 return Output;\r
279 }\r
280\r
281 public void add (Token token) {\r
282\r
283 //\r
284 // We only have size information for POINTER type PCD entry.\r
285 //\r
286 if (token.datumType != Token.DATUM_TYPE.POINTER) {\r
287 return;\r
288 }\r
289\r
290 ArrayList<Integer> ial = token.getPointerTypeSize();\r
291\r
292 len+= ial.size();\r
293\r
294 al.add(ial);\r
295 alComments.add(token.getPrimaryKeyString());\r
296\r
297 return;\r
298 }\r
299\r
300}\r
301\r
302/**\r
303 GuidTable\r
304\r
305 This class is used to store the GUIDs in a PCD database.\r
306**/\r
307class GuidTable {\r
308 private ArrayList<UUID> al;\r
309 private ArrayList<String> alComments;\r
310 private String phase;\r
311 private int len;\r
312 private int bodyLineNum;\r
313\r
314 public GuidTable (String phase) {\r
315 this.phase = phase;\r
316 al = new ArrayList<UUID>();\r
317 alComments = new ArrayList<String>();\r
318 len = 0;\r
319 bodyLineNum = 0;\r
320 }\r
321\r
322 public String getSizeMacro () {\r
323 return String.format(PcdDatabase.GuidTableSizeMacro, phase, getSize());\r
324 }\r
325\r
326 private int getSize () {\r
327 return (al.size() == 0)? 1 : al.size();\r
328 }\r
329\r
330 public String getExistanceMacro () {\r
331 return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
332 }\r
333\r
334 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
335 final String name = "GuidTable";\r
336\r
337 CStructTypeDeclaration decl;\r
338 String cCode = "";\r
339\r
340 cCode += String.format(PcdDatabase.GuidTableDeclaration, phase);\r
341 decl = new CStructTypeDeclaration (\r
342 name,\r
343 4,\r
344 cCode,\r
345 true\r
346 );\r
347 declaList.add(decl);\r
348\r
349\r
350 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
351 instTable.put(name, cCode);\r
352 }\r
353\r
354 private String getUuidCString (UUID uuid) {\r
355 String[] guidStrArray;\r
356\r
357 guidStrArray =(uuid.toString()).split("-");\r
358\r
359 return String.format("{0x%s, 0x%s, 0x%s, {0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s}}",\r
360 guidStrArray[0],\r
361 guidStrArray[1],\r
362 guidStrArray[2],\r
363 (guidStrArray[3].substring(0, 2)),\r
364 (guidStrArray[3].substring(2, 4)),\r
365 (guidStrArray[4].substring(0, 2)),\r
366 (guidStrArray[4].substring(2, 4)),\r
367 (guidStrArray[4].substring(4, 6)),\r
368 (guidStrArray[4].substring(6, 8)),\r
369 (guidStrArray[4].substring(8, 10)),\r
370 (guidStrArray[4].substring(10, 12))\r
371 );\r
372 }\r
373\r
374 private ArrayList<String> getInstantiation () {\r
375 ArrayList<String> Output = new ArrayList<String>();\r
376\r
377 Output.add("/* GuidTable */");\r
378 Output.add("{");\r
379\r
380 if (al.size() == 0) {\r
381 Output.add("\t" + getUuidCString(new UUID(0, 0)));\r
382 }\r
383\r
384 for (int i = 0; i < al.size(); i++) {\r
385 String str = "\t" + getUuidCString(al.get(i));\r
386\r
387 str += "/* " + alComments.get(i) + " */";\r
388 if (i != (al.size() - 1)) {\r
389 str += ",";\r
390 }\r
391 Output.add(str);\r
392 bodyLineNum++;\r
393\r
394 }\r
395 Output.add("}");\r
396\r
397 return Output;\r
398 }\r
399\r
400 public int add (UUID uuid, String name) {\r
401 //\r
402 // Check if GuidTable has this entry already.\r
403 // If so, return the GuidTable index.\r
404 //\r
405 for (int i = 0; i < al.size(); i++) {\r
406 if (al.get(i).compareTo(uuid) == 0) {\r
407 return i;\r
408 }\r
409 }\r
410\r
411 len++;\r
412 al.add(uuid);\r
413 alComments.add(name);\r
414\r
415 //\r
416 // Return the previous Table Index\r
417 //\r
418 return len - 1;\r
419 }\r
420\r
421}\r
422\r
423/**\r
424 SkuIdTable\r
425\r
426 This class is used to store the SKU IDs in a PCD database.\r
427\r
428**/\r
429class SkuIdTable {\r
430 private ArrayList<Integer[]> al;\r
431 private ArrayList<String> alComment;\r
432 private String phase;\r
433 private int len;\r
434\r
435 public SkuIdTable (String phase) {\r
436 this.phase = phase;\r
437 al = new ArrayList<Integer[]>();\r
438 alComment = new ArrayList<String>();\r
439 len = 0;\r
440 }\r
441\r
442 public String getSizeMacro () {\r
443 return String.format(PcdDatabase.SkuIdTableSizeMacro, phase, getSize());\r
444 }\r
445\r
446 private int getSize () {\r
447 return (len == 0)? 1 : len;\r
448 }\r
449\r
450 public String getExistanceMacro () {\r
451 return String.format(PcdDatabase.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
452 }\r
453\r
454 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
455 final String name = "SkuIdTable";\r
456\r
457 CStructTypeDeclaration decl;\r
458 String cCode = "";\r
459\r
460 cCode += String.format(PcdDatabase.SkuIdTableDeclaration, phase);\r
461 decl = new CStructTypeDeclaration (\r
462 name,\r
463 1,\r
464 cCode,\r
465 true\r
466 );\r
467 declaList.add(decl);\r
468\r
469\r
470 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
471 instTable.put(name, cCode);\r
472\r
473 //\r
474 // SystemSkuId is in PEI phase PCD Database\r
475 //\r
476 if (phase.equalsIgnoreCase("PEI")) {\r
477 decl = new CStructTypeDeclaration (\r
478 "SystemSkuId",\r
479 1,\r
480 String.format("%-20sSystemSkuId;\r\n", "SKU_ID"),\r
481 true\r
482 );\r
483 declaList.add(decl);\r
484\r
485 instTable.put("SystemSkuId", "0");\r
486 }\r
487\r
488 }\r
489\r
490 private ArrayList<String> getInstantiation () {\r
491 ArrayList<String> Output = new ArrayList<String> ();\r
492\r
493 Output.add("/* SkuIdTable */");\r
494 Output.add("{");\r
495\r
496 if (al.size() == 0) {\r
497 Output.add("\t0");\r
498 }\r
499\r
500 for (int index = 0; index < al.size(); index++) {\r
501 String str;\r
502\r
503 str = "/* " + alComment.get(index) + "*/ ";\r
504 str += "/* MaxSku */ ";\r
505\r
506\r
507 Integer[] ia = al.get(index);\r
508\r
509 str += "\t" + ia[0].toString() + ", ";\r
510 for (int index2 = 1; index2 < ia.length; index2++) {\r
511 str += ia[index2].toString();\r
512 if (!((index2 == ia.length - 1) && (index == al.size() - 1))) {\r
513 str += ", ";\r
514 }\r
515 }\r
516\r
517 Output.add(str);\r
518\r
519 }\r
520\r
521 Output.add("}");\r
522\r
523 return Output;\r
524 }\r
525\r
526 public int add (Token token) {\r
527\r
528 int index;\r
529 int pos;\r
530\r
531 //\r
532 // Check if this SKU_ID Array is already in the table\r
533 //\r
534 pos = 0;\r
535 for (Object o: al) {\r
536 Integer [] s = (Integer[]) o;\r
537 boolean different = false;\r
538 if (s[0] == token.getSkuIdCount()) {\r
539 for (index = 1; index < s.length; index++) {\r
540 if (s[index] != token.skuData.get(index-1).id) {\r
541 different = true;\r
542 break;\r
543 }\r
544 }\r
545 } else {\r
546 different = true;\r
547 }\r
548 if (different) {\r
549 pos += s[0] + 1;\r
550 } else {\r
551 return pos;\r
552 }\r
553 }\r
554\r
555 Integer [] skuIds = new Integer[token.skuData.size() + 1];\r
556 skuIds[0] = new Integer(token.skuData.size());\r
557 for (index = 1; index < skuIds.length; index++) {\r
558 skuIds[index] = new Integer(token.skuData.get(index - 1).id);\r
559 }\r
560\r
561 index = len;\r
562\r
563 len += skuIds.length;\r
564 al.add(skuIds);\r
565 alComment.add(token.getPrimaryKeyString());\r
566\r
567 return index;\r
568 }\r
569\r
570}\r
571\r
572class LocalTokenNumberTable {\r
573 private ArrayList<String> al;\r
574 private ArrayList<String> alComment;\r
575 private String phase;\r
576 private int len;\r
577\r
578 public LocalTokenNumberTable (String phase) {\r
579 this.phase = phase;\r
580 al = new ArrayList<String>();\r
581 alComment = new ArrayList<String>();\r
582\r
583 len = 0;\r
584 }\r
585\r
586 public String getSizeMacro () {\r
587 return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize())\r
588 + String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size());\r
589 }\r
590\r
591 public int getSize () {\r
592 return (al.size() == 0)? 1 : al.size();\r
593 }\r
594\r
595 public String getExistanceMacro () {\r
596 return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
597 }\r
598\r
599 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
600 final String name = "LocalTokenNumberTable";\r
601\r
602 CStructTypeDeclaration decl;\r
603 String cCode = "";\r
604\r
605 cCode += String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase);\r
606 decl = new CStructTypeDeclaration (\r
607 name,\r
608 4,\r
609 cCode,\r
610 true\r
611 );\r
612 declaList.add(decl);\r
613\r
614 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
615 instTable.put(name, cCode);\r
616 }\r
617\r
618 private ArrayList<String> getInstantiation () {\r
619 ArrayList<String> output = new ArrayList<String>();\r
620\r
621 output.add("/* LocalTokenNumberTable */");\r
622 output.add("{");\r
623\r
624 if (al.size() == 0) {\r
625 output.add("\t0");\r
626 }\r
627\r
628 for (int index = 0; index < al.size(); index++) {\r
629 String str;\r
630\r
631 str = "\t" + (String)al.get(index);\r
632\r
633 str += " /* " + alComment.get(index) + " */ ";\r
634\r
635\r
636 if (index != (al.size() - 1)) {\r
637 str += ",";\r
638 }\r
639\r
640 output.add(str);\r
641\r
642 }\r
643\r
644 output.add("}");\r
645\r
646 return output;\r
647 }\r
648\r
649 public int add (Token token) {\r
650 int index = len;\r
651 String str;\r
652\r
653 len++;\r
654\r
655 str = String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString());\r
656\r
657 if (token.isUnicodeStringType()) {\r
658 str += " | PCD_TYPE_STRING";\r
659 }\r
660\r
661 if (token.isSkuEnable()) {\r
662 str += " | PCD_TYPE_SKU_ENABLED";\r
663 }\r
664\r
665 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {\r
666 str += " | PCD_TYPE_HII";\r
667 }\r
668\r
669 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {\r
670 str += " | PCD_TYPE_VPD";\r
671 }\r
672\r
673 switch (token.datumType) {\r
674 case UINT8:\r
675 case BOOLEAN:\r
676 str += " | PCD_DATUM_TYPE_UINT8";\r
677 break;\r
678 case UINT16:\r
679 str += " | PCD_DATUM_TYPE_UINT16";\r
680 break;\r
681 case UINT32:\r
682 str += " | PCD_DATUM_TYPE_UINT32";\r
683 break;\r
684 case UINT64:\r
685 str += " | PCD_DATUM_TYPE_UINT64";\r
686 break;\r
687 case POINTER:\r
688 str += " | PCD_DATUM_TYPE_POINTER";\r
689 break;\r
690 }\r
691\r
692 al.add(str);\r
693 alComment.add(token.getPrimaryKeyString());\r
694\r
695 return index;\r
696 }\r
697}\r
698\r
699/**\r
700 ExMapTable\r
701\r
702 This class is used to store the table of mapping information\r
703 between DynamicEX ID pair(Guid, TokenNumber) and\r
704 the local token number assigned by PcdDatabase class.\r
705**/\r
706class ExMapTable {\r
707\r
708 /**\r
709 ExTriplet\r
710\r
711 This class is used to store the mapping information\r
712 between DynamicEX ID pair(Guid, TokenNumber) and\r
713 the local token number assigned by PcdDatabase class.\r
714 **/\r
715 class ExTriplet {\r
716 public Integer guidTableIdx;\r
717 public Long exTokenNumber;\r
718 public Long localTokenIdx;\r
719\r
720 public ExTriplet (int guidTableIdx, long exTokenNumber, long localTokenIdx) {\r
721 this.guidTableIdx = new Integer(guidTableIdx);\r
722 this.exTokenNumber = new Long(exTokenNumber);\r
723 this.localTokenIdx = new Long(localTokenIdx);\r
724 }\r
725 }\r
726\r
727 private ArrayList<ExTriplet> al;\r
728 private Map<ExTriplet, String> alComment;\r
729 private String phase;\r
730 private int len;\r
731 private int bodyLineNum;\r
732\r
733 public ExMapTable (String phase) {\r
734 this.phase = phase;\r
735 al = new ArrayList<ExTriplet>();\r
736 alComment = new HashMap<ExTriplet, String>();\r
737 bodyLineNum = 0;\r
738 len = 0;\r
739 }\r
740\r
741 public String getSizeMacro () {\r
742 return String.format(PcdDatabase.ExMapTableSizeMacro, phase, getTableLen())\r
743 + String.format(PcdDatabase.ExTokenNumber, phase, al.size());\r
744 }\r
745\r
746 public String getExistanceMacro () {\r
747 return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
748 }\r
749\r
750 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
751 final String exMapTableName = "ExMapTable";\r
752\r
753 sortTable();\r
754\r
755 CStructTypeDeclaration decl;\r
756 String cCode = "";\r
757\r
758 cCode += String.format(PcdDatabase.ExMapTableDeclaration, phase);\r
759 decl = new CStructTypeDeclaration (\r
760 exMapTableName,\r
761 4,\r
762 cCode,\r
763 true\r
764 );\r
765 declaList.add(decl);\r
766\r
767\r
768 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
769 instTable.put(exMapTableName, cCode);\r
770 }\r
771\r
772 private ArrayList<String> getInstantiation () {\r
773 ArrayList<String> Output = new ArrayList<String>();\r
774\r
775 Output.add("/* ExMapTable */");\r
776 Output.add("{");\r
777 if (al.size() == 0) {\r
778 Output.add("\t{0, 0, 0}");\r
779 }\r
780\r
781 int index;\r
782 for (index = 0; index < al.size(); index++) {\r
783 String str;\r
784\r
785 ExTriplet e = (ExTriplet)al.get(index);\r
786\r
787 str = "\t" + "{ " + String.format("0x%08X", e.exTokenNumber) + ", ";\r
788 str += e.localTokenIdx.toString() + ", ";\r
789 str += e.guidTableIdx.toString();\r
790\r
791 str += "}" + " /* " + alComment.get(e) + " */" ;\r
792\r
793 if (index != al.size() - 1) {\r
794 str += ",";\r
795 }\r
796\r
797 Output.add(str);\r
798 bodyLineNum++;\r
799\r
800 }\r
801\r
802 Output.add("}");\r
803\r
804 return Output;\r
805 }\r
806\r
807 public int add (int localTokenIdx, long exTokenNum, int guidTableIdx, String name) {\r
808 int index = len;\r
809\r
810 len++;\r
811 ExTriplet et = new ExTriplet(guidTableIdx, exTokenNum, localTokenIdx);\r
812\r
813 al.add(et);\r
814 alComment.put(et, name);\r
815\r
816 return index;\r
817 }\r
818\r
819 private int getTableLen () {\r
820 return al.size() == 0 ? 1 : al.size();\r
821 }\r
822\r
823 //\r
824 // To simplify the algorithm for GetNextToken and GetNextTokenSpace in\r
825 // PCD PEIM/Driver, we need to sort the ExMapTable according to the\r
826 // following order:\r
827 // 1) ExGuid\r
828 // 2) ExTokenNumber\r
829 //\r
830 class ExTripletComp implements Comparator<ExTriplet> {\r
831 public int compare (ExTriplet a, ExTriplet b) {\r
832 if (a.guidTableIdx == b.guidTableIdx ) {\r
833 //\r
834 // exTokenNumber is long, we can't use simple substraction.\r
835 //\r
836 if (a.exTokenNumber > b.exTokenNumber) {\r
837 return 1;\r
838 } else if (a.exTokenNumber == b.exTokenNumber) {\r
839 return 0;\r
840 } else {\r
841 return -1;\r
842 }\r
843 }\r
844\r
845 return a.guidTableIdx - b.guidTableIdx;\r
846 }\r
847 }\r
848\r
849 private void sortTable () {\r
850 java.util.Comparator<ExTriplet> comparator = new ExTripletComp();\r
851 java.util.Collections.sort(al, comparator);\r
852 }\r
853}\r
854\r
855/**\r
856 PcdDatabase\r
857\r
858 This class is used to generate C code for Autogen.h and Autogen.c of\r
859 a PCD service DXE driver and PCD service PEIM.\r
860**/\r
861public class PcdDatabase {\r
862\r
863 private final static int SkuHeadAlignmentSize = 4;\r
864 private final String newLine = "\r\n";\r
865 private final String commaNewLine = ",\r\n";\r
866 private final String tab = "\t";\r
867 public final static String ExMapTableDeclaration = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";\r
868 public final static String GuidTableDeclaration = "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n";\r
869 public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";\r
870 public final static String StringTableDeclaration = "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n";\r
871 public final static String SizeTableDeclaration = "SIZE_INFO SizeTable[%s_SIZE_TABLE_SIZE];\r\n";\r
872 public final static String SkuIdTableDeclaration = "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";\r
873\r
874\r
875 public final static String ExMapTableSizeMacro = "#define %s_EXMAPPING_TABLE_SIZE %d\r\n";\r
876 public final static String ExTokenNumber = "#define %s_EX_TOKEN_NUMBER %d\r\n";\r
877 public final static String GuidTableSizeMacro = "#define %s_GUID_TABLE_SIZE %d\r\n";\r
878 public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE %d\r\n";\r
879 public final static String LocalTokenNumberSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n";\r
880 public final static String SizeTableSizeMacro = "#define %s_SIZE_TABLE_SIZE %d\r\n";\r
881 public final static String StringTableSizeMacro = "#define %s_STRING_TABLE_SIZE %d\r\n";\r
882 public final static String SkuIdTableSizeMacro = "#define %s_SKUID_TABLE_SIZE %d\r\n";\r
883\r
884\r
885 public final static String ExMapTableExistenceMacro = "#define %s_EXMAP_TABLE_EMPTY %s\r\n";\r
886 public final static String GuidTableExistenceMacro = "#define %s_GUID_TABLE_EMPTY %s\r\n";\r
887 public final static String DatabaseExistenceMacro = "#define %s_DATABASE_EMPTY %s\r\n";\r
888 public final static String StringTableExistenceMacro = "#define %s_STRING_TABLE_EMPTY %s\r\n";\r
889 public final static String SkuTableExistenceMacro = "#define %s_SKUID_TABLE_EMPTY %s\r\n";\r
890\r
891 public final static String offsetOfSkuHeadStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";\r
892 public final static String offsetOfVariableEnabledDefault = "offsetof(%s_PCD_DATABASE, %s.%s_VariableDefault_%d)";\r
893 public final static String offsetOfStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s)";\r
894\r
895 private final static String skuDataTableTemplate = "SkuDataTable";\r
896\r
897\r
898 private StringTable stringTable;\r
899 private GuidTable guidTable;\r
900 private LocalTokenNumberTable localTokenNumberTable;\r
901 private SkuIdTable skuIdTable;\r
902 private SizeTable sizeTable;\r
903 private ExMapTable exMapTable;\r
904\r
905 private ArrayList<Token> alTokens;\r
906 private String phase;\r
907 private int assignedTokenNumber;\r
908\r
909 //\r
910 // Use two class global variable to store\r
911 // temperary\r
912 //\r
913 private String privateGlobalName;\r
914 private String privateGlobalCCode;\r
915 //\r
916 // After Major changes done to the PCD\r
917 // database generation class PcdDatabase\r
918 // Please increment the version and please\r
919 // also update the version number in PCD\r
920 // service PEIM and DXE driver accordingly.\r
921 //\r
922 private final int version = 2;\r
923\r
924 private String hString;\r
925 private String cString;\r
926\r
927 /**\r
928 Constructor for PcdDatabase class.\r
929\r
930 <p>We have two PCD dynamic(ex) database for the Framework implementation. One\r
931 for PEI phase and the other for DXE phase. </p>\r
932\r
933 @param alTokens A ArrayList of Dynamic(EX) PCD entry.\r
934 @param exePhase The phase to generate PCD database for: valid input\r
935 is "PEI" or "DXE".\r
936 @param startLen The starting Local Token Number for the PCD database. For\r
937 PEI phase, the starting Local Token Number starts from 0.\r
938 For DXE phase, the starting Local Token Number starts\r
939 from the total number of PCD entry of PEI phase.\r
940 @return void\r
941 **/\r
942 public PcdDatabase (ArrayList<Token> alTokens, String exePhase, int startLen) {\r
943 phase = exePhase;\r
944\r
945 stringTable = new StringTable(phase);\r
946 guidTable = new GuidTable(phase);\r
947 localTokenNumberTable = new LocalTokenNumberTable(phase);\r
948 skuIdTable = new SkuIdTable(phase);\r
949 sizeTable = new SizeTable(phase);\r
950 exMapTable = new ExMapTable(phase);\r
951\r
952 //\r
953 // Local token number 0 is reserved for INVALID_TOKEN_NUMBER.\r
954 // So we will increment 1 for the startLen passed from the\r
955 // constructor.\r
956 //\r
957 assignedTokenNumber = startLen + 1;\r
958 this.alTokens = alTokens;\r
959 }\r
960\r
961 private void getNonExAndExTokens (ArrayList<Token> alTokens, List<Token> nexTokens, List<Token> exTokens) {\r
962 for (int i = 0; i < alTokens.size(); i++) {\r
963 Token t = (Token)alTokens.get(i);\r
964 if (t.isDynamicEx()) {\r
965 exTokens.add(t);\r
966 } else {\r
967 nexTokens.add(t);\r
968 }\r
969 }\r
970\r
971 return;\r
972 }\r
973\r
974 private int getDataTypeAlignmentSize (Token token) {\r
975 switch (token.datumType) {\r
976 case UINT8:\r
977 return 1;\r
978 case UINT16:\r
979 return 2;\r
980 case UINT32:\r
981 return 4;\r
982 case UINT64:\r
983 return 8;\r
984 case POINTER:\r
985 return 1;\r
986 case BOOLEAN:\r
987 return 1;\r
988 default:\r
989 return 1;\r
990 }\r
991 }\r
992\r
993 private int getHiiPtrTypeAlignmentSize(Token token) {\r
994 switch (token.datumType) {\r
995 case UINT8:\r
996 return 1;\r
997 case UINT16:\r
998 return 2;\r
999 case UINT32:\r
1000 return 4;\r
1001 case UINT64:\r
1002 return 8;\r
1003 case POINTER:\r
1004 if (token.isHiiEnable()) {\r
1005 if (token.isHiiDefaultValueUnicodeStringType()) {\r
1006 return 2;\r
1007 }\r
1008 }\r
1009 return 1;\r
1010 case BOOLEAN:\r
1011 return 1;\r
1012 default:\r
1013 return 1;\r
1014 }\r
1015 }\r
1016\r
1017 private int getAlignmentSize (Token token) {\r
1018 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {\r
1019 return 2;\r
1020 }\r
1021\r
1022 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {\r
1023 return 4;\r
1024 }\r
1025\r
1026 if (token.isUnicodeStringType()) {\r
1027 return 2;\r
1028 }\r
1029\r
1030 return getDataTypeAlignmentSize(token);\r
1031 }\r
1032\r
1033 public String getCString () {\r
1034 return cString;\r
1035 }\r
1036\r
1037 public String getHString () {\r
1038 return hString;\r
1039 }\r
1040\r
1041 private void genCodeWorker(Token t,\r
1042 ArrayList<CStructTypeDeclaration> declaList,\r
1043 HashMap<String, String> instTable, String phase)\r
1044 throws EntityException {\r
1045\r
1046 CStructTypeDeclaration decl;\r
1047\r
1048 //\r
1049 // Insert SKU_HEAD if isSkuEnable is true\r
1050 //\r
1051 if (t.isSkuEnable()) {\r
1052 int tableIdx;\r
1053 tableIdx = skuIdTable.add(t);\r
1054 decl = new CStructTypeDeclaration(t.getPrimaryKeyString(),\r
1055 SkuHeadAlignmentSize, getSkuEnabledTypeDeclaration(t), true);\r
1056 declaList.add(decl);\r
1057 instTable.put(t.getPrimaryKeyString(),\r
1058 getSkuEnabledTypeInstantiaion(t, tableIdx));\r
1059 }\r
1060\r
1061 //\r
1062 // Insert PCD_ENTRY declaration and instantiation\r
1063 //\r
1064 getCDeclarationString(t);\r
1065\r
1066 decl = new CStructTypeDeclaration(privateGlobalName,\r
1067 getAlignmentSize(t), privateGlobalCCode, t.hasDefaultValue());\r
1068 declaList.add(decl);\r
1069\r
1070 if (t.hasDefaultValue()) {\r
1071 instTable.put(privateGlobalName,\r
1072 getTypeInstantiation(t, declaList, instTable, phase)\r
1073 );\r
1074 }\r
1075\r
1076 }\r
1077\r
1078 private void ProcessTokens (List<Token> tokens,\r
1079 ArrayList<CStructTypeDeclaration> cStructDeclList,\r
1080 HashMap<String, String> cStructInstTable,\r
1081 String phase\r
1082 )\r
1083 throws EntityException {\r
1084\r
1085 for (int idx = 0; idx < tokens.size(); idx++) {\r
1086 Token t = tokens.get(idx);\r
1087\r
1088 genCodeWorker (t, cStructDeclList, cStructInstTable, phase);\r
1089\r
1090 sizeTable.add(t);\r
1091 localTokenNumberTable.add(t);\r
1092 t.tokenNumber = assignedTokenNumber++;\r
1093\r
1094 //\r
1095 // Add a mapping if this dynamic PCD entry is a EX type\r
1096 //\r
1097 if (t.isDynamicEx()) {\r
1098 exMapTable.add((int)t.tokenNumber,\r
1099 t.dynamicExTokenNumber,\r
1100 guidTable.add(translateSchemaStringToUUID(t.tokenSpaceName), t.getPrimaryKeyString()),\r
1101 t.getPrimaryKeyString()\r
1102 );\r
1103 }\r
1104 }\r
1105\r
1106 }\r
1107\r
1108 public void genCode () throws EntityException {\r
1109\r
1110 ArrayList<CStructTypeDeclaration> cStructDeclList = new ArrayList<CStructTypeDeclaration>();\r
1111 HashMap<String, String> cStructInstTable = new HashMap<String, String>();\r
1112\r
1113 List<Token> nexTokens = new ArrayList<Token> ();\r
1114 List<Token> exTokens = new ArrayList<Token> ();\r
1115\r
1116 getNonExAndExTokens (alTokens, nexTokens, exTokens);\r
1117\r
1118 //\r
1119 // We have to process Non-Ex type PCD entry first. The reason is\r
1120 // that our optimization assumes that the Token Number of Non-Ex\r
1121 // PCD entry start from 1 (for PEI phase) and grows continously upwards.\r
1122 //\r
1123 // EX type token number starts from the last Non-EX PCD entry and\r
1124 // grows continously upwards.\r
1125 //\r
1126 ProcessTokens (nexTokens, cStructDeclList, cStructInstTable, phase);\r
1127 ProcessTokens (exTokens, cStructDeclList, cStructInstTable, phase);\r
1128\r
1129 stringTable.genCode(cStructDeclList, cStructInstTable);\r
1130 skuIdTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1131 exMapTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1132 localTokenNumberTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1133 sizeTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1134 guidTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1135\r
1136 hString = genCMacroCode ();\r
1137\r
1138 HashMap <String, String> result;\r
1139\r
1140 result = genCStructCode(cStructDeclList,\r
1141 cStructInstTable,\r
1142 phase\r
1143 );\r
1144\r
1145 hString += result.get("initDeclStr");\r
1146 hString += result.get("uninitDeclStr");\r
1147\r
1148 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);\r
1149\r
1150 cString = newLine + newLine + result.get("initInstStr");\r
1151\r
1152 }\r
1153\r
1154 private String genCMacroCode () {\r
1155 String macroStr = "";\r
1156\r
1157 //\r
1158 // Generate size info Macro for all Tables\r
1159 //\r
1160 macroStr += guidTable.getSizeMacro();\r
1161 macroStr += stringTable.getSizeMacro();\r
1162 macroStr += skuIdTable.getSizeMacro();\r
1163 macroStr += localTokenNumberTable.getSizeMacro();\r
1164 macroStr += exMapTable.getSizeMacro();\r
1165 macroStr += sizeTable.getSizeMacro();\r
1166\r
1167 //\r
1168 // Generate existance info Macro for all Tables\r
1169 //\r
1170 macroStr += guidTable.getExistanceMacro();\r
1171 macroStr += stringTable.getExistanceMacro();\r
1172 macroStr += skuIdTable.getExistanceMacro();\r
1173 macroStr += localTokenNumberTable.getExistanceMacro();\r
1174 macroStr += exMapTable.getExistanceMacro();\r
1175\r
1176 macroStr += newLine;\r
1177\r
1178 return macroStr;\r
1179 }\r
1180\r
1181 private HashMap <String, String> genCStructCode(\r
1182 ArrayList<CStructTypeDeclaration> declaList,\r
1183 HashMap<String, String> instTable,\r
1184 String phase\r
1185 ) {\r
1186\r
1187 int i;\r
1188 HashMap <String, String> result = new HashMap<String, String>();\r
1189 HashMap <Integer, ArrayList<String>> alignmentInitDecl = new HashMap<Integer, ArrayList<String>>();\r
1190 HashMap <Integer, ArrayList<String>> alignmentUninitDecl = new HashMap<Integer, ArrayList<String>>();\r
1191 HashMap <Integer, ArrayList<String>> alignmentInitInst = new HashMap<Integer, ArrayList<String>>();\r
1192\r
1193 //\r
1194 // Initialize the storage for each alignment\r
1195 //\r
1196 for (i = 8; i > 0; i>>=1) {\r
1197 alignmentInitDecl.put(new Integer(i), new ArrayList<String>());\r
1198 alignmentInitInst.put(new Integer(i), new ArrayList<String>());\r
1199 alignmentUninitDecl.put(new Integer(i), new ArrayList<String>());\r
1200 }\r
1201\r
1202 String initDeclStr = "typedef struct {" + newLine;\r
1203 String initInstStr = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase()) + newLine;\r
1204 String uninitDeclStr = "typedef struct {" + newLine;\r
1205\r
1206 //\r
1207 // Sort all C declaration and instantiation base on Alignment Size\r
1208 //\r
1209 for (Object d : declaList) {\r
1210 CStructTypeDeclaration decl = (CStructTypeDeclaration) d;\r
1211\r
1212 if (decl.initTable) {\r
1213 alignmentInitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);\r
1214 alignmentInitInst.get(new Integer(decl.alignmentSize)).add(instTable.get(decl.key));\r
1215 } else {\r
1216 alignmentUninitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);\r
1217 }\r
1218 }\r
1219\r
1220 //\r
1221 // Generate code for every alignment size\r
1222 //\r
1223 boolean uinitDatabaseEmpty = true;\r
1224 for (int align = 8; align > 0; align >>= 1) {\r
1225 ArrayList<String> declaListBasedOnAlignment = alignmentInitDecl.get(new Integer(align));\r
1226 ArrayList<String> instListBasedOnAlignment = alignmentInitInst.get(new Integer(align));\r
1227 for (i = 0; i < declaListBasedOnAlignment.size(); i++) {\r
1228 initDeclStr += tab + declaListBasedOnAlignment.get(i);\r
1229 initInstStr += tab + instListBasedOnAlignment.get(i);\r
1230\r
1231 //\r
1232 // We made a assumption that both PEI_PCD_DATABASE and DXE_PCD_DATABASE\r
1233 // has a least one data memember with alignment size of 1. So we can\r
1234 // remove the last "," in the C structure instantiation string. Luckily,\r
1235 // this is true as both data structure has SKUID_TABLE anyway.\r
1236 //\r
1237 if ((align == 1) && (i == declaListBasedOnAlignment.size() - 1)) {\r
1238 initInstStr += newLine;\r
1239 } else {\r
1240 initInstStr += commaNewLine;\r
1241 }\r
1242 }\r
1243\r
1244 declaListBasedOnAlignment = alignmentUninitDecl.get(new Integer(align));\r
1245\r
1246 if (declaListBasedOnAlignment.size() != 0) {\r
1247 uinitDatabaseEmpty = false;\r
1248 }\r
1249\r
1250 for (Object d : declaListBasedOnAlignment) {\r
1251 String s = (String)d;\r
1252 uninitDeclStr += tab + s;\r
1253 }\r
1254 }\r
1255\r
1256 if (uinitDatabaseEmpty) {\r
1257 uninitDeclStr += tab + String.format("%-20sdummy; /* PCD_DATABASE_UNINIT is emptry */\r\n", "UINT8");\r
1258 }\r
1259\r
1260 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;", phase) + newLine + newLine;\r
1261 initInstStr += "};" + newLine;\r
1262 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;", phase) + newLine + newLine;\r
1263\r
1264 result.put("initDeclStr", initDeclStr);\r
1265 result.put("initInstStr", initInstStr);\r
1266 result.put("uninitDeclStr", uninitDeclStr);\r
1267\r
1268 return result;\r
1269 }\r
1270\r
1271 public static String genInstantiationStr (ArrayList<String> alStr) {\r
1272 String str = "";\r
1273 for (int i = 0; i< alStr.size(); i++) {\r
1274 if (i != 0) {\r
1275 str += "\t";\r
1276 }\r
1277 str += alStr.get(i);\r
1278 if (i != alStr.size() - 1) {\r
1279 str += "\r\n";\r
1280 }\r
1281 }\r
1282\r
1283 return str;\r
1284 }\r
1285\r
1286 private String getSkuEnabledTypeDeclaration (Token token) {\r
1287 return String.format("%-20s%s;\r\n", "SKU_HEAD", token.getPrimaryKeyString());\r
1288 }\r
1289\r
1290 private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {\r
1291\r
1292 String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());\r
1293 return String.format("{ %s, %d } /* SKU_ENABLED: %s */", offsetof, SkuTableIdx, token.getPrimaryKeyString());\r
1294 }\r
1295\r
1296 private String getDataTypeInstantiationForVariableDefault (Token token, String cName, int skuId) {\r
1297 return String.format("%s /* %s */", token.skuData.get(skuId).value.hiiDefaultValue, cName);\r
1298 }\r
1299\r
1300 private String getCType (Token t)\r
1301 throws EntityException {\r
1302\r
1303 if (t.isHiiEnable()) {\r
1304 return "VARIABLE_HEAD";\r
1305 }\r
1306\r
1307 if (t.isVpdEnable()) {\r
1308 return "VPD_HEAD";\r
1309 }\r
1310\r
1311 if (t.isUnicodeStringType()) {\r
1312 return "STRING_HEAD";\r
1313 }\r
1314\r
1315 switch (t.datumType) {\r
1316 case UINT64:\r
1317 return "UINT64";\r
1318 case UINT32:\r
1319 return "UINT32";\r
1320 case UINT16:\r
1321 return "UINT16";\r
1322 case UINT8:\r
1323 return "UINT8";\r
1324 case BOOLEAN:\r
1325 return "BOOLEAN";\r
1326 case POINTER:\r
1327 return "UINT8";\r
1328 default:\r
1329 throw new EntityException("Unknown DatumType in getDataTypeCDeclaration");\r
1330 }\r
1331 }\r
1332\r
1333 //\r
1334 // privateGlobalName and privateGlobalCCode is used to pass output to caller of getCDeclarationString\r
1335 //\r
1336 private void getCDeclarationString(Token t)\r
1337 throws EntityException {\r
1338\r
1339 if (t.isSkuEnable()) {\r
1340 privateGlobalName = String.format("%s_%s", t.getPrimaryKeyString(), skuDataTableTemplate);\r
1341 } else {\r
1342 privateGlobalName = t.getPrimaryKeyString();\r
1343 }\r
1344\r
1345 String type = getCType(t);\r
1346 if ((t.datumType == Token.DATUM_TYPE.POINTER) && (!t.isHiiEnable()) && (!t.isUnicodeStringType())) {\r
1347 int bufferSize;\r
1348 if (t.isASCIIStringType()) {\r
1349 //\r
1350 // Build tool will add a NULL string at the end of the ASCII string\r
1351 //\r
1352 bufferSize = t.datumSize + 1;\r
1353 } else {\r
1354 bufferSize = t.datumSize;\r
1355 }\r
1356 privateGlobalCCode = String.format("%-20s%s[%d][%d];\r\n", type, privateGlobalName, t.getSkuIdCount(), bufferSize);\r
1357 } else {\r
1358 privateGlobalCCode = String.format("%-20s%s[%d];\r\n", type, privateGlobalName, t.getSkuIdCount());\r
1359 }\r
1360 }\r
1361\r
1362 private String getDataTypeDeclarationForVariableDefault (Token token, String cName, int skuId)\r
1363 throws EntityException {\r
1364\r
1365 String typeStr;\r
1366\r
1367 if (token.datumType == Token.DATUM_TYPE.UINT8) {\r
1368 typeStr = "UINT8";\r
1369 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {\r
1370 typeStr = "UINT16";\r
1371 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {\r
1372 typeStr = "UINT32";\r
1373 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {\r
1374 typeStr = "UINT64";\r
1375 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {\r
1376 typeStr = "BOOLEAN";\r
1377 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {\r
1378 int size;\r
1379 if (token.isHiiDefaultValueUnicodeStringType()) {\r
1380 typeStr = "UINT16";\r
1381 //\r
1382 // Include the NULL charactor\r
1383 //\r
1384 size = token.datumSize / 2 + 1;\r
1385 } else {\r
1386 typeStr = "UINT8";\r
1387 if (token.isHiiDefaultValueASCIIStringType()) {\r
1388 //\r
1389 // Include the NULL charactor\r
1390 //\r
1391 size = token.datumSize + 1;\r
1392 } else {\r
1393 size = token.datumSize;\r
1394 }\r
1395 }\r
1396 return String.format("%-20s%s[%d];\r\n", typeStr, cName, size);\r
1397 } else {\r
1398 throw new EntityException("Unknown DATUM_TYPE type in when generating code for VARIABLE_ENABLED PCD entry");\r
1399 }\r
1400\r
1401 return String.format("%-20s%s;\r\n", typeStr, cName);\r
1402 }\r
1403\r
1404 private String getTypeInstantiation (Token t, ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) throws EntityException {\r
1405\r
1406 int i;\r
1407\r
1408 String s;\r
1409 s = String.format("/* %s */", t.getPrimaryKeyString()) + newLine;\r
1410 s += tab + "{" + newLine;\r
1411\r
1412 for (i = 0; i < t.skuData.size(); i++) {\r
1413 if (t.isUnicodeStringType()) {\r
1414 s += tab + tab + String.format("{ %d }", stringTable.add(t.skuData.get(i).value.value, t));\r
1415 } else if (t.isHiiEnable()) {\r
1416 /* VPD_HEAD definition\r
1417 typedef struct {\r
1418 UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.\r
1419 UINT16 StringIndex; // Offset in String Table in units of UINT16.\r
1420 UINT16 Offset; // Offset in Variable\r
1421 UINT16 DefaultValueOffset; // Offset of the Default Value\r
1422 } VARIABLE_HEAD ;\r
1423 */\r
1424 String variableDefaultName = String.format("%s_VariableDefault_%d", t.getPrimaryKeyString(), i);\r
1425\r
1426 s += tab + tab + String.format("{ %d, %d, %s, %s }", guidTable.add(t.skuData.get(i).value.variableGuid, t.getPrimaryKeyString()),\r
1427 stringTable.add(t.skuData.get(i).value.getStringOfVariableName(), t),\r
1428 t.skuData.get(i).value.variableOffset,\r
1429 String.format("offsetof(%s_PCD_DATABASE, Init.%s)", phase, variableDefaultName)\r
1430 );\r
1431 //\r
1432 // We need to support the default value, so we add the declaration and\r
1433 // the instantiation for the default value.\r
1434 //\r
1435 CStructTypeDeclaration decl = new CStructTypeDeclaration (variableDefaultName,\r
1436 getHiiPtrTypeAlignmentSize(t),\r
1437 getDataTypeDeclarationForVariableDefault(t, variableDefaultName, i),\r
1438 true\r
1439 );\r
1440 declaList.add(decl);\r
1441 instTable.put(variableDefaultName, getDataTypeInstantiationForVariableDefault (t, variableDefaultName, i));\r
1442 } else if (t.isVpdEnable()) {\r
1443 /* typedef struct {\r
1444 UINT32 Offset;\r
1445 } VPD_HEAD;\r
1446 */\r
1447 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.vpdOffset);\r
1448 } else {\r
1449 if (t.isByteStreamType()) {\r
1450 //\r
1451 // Byte stream type input has their own "{" "}", so we won't help to insert.\r
1452 //\r
1453 s += tab + tab + String.format(" %s ", t.skuData.get(i).value.value);\r
1454 } else {\r
1455 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.value);\r
1456 }\r
1457 }\r
1458\r
1459 if (i != t.skuData.size() - 1) {\r
1460 s += commaNewLine;\r
1461 } else {\r
1462 s += newLine;\r
1463 }\r
1464\r
1465 }\r
1466\r
1467 s += tab + "}";\r
1468\r
1469 return s;\r
1470 }\r
1471\r
1472 public static String getPcdDatabaseCommonDefinitions ()\r
1473 throws EntityException {\r
1474\r
1475 String retStr = "";\r
1476 try {\r
1477 File file = new File(GlobalData.getWorkspacePath() + File.separator +\r
1478 "Tools" + File.separator +\r
1479 "Conf" + File.separator +\r
1480 "Pcd" + File.separator +\r
1481 "PcdDatabaseCommonDefinitions.sample");\r
1482 FileReader reader = new FileReader(file);\r
1483 BufferedReader in = new BufferedReader(reader);\r
1484 String str;\r
1485 while ((str = in.readLine()) != null) {\r
1486 retStr = retStr +"\r\n" + str;\r
1487 }\r
1488 } catch (Exception ex) {\r
1489 throw new EntityException("Fatal error when generating PcdDatabase Common Definitions!");\r
1490 }\r
1491\r
1492 return retStr;\r
1493 }\r
1494\r
1495 public static String getPcdDxeDatabaseDefinitions ()\r
1496 throws EntityException {\r
1497\r
1498 String retStr = "";\r
1499 try {\r
1500 File file = new File(GlobalData.getWorkspacePath() + File.separator +\r
1501 "Tools" + File.separator +\r
1502 "Conf" + File.separator +\r
1503 "Pcd" + File.separator +\r
1504 "PcdDatabaseDxeDefinitions.sample");\r
1505 FileReader reader = new FileReader(file);\r
1506 BufferedReader in = new BufferedReader(reader);\r
1507 String str;\r
1508 while ((str = in.readLine()) != null) {\r
1509 retStr = retStr +"\r\n" + str;\r
1510 }\r
1511 } catch (Exception ex) {\r
1512 throw new EntityException("Fatal error when generating PcdDatabase Dxe Definitions!");\r
1513 }\r
1514\r
1515 return retStr;\r
1516 }\r
1517\r
1518 public static String getPcdPeiDatabaseDefinitions ()\r
1519 throws EntityException {\r
1520\r
1521 String retStr = "";\r
1522 try {\r
1523 File file = new File(GlobalData.getWorkspacePath() + File.separator +\r
1524 "Tools" + File.separator +\r
1525 "Conf" + File.separator +\r
1526 "Pcd" + File.separator +\r
1527 "PcdDatabasePeiDefinitions.sample");\r
1528 FileReader reader = new FileReader(file);\r
1529 BufferedReader in = new BufferedReader(reader);\r
1530 String str;\r
1531 while ((str = in.readLine()) != null) {\r
1532 retStr = retStr +"\r\n" + str;\r
1533 }\r
1534 } catch (Exception ex) {\r
1535 throw new EntityException("Fatal error when generating PcdDatabase Pei Definitions!");\r
1536 }\r
1537\r
1538 return retStr;\r
1539 }\r
1540\r
1541 /**\r
1542 Translate the schema string to UUID instance.\r
1543\r
1544 In schema, the string of UUID is defined as following two types string:\r
1545 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(\r
1546 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?\r
1547\r
1548 2) GuidNamingConvention: pattern =\r
1549 [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\r
1550\r
1551 This function will convert string and create uuid instance.\r
1552\r
1553 @param uuidString UUID string in XML file\r
1554\r
1555 @return UUID UUID instance\r
1556 **/\r
1557 private UUID translateSchemaStringToUUID(String uuidString)\r
1558 throws EntityException {\r
1559 String temp;\r
1560 String[] splitStringArray;\r
1561 int index;\r
1562 int chIndex;\r
1563 int chLen;\r
1564\r
1565 if (uuidString == null) {\r
1566 return null;\r
1567 }\r
1568\r
1569 if (uuidString.length() == 0) {\r
1570 return null;\r
1571 }\r
1572\r
1573 if (uuidString.equals("0") ||\r
1574 uuidString.equalsIgnoreCase("0x0")) {\r
1575 return new UUID(0, 0);\r
1576 }\r
1577\r
1578 uuidString = uuidString.replaceAll("\\{", "");\r
1579 uuidString = uuidString.replaceAll("\\}", "");\r
1580\r
1581 //\r
1582 // If the UUID schema string is GuidArrayType type then need translate\r
1583 // to GuidNamingConvention type at first.\r
1584 //\r
1585 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {\r
1586 splitStringArray = uuidString.split("," );\r
1587 if (splitStringArray.length != 11) {\r
1588 throw new EntityException ("[FPD file error] Wrong format for GUID string: " + uuidString);\r
1589 }\r
1590\r
1591 //\r
1592 // Remove blank space from these string and remove header string "0x"\r
1593 //\r
1594 for (index = 0; index < 11; index ++) {\r
1595 splitStringArray[index] = splitStringArray[index].trim();\r
1596 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());\r
1597 }\r
1598\r
1599 //\r
1600 // Add heading '0' to normalize the string length\r
1601 //\r
1602 for (index = 3; index < 11; index ++) {\r
1603 chLen = splitStringArray[index].length();\r
1604 for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {\r
1605 splitStringArray[index] = "0" + splitStringArray[index];\r
1606 }\r
1607 }\r
1608\r
1609 //\r
1610 // construct the final GuidNamingConvention string\r
1611 //\r
1612 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",\r
1613 splitStringArray[0],\r
1614 splitStringArray[1],\r
1615 splitStringArray[2],\r
1616 splitStringArray[3],\r
1617 splitStringArray[4],\r
1618 splitStringArray[5],\r
1619 splitStringArray[6],\r
1620 splitStringArray[7],\r
1621 splitStringArray[8],\r
1622 splitStringArray[9],\r
1623 splitStringArray[10]);\r
1624 uuidString = temp;\r
1625 }\r
1626\r
1627 return UUID.fromString(uuidString);\r
1628 }\r
1629}\r