1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright (c) 2021-2023 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import sys 17import os 18import stat 19import json 20import argparse 21import zipfile 22 23from collections import Counter 24 25sys.path.append( 26 os.path.dirname( 27 os.path.dirname( 28 os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))) 29 30from third_party.PyYAML.lib import yaml # noqa: E402 31 32_DUPLICATE_KEY_DEF = "duplicate key definition" 33_EMPTY_YAML = "empty yaml file input" 34_INVALID_YAML = "invalid yaml format" 35_DUPLICATE_DOMAIN = "duplicate domain" 36_INVALID_DOMAIN_NUMBER = "invalid domain number" 37_INVALID_DOMAIN_LENGTH = "invalid domain length" 38_INVALID_DOMAIN_CHAR = "invalid domain character" 39_INVALID_DOMAIN_CHAR_HEAD = "invalid domain character head" 40_INVALID_EVENT_NUMBER = "invalid event number" 41_INVALID_EVENT_LENGTH = "invalid event length" 42_INVALID_EVENT_CHAR = "invalid event character" 43_INVALID_EVENT_CHAR_HEAD = "invalid event character head" 44_MISSING_EVENT_BASE = "missing event base" 45_MISSING_EVENT_TYPE = "missing event type" 46_INVALID_EVENT_TYPE = "invalid event type" 47_MISSING_EVENT_LEVEL = "missing event level" 48_INVALID_EVENT_LEVEL = "invalid event level" 49_MISSING_EVENT_DESC = "missing event desc" 50_INVALID_EVENT_DESC_LENGTH = "invalid event desc length" 51_INVALID_EVENT_TAG_NUM = "invalid event tag number" 52_INVALID_EVENT_TAG_LEN = "invalid event tag length" 53_INVALID_EVENT_TAG_CHAR = "invalid event tag character" 54_DUPLICATE_EVENT_TAG = "duplicate event tag" 55_INVALID_EVENT_BASE_KEY = "invalid event base key" 56_INVALID_EVENT_PARAM_NUM = "invalid event param number" 57_INVALID_EVENT_PARAM_LEN = "invalid event param length" 58_INVALID_EVENT_PARAM_CHAR = "invalid event param character" 59_INVALID_EVENT_PARAM_CHAR_HEAD = "invalid event param character head" 60_MISSING_EVENT_PARAM_TYPE = "missing event param type" 61_INVALID_EVENT_PARAM_TYPE = "invalid event param type" 62_INVALID_EVENT_PARAM_ARRSIZE = "invalid event param arrsize" 63_MISSING_EVENT_PARAM_DESC = "missing event param desc" 64_INVALID_EVENT_PARAM_DESC_LEN = "invalid event param desc length" 65_INVALID_EVENT_PARAM_KEY = "invalid event param key" 66_DEPRECATED_EVENT_NAME_PREFIX = "deprecated event name prefix" 67_DEPRECATED_PARAM_NAME_PREFIX = "deprecated param name prefix" 68_DEPRECATED_TAG_NAME = "deprecated tag name" 69_DEPRECATED_EVENT_DESC_NAME = "deprecated event desc name" 70_DEPRECATED_PARAM_DESC_NAME = "deprecated param desc name" 71_INVALID_DOMAIN_DEF = "invalid definition type for domain" 72_INVALID_EVENT_DEF = "invalid definition type for event" 73_INVALID_EVENT_BASE_DEF = "invalid definition type for event base" 74_INVALID_EVENT_TYPE_DEF = "invalid definition type for event type" 75_INVALID_EVENT_LEVEL_DEF = "invalid definition type for event level" 76_INVALID_EVENT_DESC_DEF = "invalid definition type for event desc" 77_INVALID_EVENT_TAG_DEF = "invalid definition type for event tag" 78_INVALID_EVENT_PRESERVE_DEF = "invalid definition type for event preserve" 79_INVALID_EVENT_PARAM_DEF = "invalid definition type for event param" 80_INVALID_PARAM_TYPE_DEF = "invalid definition type for param type" 81_INVALID_PARAM_ARRSIZE_DEF = "invalid definition type for param arrsize" 82_INVALID_PARAM_DESC_DEF = "invalid definition type for param desc" 83_WARNING_MAP = { 84 _EMPTY_YAML : 85 "The yaml file list is empty.", 86 _INVALID_YAML : 87 "Invalid yaml file, error message: <<%s>>.", 88 _DUPLICATE_DOMAIN : 89 "Domain <<%s>> is already defined in <<%s>>.", 90 _INVALID_DOMAIN_NUMBER : 91 "The domain definition is missing in the yaml file.", 92 _INVALID_DOMAIN_LENGTH : 93 "The length of the domain must be between [1, 16], "\ 94 "but the actual length of the domain <<%s>> is <<%d>>.", 95 _INVALID_DOMAIN_CHAR : 96 "The character of the domain must be in [A-Z0-9_], "\ 97 "but the domain <<%s>> actually has <<%c>>.", 98 _INVALID_DOMAIN_CHAR_HEAD : 99 "The header of the domain must be in [A-Z], "\ 100 "but the actual header of the domain <<%s>> is <<%c>>.", 101 _INVALID_EVENT_NUMBER : 102 "The number of the events must be between [1, 4096], ."\ 103 "but there are actually <<%d>> events.", 104 _INVALID_EVENT_LENGTH : 105 "The length of the event must be between [1, 32], "\ 106 "but the actual length of the event <<%s>> is <<%d>>.", 107 _INVALID_EVENT_CHAR : 108 "The character of the event must be in [A-Z0-9_], "\ 109 "but the event <<%s>> actually has <<%c>>.", 110 _INVALID_EVENT_CHAR_HEAD : 111 "The header of the event must be in [A-Z], "\ 112 "but the actual header of the event <<%s>> is <<%c>>.", 113 _MISSING_EVENT_BASE : 114 "Event <<%s>> is missing __BASE definition.", 115 _MISSING_EVENT_TYPE : 116 "__BASE for event <<%s>> is missing type definition.", 117 _INVALID_EVENT_TYPE : 118 "The type of the event <<%s>> must be in "\ 119 "[FAULT, STATISTIC, SECURITY, BEHAVIOR], "\ 120 "but the actual event type is <<%s>>.", 121 _MISSING_EVENT_LEVEL : 122 "__BASE for event <<%s>> is missing level definition.", 123 _INVALID_EVENT_LEVEL : 124 "The level of the event <<%s>> must be in [CRITICAL, MINOR], "\ 125 "but the actual event level is <<%s>>.", 126 _MISSING_EVENT_DESC : 127 "__BASE for event <<%s>> is missing desc definition.", 128 _INVALID_EVENT_DESC_LENGTH : 129 "The length of the event desc must be between [3, 128], "\ 130 "but the actual length of the event <<%s>> desc <<%s>> is <<%d>>.", 131 _INVALID_EVENT_TAG_NUM : 132 "The number of the event tags must be between [0, 5], "\ 133 "but actually the event <<%s>> tag <<%s>> has <<%d>> tags.", 134 _INVALID_EVENT_TAG_LEN : 135 "The length of the event tag must be between [1, 16], "\ 136 "but the actual length of the event <<%s>> tag <<%s>> is <<%d>>.", 137 _INVALID_EVENT_TAG_CHAR : 138 "The character of the event tag must be in [A-Za-z0-9], "\ 139 "but the event <<%s>> tag <<%s>> actually has <<%c>>.", 140 _DUPLICATE_EVENT_TAG : 141 "Event tag should not be duplicated, "\ 142 "but tag <<%s>> for event <<%s>> has multiple identical.", 143 _INVALID_EVENT_BASE_KEY : 144 "Event <<%s>> __BASE key should be [type, level, tag, desc], "\ 145 "but actually has an invalid key <<%s>>.", 146 _INVALID_EVENT_PARAM_NUM : 147 "The number of the event param must be between [0, 128], "\ 148 "but actually the event <<%s>> has <<%d>> params.", 149 _INVALID_EVENT_PARAM_LEN : 150 "The length of the event param must be between [1, 32], "\ 151 "but the actual length of the event <<%s>> param <<%s>> is <<%d>>.", 152 _INVALID_EVENT_PARAM_CHAR : 153 "The character of the event param must be in [A-Z0-9_], "\ 154 "but the event <<%s>> param <<%s>> actually has <<%c>>.", 155 _INVALID_EVENT_PARAM_CHAR_HEAD: 156 "The header of the event param must be in [A-Z], "\ 157 "but the actual header of the event <<%s>> param <<%s>> is <<%c>>.", 158 _MISSING_EVENT_PARAM_TYPE : 159 "Event <<%s>> param <<%s>> is missing type definition.", 160 _INVALID_EVENT_PARAM_TYPE : 161 "The type of the event <<%s>> param <<%s>> must be in "\ 162 "[BOOL, INT8, UINT8, INT16, UINT16, INT32, UINT32, INT64, UINT64, "\ 163 "FLOAT, DOUBLE, STRING], but the actual type is <<%s>>.", 164 _INVALID_EVENT_PARAM_ARRSIZE : 165 "The arrsize of the event param must be between [1, 100], "\ 166 "but the actual arrsize of the event <<%s>> param <<%s>> is <<%d>>.", 167 _MISSING_EVENT_PARAM_DESC : 168 "Event <<%s>> param <<%s>> is missing desc definition.", 169 _INVALID_EVENT_PARAM_DESC_LEN : 170 "The length of the event param desc must be between [3, 128], "\ 171 "but the actual length of the event <<%s>> param <<%s>> "\ 172 "desc <<%s>> is <<%d>>.", 173 _INVALID_EVENT_PARAM_KEY : 174 "Event <<%s>> param <<%s>> key should be [type, arrsize, desc], "\ 175 "but actually has an invalid key <<%s>>.", 176 _DEPRECATED_EVENT_NAME_PREFIX : 177 "Event <<%s>> should not start with domain <<%s>>.", 178 _DEPRECATED_PARAM_NAME_PREFIX : 179 "Event param <<%s>> should not start with event <<%s>>.", 180 _DEPRECATED_TAG_NAME : 181 "Event tag <<%s>> should not be same as %s <<%s>>.", 182 _DEPRECATED_EVENT_DESC_NAME : 183 "Event desc <<%s>> should not be same as event <<%s>> and "\ 184 "should be more detailed.", 185 _DEPRECATED_PARAM_DESC_NAME : 186 "Event param desc <<%s>> should not be same as event <<%s>> "\ 187 "param <<%s>> and should be more detailed.", 188 _INVALID_DOMAIN_DEF : 189 "The definition type of the domain must be string.", 190 _INVALID_EVENT_DEF : 191 "The definition type of the event <<%s>> must be dictionary.", 192 _INVALID_EVENT_BASE_DEF : 193 "The definition type of the event <<%s>> __BASE must be dictionary.", 194 _INVALID_EVENT_TYPE_DEF : 195 "The definition type of the event <<%s>> type must be string.", 196 _INVALID_EVENT_LEVEL_DEF : 197 "The definition type of the event <<%s>> level must be string.", 198 _INVALID_EVENT_DESC_DEF : 199 "The definition type of the event <<%s>> desc must be string.", 200 _INVALID_EVENT_TAG_DEF : 201 "The definition type of the event <<%s>> tag must be string.", 202 _INVALID_EVENT_PRESERVE_DEF : 203 "The definition type of the event <<%s>> preserve must be bool.", 204 _INVALID_EVENT_PARAM_DEF : 205 "The definition type of the event <<%s>> param <<%s>> "\ 206 "must be dictionary.", 207 _INVALID_PARAM_TYPE_DEF : 208 "The definition type of the event <<%s>> param <<%s>> "\ 209 "type must be string.", 210 _INVALID_PARAM_ARRSIZE_DEF : 211 "The definition type of the event <<%s>> param <<%s>> "\ 212 "arrsize must be integer.", 213 _INVALID_PARAM_DESC_DEF : 214 "The definition type of the event <<%s>> param <<%s>> "\ 215 "desc must be string.", 216 _DUPLICATE_KEY_DEF : 217 "Duplicate key <<%s>> exists%s.", 218} 219 220 221_domain_dict = {} 222_warning_dict = {} 223_warning_file_path = "" 224_yaml_file_path = "" 225_warning_file = None 226_hisysevent_parse_res = True 227_deprecated_dict = {} 228 229 230class _UniqueKeySafeLoader(yaml.SafeLoader): 231 def construct_mapping(self, node, deep=False): 232 mapping = [] 233 for key_node, value_node in node.value: 234 key = self.construct_object(key_node, deep=deep) 235 if (key in mapping): 236 _build_warning_info(_DUPLICATE_KEY_DEF, 237 (key, key_node.start_mark)) 238 global _hisysevent_parse_res 239 _hisysevent_parse_res = False 240 continue 241 mapping.append(key) 242 return super().construct_mapping(node, deep) 243 244 245def _build_header(info_dict: dict): 246 table_header = "HiSysEvent yaml file: <<%s>>" % _yaml_file_path 247 info_dict[_yaml_file_path] = [table_header] 248 table_boundary = "-".rjust(100, '-') 249 info_dict[_yaml_file_path].append(table_boundary) 250 table_title = "Failed Item".ljust(50) + "| " + "Failed Reason" 251 info_dict[_yaml_file_path].append(table_title) 252 info_dict[_yaml_file_path].append(table_boundary) 253 254 255def _build_warning_header(): 256 global _warning_dict 257 _build_header(_warning_dict) 258 259 260def _build_deprecated_header(): 261 global _deprecated_dict 262 _build_header(_deprecated_dict) 263 264 265def _build_warning_info(item, values): 266 detail = _WARNING_MAP[item] % values 267 content = item.ljust(50) + "| " + detail 268 global _warning_dict 269 _warning_dict[_yaml_file_path].append(content) 270 271 272# Current set to warning, subsequent set to error. 273def _build_deprecated_info(item, values): 274 _build_deprecated_header() 275 detail = _WARNING_MAP[item] % values 276 content = item.ljust(50) + "| " + detail 277 global _deprecated_dict 278 _deprecated_dict[_yaml_file_path].append(content) 279 280 281def _open_warning_file(output_path: str): 282 global _warning_file_path 283 _warning_file_path = os.path.join(output_path, 'hisysevent_warning.txt') 284 global _warning_file 285 _warning_file = open(_warning_file_path, 'w+') 286 287 288def _close_warning_file(): 289 if not _warning_file: 290 _warning_file.close() 291 292 293def _output_warning(): 294 for warning_list in _warning_dict.values(): 295 if len(warning_list) > 4 or len(warning_list) == 1: 296 warning_list.append("") 297 for content in warning_list: 298 print(content) 299 print(content, file=_warning_file) 300 301 302def _output_deprecated(output_path: str): 303 deprecated_file = open(os.path.join(output_path, 'hisysevent_deprecated.txt'), 'w+') 304 for deprecated_list in _deprecated_dict.values(): 305 deprecated_list.append("") 306 for content in deprecated_list: 307 print(content, file=deprecated_file) 308 if not deprecated_file: 309 deprecated_file.close() 310 311 312def _exit_sys(): 313 print("Failed to parse the yaml file. For details about the error "\ 314 "information, see file %s." % (_warning_file_path)) 315 _output_warning() 316 _close_warning_file() 317 sys.exit(1) 318 319 320def _is_valid_length(content: str, len_min: int, len_max: int) -> bool: 321 return len(content) >= len_min and len(content) <= len_max 322 323 324def _is_valid_header(content: str) -> bool: 325 return len(content) == 0 or (content[0] >= 'A' and content[0] <= 'Z') 326 327 328def _is_invalid_char(ch) -> bool: 329 return (ch >= 'A' and ch <= 'Z') or (ch >= '0' and ch <= '9') or ch == '_' 330 331 332def _check_invalid_char(content: str): 333 for ch in iter(content): 334 if not _is_invalid_char(ch): 335 return ch 336 return None 337 338 339def _check_domain_duplicate(domain: str) -> bool: 340 if domain in _domain_dict: 341 _build_warning_info(_DUPLICATE_DOMAIN, (domain, _domain_dict[domain])) 342 return False 343 else: 344 _domain_dict[domain] = _yaml_file_path 345 return True 346 347 348def _check_event_domain(yaml_info: dict) -> bool: 349 if not "domain" in yaml_info: 350 _build_warning_info(_INVALID_DOMAIN_NUMBER, ()) 351 return False 352 if not isinstance(yaml_info["domain"], str): 353 _build_warning_info(_INVALID_DOMAIN_DEF, ()) 354 return False 355 domain = yaml_info["domain"] 356 check_res = True 357 if not _is_valid_length(domain, 1, 16): 358 _build_warning_info(_INVALID_DOMAIN_LENGTH, (domain, len(domain))) 359 check_res = False 360 if not _is_valid_header(domain): 361 _build_warning_info(_INVALID_DOMAIN_CHAR_HEAD, (domain, domain[0])) 362 check_res = False 363 invalid_ch = _check_invalid_char(domain) 364 if invalid_ch: 365 _build_warning_info(_INVALID_DOMAIN_CHAR, (domain, invalid_ch)) 366 check_res = False 367 if not _check_domain_duplicate(domain): 368 check_res = False 369 return check_res 370 371 372def _check_yaml_format(yaml_info) -> bool: 373 if not yaml_info: 374 _build_warning_info(_INVALID_YAML, ("The yaml file is empty")) 375 return False 376 if not isinstance(yaml_info, dict): 377 _build_warning_info(_INVALID_YAML, 378 ("The content of yaml file is invalid")) 379 return False 380 return True 381 382 383def _check_event_name(domain: str, event_name: str) -> bool: 384 check_res = True 385 if not _is_valid_length(event_name, 1, 32): 386 _build_warning_info(_INVALID_EVENT_LENGTH, 387 (event_name, len(event_name))) 388 check_res = False 389 if len(domain) > 0 and event_name.startswith(domain): 390 _build_deprecated_info(_DEPRECATED_EVENT_NAME_PREFIX, 391 (event_name, domain)) 392 if not _is_valid_header(event_name): 393 _build_warning_info(_INVALID_EVENT_CHAR_HEAD, 394 (event_name, event_name[0])) 395 check_res = False 396 invalid_ch = _check_invalid_char(event_name) 397 if invalid_ch: 398 _build_warning_info(_INVALID_DOMAIN_CHAR, (event_name, invalid_ch)) 399 check_res = False 400 return check_res 401 402 403def _check_event_type(event_name: str, event_base: dict) -> bool: 404 if not "type" in event_base: 405 _build_warning_info(_MISSING_EVENT_TYPE, (event_name)) 406 return False 407 else: 408 if not isinstance(event_base["type"], str): 409 _build_warning_info(_INVALID_EVENT_TYPE_DEF, event_name) 410 return False 411 type_list = ["FAULT", "STATISTIC", "SECURITY", "BEHAVIOR"] 412 if not event_base["type"] in type_list: 413 _build_warning_info(_INVALID_EVENT_TYPE, 414 (event_name, event_base["type"])) 415 return False 416 return True 417 418 419def _check_event_level(event_name: str, event_base: dict) -> bool: 420 if not "level" in event_base: 421 _build_warning_info(_MISSING_EVENT_LEVEL, (event_name)) 422 return False 423 else: 424 if not isinstance(event_base["level"], str): 425 _build_warning_info(_INVALID_EVENT_LEVEL_DEF, event_name) 426 return False 427 level_list = ["CRITICAL", "MINOR"] 428 if not event_base["level"] in level_list: 429 _build_warning_info(_INVALID_EVENT_LEVEL, 430 (event_name, event_base["level"])) 431 return False 432 return True 433 434 435def _check_event_desc(event_name: str, event_base: dict) -> bool: 436 if not "desc" in event_base: 437 _build_warning_info(_MISSING_EVENT_DESC, (event_name)) 438 return False 439 else: 440 event_desc = event_base["desc"] 441 if not isinstance(event_desc, str): 442 _build_warning_info(_INVALID_EVENT_DESC_DEF, event_name) 443 return False 444 check_res = True 445 if event_desc.lower() == event_name.lower(): 446 _build_deprecated_info(_DEPRECATED_EVENT_DESC_NAME, 447 (event_desc, event_name)) 448 if not _is_valid_length(event_desc, 3, 128): 449 _build_warning_info(_INVALID_EVENT_DESC_LENGTH, 450 (event_name, event_desc, len(event_desc))) 451 check_res = False 452 return check_res 453 454 455def _check_tag_char(event_tag: list): 456 for ch in iter(event_tag): 457 if not ch.isalnum(): 458 return ch 459 return None 460 461 462def _check_tag_name(event_name: str, event_base: dict, tag_name: str) -> bool: 463 check_res = True 464 if tag_name.lower() == event_name.lower(): 465 _build_deprecated_info(_DEPRECATED_TAG_NAME, 466 (tag_name, "event", event_name)) 467 if "type" in event_base and tag_name.lower() == event_base["type"].lower(): 468 _build_deprecated_info(_DEPRECATED_TAG_NAME, 469 (tag_name, "event type", event_base["type"])) 470 if not _is_valid_length(tag_name, 1, 16): 471 _build_warning_info(_INVALID_EVENT_TAG_LEN, 472 (event_name, tag_name, len(tag_name))) 473 check_res = False 474 invalid_ch = _check_tag_char(tag_name) 475 if invalid_ch: 476 _build_warning_info(_INVALID_EVENT_TAG_CHAR, 477 (event_name, tag_name, invalid_ch)) 478 check_res = False 479 return check_res 480 481 482def _get_duplicate_tag(tag_list: list): 483 tag_dict = dict(Counter(tag_list)) 484 for key, value in tag_dict.items(): 485 if value > 1: 486 return key 487 return None 488 489 490def _check_event_tag(event_name: str, event_base: dict) -> bool: 491 if not "tag" in event_base: 492 return True 493 event_tag = event_base["tag"] 494 if not isinstance(event_tag, str): 495 _build_warning_info(_INVALID_EVENT_TAG_DEF, event_name) 496 return False 497 tag_list = event_tag.split() 498 if not _is_valid_length(tag_list, 1, 5): 499 _build_warning_info(_INVALID_EVENT_TAG_NUM, 500 (event_name, event_tag, len(tag_list))) 501 return False 502 check_res = True 503 for each_tag in tag_list: 504 if not _check_tag_name(event_name, event_base, each_tag): 505 check_res = False 506 dup_tag = _get_duplicate_tag(tag_list) 507 if dup_tag: 508 _build_warning_info(_DUPLICATE_EVENT_TAG, (dup_tag, event_name)) 509 check_res = False 510 return check_res 511 512 513def _check_event_preserve(event_name: str, event_base: dict) -> bool: 514 if not "preserve" in event_base: 515 return True 516 event_preserve = event_base["preserve"] 517 if not isinstance(event_preserve, bool): 518 _build_warning_info(_INVALID_EVENT_PRESERVE_DEF, event_name) 519 return False 520 return True 521 522 523def _check_base_key(event_name: str, event_base: dict) -> bool: 524 key_list = ["type", "level", "tag", "desc", "preserve"] 525 for base_key in event_base.keys(): 526 if not base_key in key_list: 527 _build_warning_info(_INVALID_EVENT_BASE_KEY, 528 (event_name, base_key)) 529 return False 530 return True 531 532 533def _check_event_base(event_name: str, event_def: str) -> bool: 534 if not "__BASE" in event_def: 535 _build_warning_info(_MISSING_EVENT_BASE, (event_name)) 536 return False 537 event_base = event_def["__BASE"] 538 if not isinstance(event_base, dict): 539 _build_warning_info(_INVALID_EVENT_BASE_DEF, (event_name)) 540 return False 541 check_res = True 542 if not _check_event_type(event_name, event_base): 543 check_res = False 544 if not _check_event_level(event_name, event_base): 545 check_res = False 546 if not _check_event_desc(event_name, event_base): 547 check_res = False 548 if not _check_event_tag(event_name, event_base): 549 check_res = False 550 if not _check_event_preserve(event_name, event_base): 551 check_res = False 552 if not _check_base_key(event_name, event_base): 553 check_res = False 554 return check_res 555 556 557def _check_param_name(event_name: str, name: str) -> bool: 558 check_res = True 559 if not _is_valid_length(name, 1, 32): 560 _build_warning_info(_INVALID_EVENT_PARAM_LEN, 561 (event_name, name, len(name))) 562 check_res = False 563 if len(event_name) > 0 and name.startswith(event_name): 564 _build_deprecated_info(_DEPRECATED_PARAM_NAME_PREFIX, (name, event_name)) 565 if not _is_valid_header(name): 566 _build_warning_info(_INVALID_EVENT_PARAM_CHAR_HEAD, 567 (event_name, name, name[0])) 568 check_res = False 569 invalid_ch = _check_invalid_char(name) 570 if invalid_ch: 571 _build_warning_info(_INVALID_EVENT_PARAM_CHAR, 572 (event_name, name, invalid_ch)) 573 check_res = False 574 return check_res 575 576 577def _check_param_type(event_name: str, param_name: str, param_info: dict) -> bool: 578 if not "type" in param_info: 579 _build_warning_info(_MISSING_EVENT_PARAM_TYPE, 580 (event_name, param_name)) 581 return False 582 else: 583 if not isinstance(param_info["type"], str): 584 _build_warning_info(_INVALID_PARAM_TYPE_DEF, 585 (event_name, param_name)) 586 return False 587 type_list = ["BOOL", "INT8", "UINT8", "INT16", "UINT16", "INT32", 588 "UINT32", "INT64", "UINT64", "FLOAT", "DOUBLE", "STRING"] 589 if not param_info["type"] in type_list: 590 _build_warning_info(_INVALID_EVENT_PARAM_TYPE, 591 (event_name, param_name, param_info["type"])) 592 return False 593 return True 594 595 596def _check_param_arrsize(event_name: str, param_name: str, param_info: dict) -> bool: 597 if not "arrsize" in param_info: 598 return True 599 arrsize = param_info["arrsize"] 600 if not isinstance(arrsize, int): 601 _build_warning_info(_INVALID_PARAM_ARRSIZE_DEF, 602 (event_name, param_name)) 603 return False 604 if not (arrsize >= 1 and arrsize <= 100): 605 _build_warning_info(_INVALID_EVENT_PARAM_ARRSIZE, 606 (event_name, param_name, arrsize)) 607 return False 608 return True 609 610 611def _check_param_desc(event_name: str, param_name: str, param_info: dict) -> bool: 612 if not "desc" in param_info: 613 _build_warning_info(_MISSING_EVENT_PARAM_DESC, 614 (event_name, param_name)) 615 return False 616 else: 617 param_desc = param_info["desc"] 618 if not isinstance(param_desc, str): 619 _build_warning_info(_INVALID_PARAM_DESC_DEF, 620 (event_name, param_name)) 621 return False 622 check_res = True 623 if param_desc.lower() == param_name.lower(): 624 _build_deprecated_info(_DEPRECATED_PARAM_DESC_NAME, 625 (param_desc, event_name, param_name)) 626 if not _is_valid_length(param_desc, 3, 128): 627 _build_warning_info(_INVALID_EVENT_PARAM_DESC_LEN, 628 (event_name, param_name, param_desc, len(param_desc))) 629 check_res = False 630 return check_res 631 632 633def _check_param_key(event_name: str, param_name: str, param_info: dict) -> bool: 634 key_list = ["type", "arrsize", "desc"] 635 for key in param_info.keys(): 636 if not key in key_list: 637 _build_warning_info(_INVALID_EVENT_PARAM_KEY, 638 (event_name, param_name, key)) 639 return False 640 return True 641 642 643def _check_param_info(event_name: str, param_name: str, param_info: dict) -> bool: 644 check_res = True 645 if not _check_param_type(event_name, param_name, param_info): 646 check_res = False 647 if not _check_param_arrsize(event_name, param_name, param_info): 648 check_res = False 649 if not _check_param_desc(event_name, param_name, param_info): 650 check_res = False 651 if not _check_param_key(event_name, param_name, param_info): 652 check_res = False 653 return check_res 654 655 656def _check_event_param(event_name: str, event_def: str) -> bool: 657 sub_num = (0, 1)["__BASE" in event_def] 658 check_res = True 659 if not _is_valid_length(event_def, 0 + sub_num, 128 + sub_num): 660 _build_warning_info(_INVALID_EVENT_PARAM_NUM, 661 (event_name, (len(event_def) - sub_num))) 662 check_res = False 663 for param_name in event_def.keys(): 664 if param_name == "__BASE": 665 continue 666 if not _check_param_name(event_name, param_name): 667 check_res = False 668 param_info = event_def[param_name] 669 if not isinstance(param_info, dict): 670 _build_warning_info(_INVALID_EVENT_PARAM_DEF, 671 (event_name, param_name)) 672 check_res = False 673 continue 674 if not _check_param_info(event_name, param_name, param_info): 675 check_res = False 676 return check_res 677 678 679def _check_event_def(event_name: str, event_def: str) -> bool: 680 check_res = True 681 if not _check_event_base(event_name, event_def): 682 check_res = False 683 if not _check_event_param(event_name, event_def): 684 check_res = False 685 return check_res 686 687 688def _check_event_info(domain: str, event_info: list) -> bool: 689 event_name = event_info[0] 690 event_def = event_info[1] 691 check_res = True 692 if not isinstance(event_def, dict): 693 _build_warning_info(_INVALID_EVENT_DEF, (event_name)) 694 return False 695 if not _check_event_name(domain, event_name): 696 check_res = False 697 if not _check_event_def(event_name, event_def): 698 check_res = False 699 return check_res 700 701 702def _check_events_info(domain: str, yaml_info: str) -> bool: 703 event_num = len(yaml_info) 704 if not (event_num >= 1 and event_num <= 4096): 705 _build_warning_info(_INVALID_EVENT_NUMBER, (event_num)) 706 return False 707 check_res = True 708 for event_info in yaml_info.items(): 709 if not _check_event_info(domain, event_info): 710 check_res = False 711 return check_res 712 713 714def merge_hisysevent_config(yaml_list: str, output_path: str) -> str: 715 if (len(output_path) == 0): 716 present_path = os.path.dirname(os.path.abspath(__file__)) 717 output_path = present_path 718 if (len(yaml_list) == 0): 719 _build_warning_info(_EMPTY_YAML, ()) 720 _exit_sys() 721 if not os.path.exists(output_path): 722 os.makedirs(output_path, exist_ok=True) 723 _open_warning_file(output_path) 724 725 yaml_info_dict = {} 726 global _hisysevent_parse_res 727 for yaml_path in yaml_list: 728 global _yaml_file_path 729 _yaml_file_path = yaml_path.replace("../", "") 730 _build_warning_header() 731 with os.fdopen(os.open(yaml_path, os.O_RDWR | os.O_CREAT, stat.S_IWUSR | stat.S_IRUSR), 732 'r', encoding='utf-8') as yaml_file: 733 yaml_info = yaml.load(yaml_file, Loader=_UniqueKeySafeLoader) 734 if not _check_yaml_format(yaml_info): 735 _hisysevent_parse_res = False 736 continue 737 if not _check_event_domain(yaml_info): 738 _hisysevent_parse_res = False 739 continue 740 domain = yaml_info["domain"] 741 del yaml_info["domain"] 742 if not _check_events_info(domain, yaml_info): 743 _hisysevent_parse_res = False 744 continue 745 yaml_info_dict[domain] = yaml_info 746 _output_deprecated(output_path) 747 if not _hisysevent_parse_res: 748 _exit_sys() 749 750 hisysevent_def_file = os.path.join(output_path, 'hisysevent.def') 751 with open(hisysevent_def_file, 'w') as j: 752 json.dump(yaml_info_dict, j, indent=4) 753 print("The hisysevent.def {} is generated successfully." 754 .format(hisysevent_def_file)) 755 _close_warning_file() 756 757 # zip def file 758 hisysevent_def_zip_file = os.path.join(output_path, 'hisysevent.zip') 759 def_zip_file = zipfile.ZipFile(hisysevent_def_zip_file, "w", zipfile.ZIP_DEFLATED) 760 def_zip_file.write(hisysevent_def_file, arcname=os.path.basename(hisysevent_def_file)) 761 def_zip_file.close() 762 # remove def file 763 os.remove(hisysevent_def_file) 764 765 return hisysevent_def_zip_file 766 767 768def main(argv) -> int: 769 parser = argparse.ArgumentParser(description='yaml list') 770 parser.add_argument("--yaml-list", nargs='+', required=True) 771 parser.add_argument("--def-path", required=True) 772 args = parser.parse_args(argv) 773 hisysevent_def_file = merge_hisysevent_config(args.yaml_list, 774 args.def_path) 775 print(hisysevent_def_file) 776 return 0 777 778 779if __name__ == '__main__': 780 sys.exit(main(sys.argv[1:])) 781