/edk2/BaseTools/Source/Python/UPT/Object/Parser/InfProtocolObject.py

https://gitlab.com/envieidoc/Clover · Python · 311 lines · 194 code · 38 blank · 79 comment · 55 complexity · 0f260024444e6552f306e32a58e606f3 MD5 · raw file

  1. ## @file
  2. # This file is used to define class objects of INF file [Protocols] section.
  3. # It will consumed by InfParser.
  4. #
  5. # Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
  6. #
  7. # This program and the accompanying materials are licensed and made available
  8. # under the terms and conditions of the BSD License which accompanies this
  9. # distribution. The full text of the license may be found at
  10. # http://opensource.org/licenses/bsd-license.php
  11. #
  12. # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  14. '''
  15. InfProtocolObject
  16. '''
  17. from Library.ParserValidate import IsValidCVariableName
  18. from Library.CommentParsing import ParseComment
  19. from Library.ExpressionValidate import IsValidFeatureFlagExp
  20. from Library.Misc import Sdict
  21. from Object.Parser.InfMisc import ErrorInInf
  22. from Library import DataType as DT
  23. from Logger import StringTable as ST
  24. def ParseProtocolComment(CommentsList, InfProtocolItemObj):
  25. CommentInsList = []
  26. PreUsage = None
  27. PreNotify = None
  28. PreHelpText = ''
  29. BlockFlag = -1
  30. Count = 0
  31. for CommentItem in CommentsList:
  32. Count = Count + 1
  33. CommentItemUsage, \
  34. CommentItemNotify, \
  35. CommentItemString, \
  36. CommentItemHelpText = \
  37. ParseComment(CommentItem,
  38. DT.PROTOCOL_USAGE_TOKENS,
  39. DT.PROTOCOL_NOTIFY_TOKENS,
  40. ['PROTOCOL'],
  41. False)
  42. if CommentItemString:
  43. pass
  44. if CommentItemHelpText == None:
  45. CommentItemHelpText = ''
  46. if Count == len(CommentsList) and CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED:
  47. CommentItemHelpText = DT.END_OF_LINE
  48. if Count == len(CommentsList):
  49. if BlockFlag == 1 or BlockFlag == 2:
  50. if CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED:
  51. BlockFlag = 4
  52. else:
  53. BlockFlag = 3
  54. elif BlockFlag == -1:
  55. BlockFlag = 4
  56. if BlockFlag == -1 or BlockFlag == 1 or BlockFlag == 2:
  57. if CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED:
  58. if BlockFlag == -1:
  59. BlockFlag = 1
  60. elif BlockFlag == 1:
  61. BlockFlag = 2
  62. else:
  63. if BlockFlag == 1 or BlockFlag == 2:
  64. BlockFlag = 3
  65. elif BlockFlag == -1:
  66. BlockFlag = 4
  67. #
  68. # Combine two comment line if they are generic comment
  69. #
  70. if CommentItemUsage == CommentItemNotify == PreUsage == PreNotify == DT.ITEM_UNDEFINED:
  71. CommentItemHelpText = PreHelpText + DT.END_OF_LINE + CommentItemHelpText
  72. PreHelpText = CommentItemHelpText
  73. if BlockFlag == 4:
  74. CommentItemIns = InfProtocolItemCommentContent()
  75. CommentItemIns.SetUsageItem(CommentItemUsage)
  76. CommentItemIns.SetNotify(CommentItemNotify)
  77. CommentItemIns.SetHelpStringItem(CommentItemHelpText)
  78. CommentInsList.append(CommentItemIns)
  79. BlockFlag = -1
  80. PreUsage = None
  81. PreNotify = None
  82. PreHelpText = ''
  83. elif BlockFlag == 3:
  84. #
  85. # Add previous help string
  86. #
  87. CommentItemIns = InfProtocolItemCommentContent()
  88. CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
  89. CommentItemIns.SetNotify(DT.ITEM_UNDEFINED)
  90. if PreHelpText == '' or PreHelpText.endswith(DT.END_OF_LINE):
  91. PreHelpText += DT.END_OF_LINE
  92. CommentItemIns.SetHelpStringItem(PreHelpText)
  93. CommentInsList.append(CommentItemIns)
  94. #
  95. # Add Current help string
  96. #
  97. CommentItemIns = InfProtocolItemCommentContent()
  98. CommentItemIns.SetUsageItem(CommentItemUsage)
  99. CommentItemIns.SetNotify(CommentItemNotify)
  100. CommentItemIns.SetHelpStringItem(CommentItemHelpText)
  101. CommentInsList.append(CommentItemIns)
  102. BlockFlag = -1
  103. PreUsage = None
  104. PreNotify = None
  105. PreHelpText = ''
  106. else:
  107. PreUsage = CommentItemUsage
  108. PreNotify = CommentItemNotify
  109. PreHelpText = CommentItemHelpText
  110. InfProtocolItemObj.SetCommentList(CommentInsList)
  111. return InfProtocolItemObj
  112. class InfProtocolItemCommentContent():
  113. def __init__(self):
  114. #
  115. # ## SOMETIMES_CONSUMES ## HelpString
  116. #
  117. self.UsageItem = ''
  118. #
  119. # Help String
  120. #
  121. self.HelpStringItem = ''
  122. self.Notify = ''
  123. self.CommentList = []
  124. def SetUsageItem(self, UsageItem):
  125. self.UsageItem = UsageItem
  126. def GetUsageItem(self):
  127. return self.UsageItem
  128. def SetNotify(self, Notify):
  129. if Notify != DT.ITEM_UNDEFINED:
  130. self.Notify = 'true'
  131. def GetNotify(self):
  132. return self.Notify
  133. def SetHelpStringItem(self, HelpStringItem):
  134. self.HelpStringItem = HelpStringItem
  135. def GetHelpStringItem(self):
  136. return self.HelpStringItem
  137. class InfProtocolItem():
  138. def __init__(self):
  139. self.Name = ''
  140. self.FeatureFlagExp = ''
  141. self.SupArchList = []
  142. self.CommentList = []
  143. def SetName(self, Name):
  144. self.Name = Name
  145. def GetName(self):
  146. return self.Name
  147. def SetFeatureFlagExp(self, FeatureFlagExp):
  148. self.FeatureFlagExp = FeatureFlagExp
  149. def GetFeatureFlagExp(self):
  150. return self.FeatureFlagExp
  151. def SetSupArchList(self, SupArchList):
  152. self.SupArchList = SupArchList
  153. def GetSupArchList(self):
  154. return self.SupArchList
  155. def SetCommentList(self, CommentList):
  156. self.CommentList = CommentList
  157. def GetCommentList(self):
  158. return self.CommentList
  159. ##
  160. #
  161. #
  162. #
  163. class InfProtocolObject():
  164. def __init__(self):
  165. self.Protocols = Sdict()
  166. #
  167. # Macro defined in this section should be only used in this section.
  168. #
  169. self.Macros = {}
  170. def SetProtocol(self, ProtocolContent, Arch = None,):
  171. __SupArchList = []
  172. for ArchItem in Arch:
  173. #
  174. # Validate Arch
  175. #
  176. if (ArchItem == '' or ArchItem == None):
  177. ArchItem = 'COMMON'
  178. __SupArchList.append(ArchItem)
  179. for Item in ProtocolContent:
  180. #
  181. # Get Comment content of this protocol
  182. #
  183. CommentsList = None
  184. if len(Item) == 3:
  185. CommentsList = Item[1]
  186. CurrentLineOfItem = Item[2]
  187. LineInfo = (CurrentLineOfItem[2], CurrentLineOfItem[1], CurrentLineOfItem[0])
  188. Item = Item[0]
  189. InfProtocolItemObj = InfProtocolItem()
  190. if len(Item) >= 1 and len(Item) <= 2:
  191. #
  192. # Only CName contained
  193. #
  194. if not IsValidCVariableName(Item[0]):
  195. ErrorInInf(ST.ERR_INF_PARSER_INVALID_CNAME%(Item[0]),
  196. LineInfo=LineInfo)
  197. if (Item[0] != ''):
  198. InfProtocolItemObj.SetName(Item[0])
  199. else:
  200. ErrorInInf(ST.ERR_INF_PARSER_CNAME_MISSING,
  201. LineInfo=LineInfo)
  202. if len(Item) == 2:
  203. #
  204. # Contained CName and Feature Flag Express
  205. # <statements> ::= <CName> ["|"
  206. # <FeatureFlagExpress>]
  207. # For Protocol Object
  208. #
  209. if Item[1].strip() == '':
  210. ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
  211. LineInfo=LineInfo)
  212. #
  213. # Validate Feature Flag Express for Item[1]
  214. #
  215. FeatureFlagRtv = IsValidFeatureFlagExp(Item[1].strip())
  216. if not FeatureFlagRtv[0]:
  217. ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
  218. LineInfo=LineInfo)
  219. InfProtocolItemObj.SetFeatureFlagExp(Item[1])
  220. if len(Item) < 1 or len(Item) > 2:
  221. #
  222. # Invalid format of Protocols statement
  223. #
  224. ErrorInInf(ST.ERR_INF_PARSER_GUID_PPI_PROTOCOL_SECTION_CONTENT_ERROR,
  225. LineInfo=LineInfo)
  226. #
  227. # Get/Set Usage and HelpString for Protocol entry
  228. #
  229. if CommentsList != None and len(CommentsList) != 0:
  230. InfProtocolItemObj = ParseProtocolComment(CommentsList, InfProtocolItemObj)
  231. else:
  232. CommentItemIns = InfProtocolItemCommentContent()
  233. CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
  234. CommentItemIns.SetNotify(DT.ITEM_UNDEFINED)
  235. InfProtocolItemObj.SetCommentList([CommentItemIns])
  236. InfProtocolItemObj.SetSupArchList(__SupArchList)
  237. #
  238. # Determine protocol name duplicate. Follow below rule:
  239. #
  240. # A protocol must not be duplicated within a [Protocols] section.
  241. # A protocol may appear in multiple architectural [Protocols]
  242. # sections. A protocol listed in an architectural [Protocols]
  243. # section must not be listed in the common architectural
  244. # [Protocols] section.
  245. #
  246. # NOTE: This check will not report error now.
  247. #
  248. for Item in self.Protocols:
  249. if Item.GetName() == InfProtocolItemObj.GetName():
  250. ItemSupArchList = Item.GetSupArchList()
  251. for ItemArch in ItemSupArchList:
  252. for ProtocolItemObjArch in __SupArchList:
  253. if ItemArch == ProtocolItemObjArch:
  254. #
  255. # ST.ERR_INF_PARSER_ITEM_DUPLICATE
  256. #
  257. pass
  258. if ItemArch.upper() == 'COMMON' or ProtocolItemObjArch.upper() == 'COMMON':
  259. #
  260. # ST.ERR_INF_PARSER_ITEM_DUPLICATE_COMMON
  261. #
  262. pass
  263. if self.Protocols.has_key((InfProtocolItemObj)):
  264. ProcotolList = self.Protocols[InfProtocolItemObj]
  265. ProcotolList.append(InfProtocolItemObj)
  266. self.Protocols[InfProtocolItemObj] = ProcotolList
  267. else:
  268. ProcotolList = []
  269. ProcotolList.append(InfProtocolItemObj)
  270. self.Protocols[InfProtocolItemObj] = ProcotolList
  271. return True
  272. def GetProtocol(self):
  273. return self.Protocols