Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """code generator for GLES2 command buffers.""" | 6 """code generator for GLES2 command buffers.""" |
| 7 | 7 |
| 8 import itertools | 8 import itertools |
| 9 import os | 9 import os |
| 10 import os.path | 10 import os.path |
| (...skipping 1365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1376 'decoder_func': 'DoConsumeTextureCHROMIUM', | 1376 'decoder_func': 'DoConsumeTextureCHROMIUM', |
| 1377 'impl_func': False, | 1377 'impl_func': False, |
| 1378 'type': 'PUT', | 1378 'type': 'PUT', |
| 1379 'count': 64, # GL_MAILBOX_SIZE_CHROMIUM | 1379 'count': 64, # GL_MAILBOX_SIZE_CHROMIUM |
| 1380 'unit_test': False, | 1380 'unit_test': False, |
| 1381 'client_test': False, | 1381 'client_test': False, |
| 1382 'extension': True, | 1382 'extension': True, |
| 1383 'chromium': True, | 1383 'chromium': True, |
| 1384 'trace_level': 1, | 1384 'trace_level': 1, |
| 1385 }, | 1385 }, |
| 1386 'CreateAndConsumeTextureCHROMIUM': { | |
| 1387 'decoder_func': 'DoCreateAndConsumeTextureCHROMIUM', | |
| 1388 'impl_func': False, | |
| 1389 'type': 'CreateAndConsume', | |
|
piman
2014/05/22 21:53:58
I'm not convinced it's worth creating a new type j
| |
| 1390 'count': 64, # GL_MAILBOX_SIZE_CHROMIUM | |
| 1391 'unit_test': False, | |
| 1392 'client_test': False, | |
| 1393 'extension': True, | |
| 1394 'chromium': True, | |
| 1395 'trace_level': 1, | |
| 1396 }, | |
| 1386 'ClearStencil': { | 1397 'ClearStencil': { |
| 1387 'type': 'StateSet', | 1398 'type': 'StateSet', |
| 1388 'state': 'ClearStencil', | 1399 'state': 'ClearStencil', |
| 1389 }, | 1400 }, |
| 1390 'EnableFeatureCHROMIUM': { | 1401 'EnableFeatureCHROMIUM': { |
| 1391 'type': 'Custom', | 1402 'type': 'Custom', |
| 1392 'immediate': False, | 1403 'immediate': False, |
| 1393 'decoder_func': 'DoEnableFeatureCHROMIUM', | 1404 'decoder_func': 'DoEnableFeatureCHROMIUM', |
| 1394 'expectation': False, | 1405 'expectation': False, |
| 1395 'cmd_args': 'GLuint bucket_id, GLint* result', | 1406 'cmd_args': 'GLuint bucket_id, GLint* result', |
| (...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1969 'decoder_func': 'DoProduceTextureCHROMIUM', | 1980 'decoder_func': 'DoProduceTextureCHROMIUM', |
| 1970 'impl_func': False, | 1981 'impl_func': False, |
| 1971 'type': 'PUT', | 1982 'type': 'PUT', |
| 1972 'count': 64, # GL_MAILBOX_SIZE_CHROMIUM | 1983 'count': 64, # GL_MAILBOX_SIZE_CHROMIUM |
| 1973 'unit_test': False, | 1984 'unit_test': False, |
| 1974 'client_test': False, | 1985 'client_test': False, |
| 1975 'extension': True, | 1986 'extension': True, |
| 1976 'chromium': True, | 1987 'chromium': True, |
| 1977 'trace_level': 1, | 1988 'trace_level': 1, |
| 1978 }, | 1989 }, |
| 1990 'ProduceTextureBindlessCHROMIUM': { | |
| 1991 'decoder_func': 'DoProduceTextureBindlessCHROMIUM', | |
| 1992 'impl_func': False, | |
| 1993 'type': 'PUT', | |
| 1994 'count': 64, # GL_MAILBOX_SIZE_CHROMIUM | |
| 1995 'unit_test': False, | |
| 1996 'client_test': False, | |
| 1997 'extension': True, | |
| 1998 'chromium': True, | |
| 1999 'trace_level': 1, | |
| 2000 }, | |
| 1979 'RenderbufferStorage': { | 2001 'RenderbufferStorage': { |
| 1980 'decoder_func': 'DoRenderbufferStorage', | 2002 'decoder_func': 'DoRenderbufferStorage', |
| 1981 'gl_test_func': 'glRenderbufferStorageEXT', | 2003 'gl_test_func': 'glRenderbufferStorageEXT', |
| 1982 'expectation': False, | 2004 'expectation': False, |
| 1983 }, | 2005 }, |
| 1984 'RenderbufferStorageMultisampleCHROMIUM': { | 2006 'RenderbufferStorageMultisampleCHROMIUM': { |
| 1985 'cmd_comment': | 2007 'cmd_comment': |
| 1986 '// GL_CHROMIUM_framebuffer_multisample\n', | 2008 '// GL_CHROMIUM_framebuffer_multisample\n', |
| 1987 'decoder_func': 'DoRenderbufferStorageMultisampleCHROMIUM', | 2009 'decoder_func': 'DoRenderbufferStorageMultisampleCHROMIUM', |
| 1988 'gl_test_func': 'glRenderbufferStorageMultisampleCHROMIUM', | 2010 'gl_test_func': 'glRenderbufferStorageMultisampleCHROMIUM', |
| (...skipping 2244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4233 file.Write(" cmd.header.size * 4u);\n") | 4255 file.Write(" cmd.header.size * 4u);\n") |
| 4234 file.Write(" EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n);\n"); | 4256 file.Write(" EXPECT_EQ(static_cast<GLsizei>(arraysize(ids)), cmd.n);\n"); |
| 4235 file.Write(" CheckBytesWrittenMatchesExpectedSize(\n") | 4257 file.Write(" CheckBytesWrittenMatchesExpectedSize(\n") |
| 4236 file.Write(" next_cmd, sizeof(cmd) +\n") | 4258 file.Write(" next_cmd, sizeof(cmd) +\n") |
| 4237 file.Write(" RoundSizeToMultipleOfEntries(arraysize(ids) * 4u));\n") | 4259 file.Write(" RoundSizeToMultipleOfEntries(arraysize(ids) * 4u));\n") |
| 4238 file.Write(" // TODO(gman): Check that ids were inserted;\n") | 4260 file.Write(" // TODO(gman): Check that ids were inserted;\n") |
| 4239 file.Write("}\n") | 4261 file.Write("}\n") |
| 4240 file.Write("\n") | 4262 file.Write("\n") |
| 4241 | 4263 |
| 4242 | 4264 |
| 4243 class CreateHandler(TypeHandler): | 4265 class ArrayArgTypeHandler(TypeHandler): |
| 4244 """Handler for glCreate___ type functions.""" | 4266 """Base class for type handlers that handle args that are arrays""" |
| 4245 | 4267 |
| 4246 def __init__(self): | 4268 def __init__(self): |
| 4247 TypeHandler.__init__(self) | 4269 TypeHandler.__init__(self) |
| 4248 | 4270 |
| 4271 def GetArrayType(self, func): | |
| 4272 """Returns the type of the element in the element array being PUT to.""" | |
| 4273 for arg in func.GetOriginalArgs(): | |
| 4274 if arg.IsPointer(): | |
| 4275 element_type = arg.GetPointedType() | |
| 4276 return element_type | |
| 4277 | |
| 4278 # Special case: array type handler is used for a function that is forwarded | |
| 4279 # to the actual array type implementation | |
| 4280 element_type = func.GetOriginalArgs()[-1].type | |
| 4281 assert all(arg.type == element_type \ | |
| 4282 for arg in func.GetOriginalArgs()[-self.GetArrayCount(func):]) | |
| 4283 return element_type | |
| 4284 | |
| 4285 def GetArrayCount(self, func): | |
| 4286 """Returns the count of the elements in the array being PUT to.""" | |
| 4287 return func.GetInfo('count') | |
| 4288 | |
| 4289 | |
| 4290 class CreateHandler(ArrayArgTypeHandler): | |
| 4291 """Handler for glCreate___ type functions.""" | |
| 4292 | |
| 4293 def __init__(self): | |
| 4294 ArrayArgTypeHandler.__init__(self) | |
| 4295 | |
| 4249 def InitFunction(self, func): | 4296 def InitFunction(self, func): |
| 4250 """Overrriden from TypeHandler.""" | 4297 """Overrriden from TypeHandler.""" |
| 4251 func.AddCmdArg(Argument("client_id", 'uint32_t')) | 4298 func.AddCmdArg(Argument("client_id", 'uint32_t')) |
| 4252 | 4299 |
| 4253 def WriteServiceUnitTest(self, func, file): | 4300 def WriteServiceUnitTest(self, func, file): |
| 4254 """Overrriden from TypeHandler.""" | 4301 """Overrriden from TypeHandler.""" |
| 4255 valid_test = """ | 4302 valid_test = """ |
| 4256 TEST_P(%(test_name)s, %(name)sValidArgs) { | 4303 TEST_P(%(test_name)s, %(name)sValidArgs) { |
| 4257 EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)) | 4304 EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s)) |
| 4258 .WillOnce(Return(kNewServiceId)); | 4305 .WillOnce(Return(kNewServiceId)); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4308 file.Write(" MakeIds(this, 0, 1, &client_id);\n") | 4355 file.Write(" MakeIds(this, 0, 1, &client_id);\n") |
| 4309 file.Write(" helper_->%s(%s);\n" % | 4356 file.Write(" helper_->%s(%s);\n" % |
| 4310 (func.name, func.MakeCmdArgString(""))) | 4357 (func.name, func.MakeCmdArgString(""))) |
| 4311 file.Write(' GPU_CLIENT_LOG("returned " << client_id);\n') | 4358 file.Write(' GPU_CLIENT_LOG("returned " << client_id);\n') |
| 4312 file.Write(" CheckGLError();\n") | 4359 file.Write(" CheckGLError();\n") |
| 4313 file.Write(" return client_id;\n") | 4360 file.Write(" return client_id;\n") |
| 4314 file.Write("}\n") | 4361 file.Write("}\n") |
| 4315 file.Write("\n") | 4362 file.Write("\n") |
| 4316 | 4363 |
| 4317 | 4364 |
| 4365 class CreateAndConsumeHandler(CreateHandler): | |
| 4366 """Handler for glCreateAndConsumeTextureCHROMIUM.""" | |
| 4367 | |
| 4368 def __init__(self): | |
| 4369 CreateHandler.__init__(self) | |
| 4370 | |
| 4371 def WriteGLES2Implementation(self, func, file): | |
| 4372 """Overrriden from TypeHandler.""" | |
| 4373 pass | |
| 4374 | |
| 4375 def WriteHandlerImplementation (self, func, file): | |
| 4376 """Overrriden from TypeHandler.""" | |
| 4377 file.Write(" uint32_t client_id = c.client_id;\n") | |
| 4378 file.Write(" %s(%s, client_id);\n" % | |
| 4379 (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) | |
| 4380 | |
| 4381 def WriteImmediateHandlerImplementation (self, func, file): | |
| 4382 """Overrriden from TypeHandler.""" | |
| 4383 file.Write(" uint32_t client_id = c.client_id;\n") | |
| 4384 file.Write(" %s(%s, client_id);\n" % | |
| 4385 (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) | |
| 4386 | |
| 4387 def WriteImmediateServiceImplementation(self, func, file): | |
| 4388 """Writes the service implementation for an immediate version of command.""" | |
| 4389 file.Write( | |
| 4390 "error::Error GLES2DecoderImpl::Handle%s(\n" % func.name) | |
| 4391 file.Write( | |
| 4392 " uint32_t immediate_data_size, const gles2::cmds::%s& c) {\n" % | |
| 4393 func.name) | |
| 4394 self.WriteHandlerExtensionCheck(func, file) | |
| 4395 self.WriteHandlerDeferReadWrite(func, file); | |
| 4396 last_arg = func.GetLastOriginalArg() | |
| 4397 all_but_last_arg = func.GetOriginalArgs()[:-1] | |
| 4398 for arg in all_but_last_arg: | |
| 4399 arg.WriteGetCode(file) | |
| 4400 self.WriteGetDataSizeCode(func, file) | |
| 4401 last_arg.WriteGetCode(file) | |
| 4402 func.WriteHandlerValidation(file) | |
| 4403 func.WriteHandlerImplementation(file) | |
| 4404 file.Write(" return error::kNoError;\n") | |
| 4405 file.Write("}\n") | |
| 4406 file.Write("\n") | |
| 4407 | |
| 4408 def WriteGetDataSizeCode(self, func, file): | |
| 4409 """Overrriden from TypeHandler.""" | |
| 4410 code = """ uint32_t data_size; | |
| 4411 if (!ComputeDataSize(1, sizeof(%s), %d, &data_size)) { | |
| 4412 return error::kOutOfBounds; | |
| 4413 } | |
| 4414 """ | |
| 4415 file.Write(code % (self.GetArrayType(func), self.GetArrayCount(func))) | |
| 4416 if func.IsImmediate(): | |
| 4417 file.Write(" if (data_size > immediate_data_size) {\n") | |
| 4418 file.Write(" return error::kOutOfBounds;\n") | |
| 4419 file.Write(" }\n") | |
| 4420 | |
| 4421 def WriteImmediateCmdComputeSize(self, func, file): | |
| 4422 """Overrriden from TypeHandler.""" | |
| 4423 file.Write(" static uint32_t ComputeDataSize() {\n") | |
| 4424 file.Write(" return static_cast<uint32_t>(\n") | |
| 4425 file.Write(" sizeof(%s) * %d); // NOLINT\n" % | |
| 4426 (self.GetArrayType(func), self.GetArrayCount(func))) | |
| 4427 file.Write(" }\n") | |
| 4428 file.Write("\n") | |
| 4429 file.Write(" static uint32_t ComputeSize() {\n") | |
| 4430 file.Write(" return static_cast<uint32_t>(\n") | |
| 4431 file.Write( | |
| 4432 " sizeof(ValueType) + ComputeDataSize()); // NOLINT\n") | |
| 4433 file.Write(" }\n") | |
| 4434 file.Write("\n") | |
| 4435 | |
| 4436 def WriteImmediateCmdInit(self, func, file): | |
| 4437 """Overrriden from TypeHandler.""" | |
| 4438 last_arg = func.GetLastOriginalArg() | |
| 4439 file.Write(" void Init(%s, %s _%s) {\n" % | |
| 4440 (func.MakeTypedCmdArgString("_"), | |
| 4441 last_arg.type, last_arg.name)) | |
| 4442 file.Write(" SetHeader(ComputeSize());\n") | |
| 4443 args = func.GetCmdArgs() | |
| 4444 for arg in args: | |
| 4445 file.Write(" %s = _%s;\n" % (arg.name, arg.name)) | |
| 4446 file.Write(" memcpy(ImmediateDataAddress(this),\n") | |
| 4447 file.Write(" _%s, ComputeDataSize());\n" % last_arg.name) | |
| 4448 file.Write(" }\n") | |
| 4449 file.Write("\n") | |
| 4450 | |
| 4451 def WriteImmediateCmdSet(self, func, file): | |
| 4452 """Overrriden from TypeHandler.""" | |
| 4453 last_arg = func.GetLastOriginalArg() | |
| 4454 copy_args = func.MakeCmdArgString("_", False) | |
| 4455 file.Write(" void* Set(void* cmd%s, %s _%s) {\n" % | |
| 4456 (func.MakeTypedCmdArgString("_", True), | |
| 4457 last_arg.type, last_arg.name)) | |
| 4458 file.Write(" static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" % | |
| 4459 (copy_args, last_arg.name)) | |
| 4460 file.Write(" const uint32_t size = ComputeSize();\n") | |
| 4461 file.Write(" return NextImmediateCmdAddressTotalSize<ValueType>(" | |
| 4462 "cmd, size);\n") | |
| 4463 file.Write(" }\n") | |
| 4464 file.Write("\n") | |
| 4465 | |
| 4466 def WriteImmediateCmdHelper(self, func, file): | |
| 4467 """Writes the cmd helper definition for the immediate version of a cmd.""" | |
| 4468 code = """ void %(name)s(%(typed_args)s) { | |
| 4469 const uint32_t size = gles2::cmds::%(name)s::ComputeSize(); | |
| 4470 gles2::cmds::%(name)s* c = | |
| 4471 GetImmediateCmdSpaceTotalSize<gles2::cmds::%(name)s>(size); | |
| 4472 if (c) { | |
| 4473 c->Init(%(args)s); | |
| 4474 } | |
| 4475 } | |
| 4476 | |
| 4477 """ | |
| 4478 last_arg = func.GetLastOriginalArg() | |
| 4479 file.Write(code % { | |
| 4480 "name": func.name, | |
| 4481 "typed_args": '%s, %s _%s' % (func.MakeTypedCmdArgString(""), | |
| 4482 last_arg.type, last_arg.name), | |
| 4483 "args": '%s, _%s' % (func.MakeCmdArgString(""), last_arg.name), | |
| 4484 }) | |
| 4485 | |
| 4318 class DeleteHandler(TypeHandler): | 4486 class DeleteHandler(TypeHandler): |
| 4319 """Handler for glDelete___ single resource type functions.""" | 4487 """Handler for glDelete___ single resource type functions.""" |
| 4320 | 4488 |
| 4321 def __init__(self): | 4489 def __init__(self): |
| 4322 TypeHandler.__init__(self) | 4490 TypeHandler.__init__(self) |
| 4323 | 4491 |
| 4324 def WriteServiceImplementation(self, func, file): | 4492 def WriteServiceImplementation(self, func, file): |
| 4325 """Overrriden from TypeHandler.""" | 4493 """Overrriden from TypeHandler.""" |
| 4326 pass | 4494 pass |
| 4327 | 4495 |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4783 static_cast<cmds::%(name)s::Result*>(shared_memory_address_); | 4951 static_cast<cmds::%(name)s::Result*>(shared_memory_address_); |
| 4784 result->size = 0; | 4952 result->size = 0; |
| 4785 cmds::%(name)s cmd; | 4953 cmds::%(name)s cmd; |
| 4786 cmd.Init(%(args)s); | 4954 cmd.Init(%(args)s); |
| 4787 EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd)); | 4955 EXPECT_EQ(error::%(parse_result)s, ExecuteCmd(cmd)); |
| 4788 EXPECT_EQ(0u, result->size);%(gl_error_test)s | 4956 EXPECT_EQ(0u, result->size);%(gl_error_test)s |
| 4789 } | 4957 } |
| 4790 """ | 4958 """ |
| 4791 self.WriteInvalidUnitTest(func, file, invalid_test) | 4959 self.WriteInvalidUnitTest(func, file, invalid_test) |
| 4792 | 4960 |
| 4793 class ArrayArgTypeHandler(TypeHandler): | |
| 4794 """Base class for type handlers that handle args that are arrays""" | |
| 4795 | |
| 4796 def __init__(self): | |
| 4797 TypeHandler.__init__(self) | |
| 4798 | |
| 4799 def GetArrayType(self, func): | |
| 4800 """Returns the type of the element in the element array being PUT to.""" | |
| 4801 for arg in func.GetOriginalArgs(): | |
| 4802 if arg.IsPointer(): | |
| 4803 element_type = arg.GetPointedType() | |
| 4804 return element_type | |
| 4805 | |
| 4806 # Special case: array type handler is used for a function that is forwarded | |
| 4807 # to the actual array type implementation | |
| 4808 element_type = func.GetOriginalArgs()[-1].type | |
| 4809 assert all(arg.type == element_type \ | |
| 4810 for arg in func.GetOriginalArgs()[-self.GetArrayCount(func):]) | |
| 4811 return element_type | |
| 4812 | |
| 4813 def GetArrayCount(self, func): | |
| 4814 """Returns the count of the elements in the array being PUT to.""" | |
| 4815 return func.GetInfo('count') | |
| 4816 | 4961 |
| 4817 class PUTHandler(ArrayArgTypeHandler): | 4962 class PUTHandler(ArrayArgTypeHandler): |
| 4818 """Handler for glTexParameter_v, glVertexAttrib_v functions.""" | 4963 """Handler for glTexParameter_v, glVertexAttrib_v functions.""" |
| 4819 | 4964 |
| 4820 def __init__(self): | 4965 def __init__(self): |
| 4821 ArrayArgTypeHandler.__init__(self) | 4966 ArrayArgTypeHandler.__init__(self) |
| 4822 | 4967 |
| 4823 def WriteServiceUnitTest(self, func, file): | 4968 def WriteServiceUnitTest(self, func, file): |
| 4824 """Writes the service unit test for a command.""" | 4969 """Writes the service unit test for a command.""" |
| 4825 expected_call = "EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));" | 4970 expected_call = "EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s));" |
| (...skipping 1774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6600 return ("kInvalidClientId", "kNoError", "GL_INVALID_VALUE") | 6745 return ("kInvalidClientId", "kNoError", "GL_INVALID_VALUE") |
| 6601 | 6746 |
| 6602 | 6747 |
| 6603 class Function(object): | 6748 class Function(object): |
| 6604 """A class that represents a function.""" | 6749 """A class that represents a function.""" |
| 6605 | 6750 |
| 6606 type_handlers = { | 6751 type_handlers = { |
| 6607 '': TypeHandler(), | 6752 '': TypeHandler(), |
| 6608 'Bind': BindHandler(), | 6753 'Bind': BindHandler(), |
| 6609 'Create': CreateHandler(), | 6754 'Create': CreateHandler(), |
| 6755 'CreateAndConsume': CreateAndConsumeHandler(), | |
| 6610 'Custom': CustomHandler(), | 6756 'Custom': CustomHandler(), |
| 6611 'Data': DataHandler(), | 6757 'Data': DataHandler(), |
| 6612 'Delete': DeleteHandler(), | 6758 'Delete': DeleteHandler(), |
| 6613 'DELn': DELnHandler(), | 6759 'DELn': DELnHandler(), |
| 6614 'GENn': GENnHandler(), | 6760 'GENn': GENnHandler(), |
| 6615 'GETn': GETnHandler(), | 6761 'GETn': GETnHandler(), |
| 6616 'GLchar': GLcharHandler(), | 6762 'GLchar': GLcharHandler(), |
| 6617 'GLcharN': GLcharNHandler(), | 6763 'GLcharN': GLcharNHandler(), |
| 6618 'HandWritten': HandWrittenHandler(), | 6764 'HandWritten': HandWrittenHandler(), |
| 6619 'Is': IsHandler(), | 6765 'Is': IsHandler(), |
| (...skipping 1717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8337 "ppapi/shared_impl/ppb_opengles2_shared.cc"]) | 8483 "ppapi/shared_impl/ppb_opengles2_shared.cc"]) |
| 8338 | 8484 |
| 8339 if gen.errors > 0: | 8485 if gen.errors > 0: |
| 8340 print "%d errors" % gen.errors | 8486 print "%d errors" % gen.errors |
| 8341 return 1 | 8487 return 1 |
| 8342 return 0 | 8488 return 0 |
| 8343 | 8489 |
| 8344 | 8490 |
| 8345 if __name__ == '__main__': | 8491 if __name__ == '__main__': |
| 8346 sys.exit(main(sys.argv[1:])) | 8492 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |