1# Copyright 2014 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""A code generator for TPM 2.0 commands. 6 7The command generator takes as input a list of command objects generated by 8parsing the TCG specification and outputs valid C code to marshal command 9input and output structures, and also generates functions ParseHandleBuffer 10and CommandDispatcher defined by the TCG TPM2.0 Library Specification. 11 12""" 13 14from __future__ import print_function 15 16import re 17from subprocess import call 18 19from structure_generator import COPYRIGHT_HEADER 20from structure_generator import Field 21 22_HEADER_FILE_GUARD_HEADER = """ 23#ifndef TPM2_%(name)s_FP_H_ 24#define TPM2_%(name)s_FP_H_ 25""" 26_HEADER_FILE_GUARD_FOOTER = """ 27#endif // TPM2_%(name)s_FP_H 28""" 29_HEADER_FILE_INCLUDES = """ 30#include "tpm_generated.h" 31""" 32_IMPLEMENTATION_FILE_INCLUDES = """ 33#include "MemoryLib_fp.h" 34#include "%(command_name)s_fp.h" 35""" 36_COMMAND_DISPATCHER_INCLUDES = '#include "%(command_name)s_fp.h"\n' 37_COMMAND_DISPATCHER_START = """ 38#include "Implementation.h" 39#include "CommandDispatcher_fp.h" 40 41TPM_RC CommandDispatcher( 42 TPMI_ST_COMMAND_TAG tag, 43 TPM_CC command_code, 44 INT32 *request_parameter_buffer_size, 45 BYTE *request_parameter_buffer_start, 46 TPM_HANDLE request_handles[], 47 UINT32 *response_handle_buffer_size, 48 UINT32 *response_parameter_buffer_size) { 49 BYTE *request_parameter_buffer = request_parameter_buffer_start; 50 switch(command_code) {""" 51_COMMAND_DISPATCHER_CASE = """ 52#ifdef %(command_code)s 53 case %(command_code)s: 54 return Exec_%(command_name)s(tag, &request_parameter_buffer, 55 request_parameter_buffer_size, request_handles, 56 response_handle_buffer_size, response_parameter_buffer_size); 57#endif""" 58_COMMAND_DISPATCHER_END = """ 59 default: 60 return TPM_RC_COMMAND_CODE; 61 } 62}""" 63_HANDLE_PROCESS_START = """ 64#include "tpm_generated.h" 65#include "HandleProcess_fp.h" 66#include "Implementation.h" 67#include "TPM_Types.h" 68 69TPM_RC ParseHandleBuffer( 70 TPM_CC command_code, 71 BYTE **request_handle_buffer_start, 72 INT32 *request_buffer_remaining_size, 73 TPM_HANDLE request_handles[], 74 UINT32 *num_request_handles) { 75 TPM_RC result = TPM_RC_SUCCESS; 76 *num_request_handles = 0; 77 switch(command_code) { 78""" 79_HANDLE_PROCESS_CASE_START = """ 80#ifdef %(command_code)s 81 case %(command_code)s:""" 82_HANDLE_PROCESS_CASE_UNMARSHAL = """ 83 result = %(handle_type)s_Unmarshal( 84 (%(handle_type)s*)&request_handles[*num_request_handles], 85 request_handle_buffer_start, 86 request_buffer_remaining_size);""" 87_HANDLE_PROCESS_CASE_UNMARSHAL_FLAG = """ 88 result = %(handle_type)s_Unmarshal( 89 (%(handle_type)s*)&request_handles[*num_request_handles], 90 request_handle_buffer_start, 91 request_buffer_remaining_size, 92 %(flag_val)s);""" 93_HANDLE_PROCESS_CASE_CHECK = """ 94 if (result != TPM_RC_SUCCESS) { 95 return result; 96 } 97 ++(*num_request_handles);""" 98_HANDLE_PROCESS_CASE_END = """ 99 return TPM_RC_SUCCESS; 100#endif""" 101_HANDLE_PROCESS_END = """ 102 default: 103 return TPM_RC_COMMAND_CODE; 104 } 105}""" 106_GET_COMMAND_CODE_STRING_HEADER = """ 107#ifndef TPM2_GET_COMMAND_CODE_STRING_FP_H_ 108#define TPM2_GET_COMMAND_CODE_STRING_FP_H_ 109 110#include "TPM_Types.h" 111 112const char* GetCommandCodeString(TPM_CC command_code); 113 114#endif // TPM2_GET_COMMAND_CODE_STRING_FP_H_""" 115_GET_COMMAND_CODE_STRING_START = """ 116#include "GetCommandCodeString_fp.h" 117 118const char* GetCommandCodeString(TPM_CC command_code) { 119 switch(command_code) {""" 120_GET_COMMAND_CODE_STRING_CASE = """ 121#ifdef TPM_CC_%(command_name)s 122 case TPM_CC_%(command_name)s: 123 return "%(command_name)s"; 124#endif""" 125_GET_COMMAND_CODE_STRING_END = """ 126 default: 127 return "Unknown command"; 128 } 129}""" 130 131 132class Command(object): 133 """Represents a TPM command. 134 135 Attributes: 136 name: The command name (e.g. 'TPM2_Startup'). 137 command_code: The name of the command code constant (e.g. TPM2_CC_Startup). 138 request_args: A list to hold command input arguments. Each element is a dict 139 and has these keys: 140 'type': The argument type. 141 'name': The argument name. 142 'command_code': The optional value of the command code constant. 143 'description': Optional descriptive text for the argument. 144 'has_conditional': String literal 'TRUE' or 'FALSE' indicating 145 whether 'type' is allowed to have a conditional value. 146 response_args: A list identical in form to request_args but to hold command 147 output arguments. 148 """ 149 150 _HANDLE_RE = re.compile(r'TPMI_.H_.*') 151 _STRUCT_DECL_START = """ 152typedef struct {""" 153 _STRUCT_DECL_FIELD = """ 154 %(type)s %(name)s;""" 155 _STRUCT_DECL_END = """ 156} %(command_name)s_%(direction)s; 157""" 158 _FUNCTION_DECL_IN_OUT = """ 159// Executes %(command_name)s with request handles and parameters from 160// |in| and computes response handles and parameters to |out|. 161TPM_RC TPM2_%(command_name)s( 162 %(command_name)s_In *in, 163 %(command_name)s_Out *out); 164 165// Initializes handle fields in |target| from |request_handles|. Unmarshals 166// parameter fields in |target| from |buffer|. 167TPM_RC %(command_name)s_In_Unmarshal( 168 %(command_name)s_In *target, 169 TPM_HANDLE request_handles[], 170 BYTE **buffer, 171 INT32 *size); 172 173// Marshals response handles and parameters from |source| to |buffer|. Computes 174// and marshals the size of the parameter area (parameter_size) if |tag| == 175// TPM_ST_SESSIONS. Returns size of (parameter area + handle area) in bytes. 176// Return value does not include parameter_size field. 177UINT16 %(command_name)s_Out_Marshal( 178 %(command_name)s_Out *source, 179 TPMI_ST_COMMAND_TAG tag, 180 BYTE **buffer, 181 INT32 *size); 182""" 183 _FUNCTION_DECL_IN = """ 184// Executes %(command_name)s with request handles and parameters from |in|. 185TPM_RC TPM2_%(command_name)s( 186 %(command_name)s_In *in); 187 188// Initializes handle fields in |target| from |request_handles|. Unmarshals 189// parameter fields in |target| from |buffer|. 190TPM_RC %(command_name)s_In_Unmarshal( 191 %(command_name)s_In *target, 192 TPM_HANDLE request_handles[], 193 BYTE **buffer, 194 INT32 *size); 195""" 196 _FUNCTION_DECL_OUT = """ 197// Executes %(command_name)s and computes response handles and parameters 198// to |out|. 199TPM_RC TPM2_%(command_name)s( 200 %(command_name)s_Out *out); 201 202// Marshals response handles and parameters from |source| to |buffer|. Computes 203// and marshals the size of the parameter area (parameter_size) if |tag| == 204// TPM_ST_SESSIONS. Returns size of (parameter area + handle area) in bytes. 205// Does not include parameter_size field. 206UINT16 %(command_name)s_Out_Marshal( 207 %(command_name)s_Out *source, 208 TPMI_ST_COMMAND_TAG tag, 209 BYTE **buffer, 210 INT32 *size); 211""" 212 _EXEC_DECL = """ 213// Unmarshals any request parameters starting at |request_parameter_buffer|. 214// Executes command. Marshals any response handles and parameters to the 215// global response buffer and computes |*response_handle_buffer_size| and 216// |*response_parameter_buffer_size|. If |tag| == TPM_ST_SESSIONS, marshals 217// parameter_size indicating the size of the parameter area. parameter_size 218// field is located between the handle area and parameter area. 219TPM_RC Exec_%(command_name)s( 220 TPMI_ST_COMMAND_TAG tag, 221 BYTE **request_parameter_buffer, 222 INT32 *request_parameter_buffer_size, 223 TPM_HANDLE request_handles[], 224 UINT32 *response_handle_buffer_size, 225 UINT32 *response_parameter_buffer_size); 226""" 227 _EXEC_COMMAND_IMPL_START = """ 228TPM_RC Exec_%(command_name)s( 229 TPMI_ST_COMMAND_TAG tag, 230 BYTE **request_parameter_buffer, 231 INT32 *request_parameter_buffer_size, 232 TPM_HANDLE request_handles[], 233 UINT32 *response_handle_buffer_size, 234 UINT32 *response_parameter_buffer_size) { 235 TPM_RC result = TPM_RC_SUCCESS;""" 236 _EXEC_COMMAND_IMPL_IN_OUT = """ 237 %(command_name)s_In in; 238 %(command_name)s_Out out; 239#ifdef %(command_code)s 240 BYTE *response_buffer; 241 INT32 response_buffer_size; 242 UINT16 bytes_marshalled; 243 UINT16 num_response_handles = %(num_response_handles)s; 244#endif 245 *response_handle_buffer_size = 0; 246 *response_parameter_buffer_size = 0; 247 // Unmarshal request parameters to input structure. 248 result = %(command_name)s_In_Unmarshal(&in, request_handles, 249 request_parameter_buffer, request_parameter_buffer_size); 250 if (result != TPM_RC_SUCCESS) { 251 return result; 252 } 253 // Execute command. 254 result = TPM2_%(command_name)s(&in, &out); 255 if (result != TPM_RC_SUCCESS) { 256 return result; 257 } 258 // Marshal output structure to global response buffer. 259#ifdef %(command_code)s 260 response_buffer = MemoryGetResponseBuffer(%(command_code)s) + 10; 261 response_buffer_size = MAX_RESPONSE_SIZE - 10; 262 bytes_marshalled = %(command_name)s_Out_Marshal( 263 &out, tag, &response_buffer, &response_buffer_size); 264 *response_handle_buffer_size = num_response_handles*sizeof(TPM_HANDLE); 265 *response_parameter_buffer_size = 266 bytes_marshalled - *response_handle_buffer_size; 267 return TPM_RC_SUCCESS; 268#endif 269 return TPM_RC_COMMAND_CODE; 270} 271""" 272 _EXEC_COMMAND_IMPL_IN = """ 273 %(command_name)s_In in; 274#ifdef %(command_code)s 275 BYTE *response_buffer; 276 INT32 response_buffer_size; 277#endif 278 *response_handle_buffer_size = 0; 279 *response_parameter_buffer_size = 0; 280 // Unmarshal request parameters to input structure. 281 result = %(command_name)s_In_Unmarshal(&in, request_handles, 282 request_parameter_buffer, request_parameter_buffer_size); 283 if (result != TPM_RC_SUCCESS) { 284 return result; 285 } 286 // Execute command. 287 result = TPM2_%(command_name)s(&in); 288 if (result != TPM_RC_SUCCESS) { 289 return result; 290 } 291#ifdef %(command_code)s 292 response_buffer = MemoryGetResponseBuffer(%(command_code)s) + 10; 293 response_buffer_size = MAX_RESPONSE_SIZE - 10; 294 // Add parameter_size field, always equal to 0 here. 295 if (tag == TPM_ST_SESSIONS) { 296 UINT32_Marshal(response_parameter_buffer_size, &response_buffer, 297 &response_buffer_size); 298 } 299 return TPM_RC_SUCCESS; 300#endif 301 return TPM_RC_COMMAND_CODE; 302} 303""" 304 _EXEC_COMMAND_IMPL_OUT = """ 305 %(command_name)s_Out out; 306#ifdef %(command_code)s 307 BYTE *response_buffer; 308 INT32 response_buffer_size; 309 UINT16 bytes_marshalled; 310 UINT16 num_response_handles = %(num_response_handles)s; 311#endif 312 *response_handle_buffer_size = 0; 313 *response_parameter_buffer_size = 0; 314 // Execute command. 315 result = TPM2_%(command_name)s(&out); 316 if (result != TPM_RC_SUCCESS) { 317 return result; 318 } 319 // Marshal output structure containing response handles and parameters to 320 // response buffer. 321#ifdef %(command_code)s 322 response_buffer = MemoryGetResponseBuffer(%(command_code)s) + 10; 323 response_buffer_size = MAX_RESPONSE_SIZE - 10; 324 bytes_marshalled = %(command_name)s_Out_Marshal( 325 &out, tag, &response_buffer, &response_buffer_size); 326 *response_handle_buffer_size = num_response_handles*sizeof(TPM_HANDLE); 327 *response_parameter_buffer_size = 328 bytes_marshalled - *response_handle_buffer_size; 329 return TPM_RC_SUCCESS; 330#endif 331 return TPM_RC_COMMAND_CODE; 332} 333""" 334 _UNMARSHAL_COMMAND_START = """ 335TPM_RC %(command_name)s_In_Unmarshal( 336 %(command_name)s_In *target, 337 TPM_HANDLE request_handles[], 338 BYTE **buffer, 339 INT32 *size) { 340 TPM_RC result = TPM_RC_SUCCESS;""" 341 _MARSHAL_COMMAND_START = """ 342UINT16 %(command_name)s_Out_Marshal( 343 %(command_name)s_Out *source, 344 TPMI_ST_COMMAND_TAG tag, 345 BYTE **buffer, 346 INT32 *size) { 347 UINT16 total_size = 0; 348 UINT32 parameter_size = 0; 349 BYTE *parameter_size_location; 350 INT32 parameter_size_size = sizeof(UINT32); 351 UINT32 num_response_handles = %(num_response_handles)s;""" 352 _UNMARSHAL_END = """ 353 if ((result == TPM_RC_SUCCESS) && *size) { 354 result = TPM_RC_SIZE; 355 } 356 return result; 357} 358""" 359 _MARSHAL_END = """ 360 // Compute actual parameter_size. Don't add result to total_size. 361 if (tag == TPM_ST_SESSIONS) { 362 parameter_size = total_size - num_response_handles*sizeof(TPM_HANDLE); 363 UINT32_Marshal( 364 ¶meter_size, ¶meter_size_location, ¶meter_size_size); 365 } 366 return total_size; 367} 368""" 369 _SET_COMMAND_HANDLE = """ 370 target->%(field_name)s = request_handles[%(num)s];""" 371 _PARAMETERSIZE_CHECK = """ 372 // Add parameter_size=0 to indicate size of the parameter area. Will be 373 // replaced later by computed parameter_size. 374 if (tag == TPM_ST_SESSIONS) { 375 parameter_size_location = *buffer; 376 // Don't add to total_size, but increment *buffer and decrement *size. 377 UINT32_Marshal(¶meter_size, buffer, size); 378 }""" 379 380 def __init__(self, name): 381 """Initializes a Command instance. 382 383 Initially the request_args and response_args attributes are not set. 384 385 Args: 386 name: The command name (e.g. 'TPM2_Startup'). 387 """ 388 self.name = name 389 self.request_args = None 390 self.response_args = None 391 if name.startswith('TPM2_'): 392 self.command_code = name.replace('TPM2_', 'TPM_CC_') 393 else: 394 self.command_code = '' 395 396 def __str__(self): 397 s = ['%s:' % self.name,] 398 if self.request_args: 399 s.append(' req:') 400 for r in self.request_args: 401 s.append(' %s: %s' % (r['type'], r['name'])) 402 if self.response_args: 403 s.append(' resp:') 404 for r in self.response_args: 405 s.append(' %s: %s' % (r['type'], r['name'])) 406 s.append('') 407 return '\n'.join(s) 408 409 def OutputMarshalFunction(self, out_file, typemap): 410 """Generates a marshal function for the command output structure. 411 412 Args: 413 out_file: File to be written to opened by the caller. 414 typemap: A dict mapping type names to the corresponding object. 415 Generated by structure_generator. 416 """ 417 if not self.response_args: 418 return 419 # Categorize arguments as either handles or parameters. 420 handles, parameters = self._SplitArgs(self.response_args) 421 out_file.write(self._MARSHAL_COMMAND_START % { 422 'command_name': self.MethodName(), 423 'num_response_handles': self._GetNumberOfResponseHandles()}) 424 if handles: 425 out_file.write('\n // Marshal response handles.') 426 for handle in handles: 427 typemap[handle['type']].OutputMarshalCall( 428 out_file, Field(handle['type'], 429 handle['name'], 430 conditional_value=handle['has_conditional'])) 431 out_file.write(self._PARAMETERSIZE_CHECK) 432 if parameters: 433 out_file.write('\n // Marshal response parameters.') 434 for parameter in parameters: 435 typemap[parameter['type']].OutputMarshalCall( 436 out_file, Field(parameter['type'], parameter['name'], 437 conditional_value=parameter['has_conditional'])) 438 out_file.write(self._MARSHAL_END) 439 440 def OutputUnmarshalFunction(self, out_file, typemap): 441 """Generates a unmarshal function for the command input structure. 442 443 Args: 444 out_file: File to be written to opened by the caller. 445 typemap: A dict mapping type names to the corresponding object. 446 Generated by structure_generator. 447 """ 448 if not self.request_args: 449 return 450 # Categorize arguments as either handles or parameters. 451 handles, parameters = self._SplitArgs(self.request_args) 452 out_file.write(self._UNMARSHAL_COMMAND_START % { 453 'command_name': self.MethodName()}) 454 if handles: 455 out_file.write('\n // Get request handles from request_handles array.') 456 for index, handle in enumerate(handles): 457 out_file.write(self._SET_COMMAND_HANDLE % {'field_name': handle['name'], 458 'num': index}) 459 if parameters: 460 out_file.write('\n // Unmarshal request parameters.') 461 for parameter in parameters: 462 typemap[parameter['type']].OutputUnmarshalCall( 463 out_file, Field(parameter['type'], 464 parameter['name'], 465 conditional_value=parameter['has_conditional'])) 466 out_file.write(self._UNMARSHAL_END) 467 468 def OutputExecFunction(self, out_file): 469 """Generates an exec function for the command. 470 471 Args: 472 out_file: File to be written to opened by the caller. 473 """ 474 out_file.write( 475 self._EXEC_COMMAND_IMPL_START % {'command_name': self.MethodName()}) 476 if self.request_args and self.response_args: 477 out_file.write(self._EXEC_COMMAND_IMPL_IN_OUT % { 478 'command_name': self.MethodName(), 479 'command_code': self.command_code, 480 'num_response_handles': self._GetNumberOfResponseHandles()}) 481 elif self.request_args: 482 out_file.write(self._EXEC_COMMAND_IMPL_IN % { 483 'command_name': self.MethodName(), 484 'command_code': self.command_code}) 485 elif self.response_args: 486 out_file.write(self._EXEC_COMMAND_IMPL_OUT % { 487 'command_name': self.MethodName(), 488 'command_code': self.command_code, 489 'num_response_handles': self._GetNumberOfResponseHandles()}) 490 491 def OutputDecl(self, out_file): 492 """Generates a TPM object declaration.""" 493 if self.request_args: 494 out_file.write(self._STRUCT_DECL_START) 495 for arg in self.request_args: 496 out_file.write(self._STRUCT_DECL_FIELD % {'type': arg['type'], 497 'name': arg['name']}) 498 out_file.write(self._STRUCT_DECL_END % {'command_name': self.MethodName(), 499 'direction': 'In'}) 500 if self.response_args: 501 out_file.write(self._STRUCT_DECL_START) 502 for arg in self.response_args: 503 out_file.write(self._STRUCT_DECL_FIELD % {'type': arg['type'], 504 'name': arg['name']}) 505 out_file.write(self._STRUCT_DECL_END % {'command_name': self.MethodName(), 506 'direction': 'Out'}) 507 if len(self.response_args) and len(self.request_args): 508 out_file.write( 509 self._FUNCTION_DECL_IN_OUT % {'command_name': self.MethodName()}) 510 elif self.response_args: 511 out_file.write( 512 self._FUNCTION_DECL_OUT % {'command_name': self.MethodName()}) 513 elif self.request_args: 514 out_file.write( 515 self._FUNCTION_DECL_IN % {'command_name': self.MethodName()}) 516 out_file.write(self._EXEC_DECL % {'command_name': self.MethodName()}) 517 518 def _GetNumberOfRequestHandles(self): 519 """Returns the number of input handles for this command.""" 520 return len(self._SplitArgs(self.request_args)[0]) 521 522 def _GetNumberOfResponseHandles(self): 523 """Returns the number of output handles for this command.""" 524 return len(self._SplitArgs(self.response_args)[0]) 525 526 def MethodName(self): 527 """Creates an appropriate generated method name for the command. 528 529 We use the command name without the TPM2_ prefix. 530 531 Returns: 532 The method name. 533 """ 534 if not self.name.startswith('TPM2_'): 535 return self.name 536 return self.name[5:] 537 538 def GetRequestHandles(self): 539 """Returns a list of input handles for this command.""" 540 return self._SplitArgs(self.request_args)[0] 541 542 def _SplitArgs(self, args): 543 """Splits a list of args into handles and parameters.""" 544 always_params = { 545 'TPM_CC_FlushContext': 'TPMI_DH_CONTEXT', 546 'TPM_CC_Hash': 'TPMI_RH_HIERARCHY', 547 'TPM_CC_LoadExternal': 'TPMI_RH_HIERARCHY', 548 'TPM_CC_SequenceComplete': 'TPMI_RH_HIERARCHY', 549 } 550 handles = [] 551 parameters = [] 552 always_handle = set(['TPM_HANDLE']) 553 # Handle types that appear as command parameters. 554 always_parameter = set(['TPMI_RH_ENABLES', 'TPMI_DH_PERSISTENT']) 555 if self.command_code in always_params: 556 always_parameter.add(always_params[self.command_code]) 557 for arg in args: 558 if (arg['type'] in always_handle or 559 (self._HANDLE_RE.search(arg['type']) and 560 arg['type'] not in always_parameter)): 561 handles.append(arg) 562 else: 563 parameters.append(arg) 564 return handles, parameters 565 566 567def _OutputCommandDispatcher(commands): 568 """Generates implementation file for CommandDispatcher function. 569 570 Args: 571 commands: A list of Command objects. 572 """ 573 with open('CommandDispatcher.c', 'w') as out_file: 574 out_file.write(COPYRIGHT_HEADER) 575 for command in commands: 576 out_file.write(_COMMAND_DISPATCHER_INCLUDES % 577 {'command_name': command.MethodName()}) 578 out_file.write(_COMMAND_DISPATCHER_START) 579 for command in commands: 580 command_code = 'TPM_CC_' + command.MethodName() 581 out_file.write(_COMMAND_DISPATCHER_CASE % 582 {'command_code': command_code, 583 'command_name': command.MethodName()}) 584 out_file.write(_COMMAND_DISPATCHER_END) 585 call(['clang-format', '-i', '-style=Chromium', 'CommandDispatcher.c']) 586 587 588def _OutputHandleProcess(commands, typemap): 589 """Generates implementation file for ParseHandleBuffer function. 590 591 Args: 592 commands: A list of Command objects. 593 typemap: A dict mapping type names to the corresponding object. 594 Generated by structure_generator. 595 """ 596 with open('HandleProcess.c', 'w') as out_file: 597 out_file.write(COPYRIGHT_HEADER) 598 out_file.write(_HANDLE_PROCESS_START) 599 for command in commands: 600 command_code = 'TPM_CC_' + command.MethodName() 601 out_file.write(_HANDLE_PROCESS_CASE_START % 602 {'command_code': command_code}) 603 for handle in command.GetRequestHandles(): 604 if typemap[handle['type']].HasConditional(): 605 out_file.write(_HANDLE_PROCESS_CASE_UNMARSHAL_FLAG % 606 {'handle_type': handle['type'], 607 'flag_val': handle['has_conditional']}) 608 else: 609 out_file.write(_HANDLE_PROCESS_CASE_UNMARSHAL % 610 {'handle_type': handle['type']}) 611 out_file.write(_HANDLE_PROCESS_CASE_CHECK) 612 out_file.write(_HANDLE_PROCESS_CASE_END) 613 out_file.write(_HANDLE_PROCESS_END) 614 call(['clang-format', '-i', '-style=Chromium', 'HandleProcess.c']) 615 616 617def _OutputGetCommandCodeString(commands): 618 """Generates header and implementation files for GetCommandCodeString. 619 620 Args: 621 commands: A list of Command objects. 622 """ 623 with open('GetCommandCodeString_fp.h', 'w') as out_file: 624 out_file.write(COPYRIGHT_HEADER) 625 out_file.write(_GET_COMMAND_CODE_STRING_HEADER) 626 call(['clang-format', '-i', '-style=Chromium', 'GetCommandCodeString_fp.h']) 627 with open('GetCommandCodeString.c', 'w') as out_file: 628 out_file.write(COPYRIGHT_HEADER) 629 out_file.write(_GET_COMMAND_CODE_STRING_START) 630 for command in commands: 631 out_file.write(_GET_COMMAND_CODE_STRING_CASE % 632 {'command_name': command.MethodName()}) 633 out_file.write(_GET_COMMAND_CODE_STRING_END) 634 call(['clang-format', '-i', '-style=Chromium', 'GetCommandCodeString.c']) 635 636 637def GenerateHeader(commands): 638 """Generates a header file with declarations for all given generator objects. 639 640 Args: 641 commands: A list of Command objects. 642 """ 643 for command in commands: 644 command_header_file = command.MethodName()+'_fp.h' 645 with open(command_header_file, 'w') as out_file: 646 out_file.write(COPYRIGHT_HEADER) 647 out_file.write( 648 _HEADER_FILE_GUARD_HEADER % {'name': command.MethodName().upper()}) 649 out_file.write(_HEADER_FILE_INCLUDES) 650 command.OutputDecl(out_file) 651 out_file.write( 652 _HEADER_FILE_GUARD_FOOTER % {'name': command.MethodName().upper()}) 653 call(['clang-format', '-i', '-style=Chromium', command_header_file]) 654 655 656def GenerateImplementation(commands, typemap): 657 """Generates implementation code for each command. 658 659 Args: 660 commands: A list of Command objects. 661 typemap: A dict mapping type names to the corresponding object. 662 Generated by structure_generator. 663 """ 664 for command in commands: 665 marshal_command_file = 'Marshal_'+command.MethodName()+'.c' 666 with open(marshal_command_file, 'w') as out_file: 667 out_file.write(COPYRIGHT_HEADER) 668 out_file.write(_IMPLEMENTATION_FILE_INCLUDES % 669 {'command_name': command.MethodName()}) 670 command.OutputMarshalFunction(out_file, typemap) 671 command.OutputUnmarshalFunction(out_file, typemap) 672 command.OutputExecFunction(out_file) 673 call(['clang-format', '-i', '-style=Chromium', marshal_command_file]) 674 _OutputHandleProcess(commands, typemap) 675 _OutputCommandDispatcher(commands) 676 _OutputGetCommandCodeString(commands) 677