## @file
# This file is used to parse DEC file. It will consumed by DecParser
#
# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available
# under the terms and conditions of the BSD License which accompanies this
# distribution. The full text of the license may be found at
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
'''
DecParser
'''
## Import modules
#
##
# _DecBase class for parsing
#
class _DecBase:
self._LocalMacro = {}
#
# Data parsed by 'self' are saved to this object
#
self.ItemObject = None
return self.ItemObject
## BlockStart
#
# Called if a new section starts
#
self._LocalMacro = {}
## _CheckReDefine
#
# @param Key: to be checked if multi-defined
# @param Scope: Format: [[SectionName, Arch], ...].
# If scope is none, use global scope
#
if not Scope:
return
SecArch = []
#
# Copy scope to SecArch, avoid Scope be changed outside
#
return
#
# If current is common section
#
# Key in common cannot be redefined in other arches
# [:-1] means stripping arch info
return
continue
CommonScope = []
#
# Cannot be redefined if this key already defined in COMMON Or defined in same arch
#
return
## CheckRequiredFields
# Some sections need to check if some fields exist, define section for example
# Derived class can re-implement, top parser will call this function after all parsing done
#
pass
return True
## IsItemRequired
# In DEC spec, sections must have at least one statement except user
# extension.
# For example: "[guids" [<attribs>] "]" <EOL> <statements>+
# sub class can override this method to indicate if statement is a must.
#
pass
return False
if MacroUsed:
return String
else:
## _ParseItem
#
# Parse specified item, this function must be derived by subclass
#
pass
#
# Should never be called
#
return None
## _TailCommentStrategy
#
# This function can be derived to parse tail comment
# default is it will not consume any lines
#
# @param Comment: Comment of current line
#
if Comment:
pass
pass
return False
## _StopCurrentParsing
#
# Called in Parse if current parsing should be stopped when encounter some
# keyword
# Default is section start and end
#
# @param Line: Current line
#
pass
## _TryBackSlash
#
# Split comment and DEC content, concatenate lines if end of char is '\'
#
# @param ProcessedLine: ProcessedLine line
# @param ProcessedComments: ProcessedComments line
#
CatLine = ''
Comment = ''
if Line == '':
break
if Comment:
break
else:
#
# Reach end of content
#
if not CatLine:
else:
return CatLine, CommentList
## Parse
# This is a template method in which other member functions which might
# override by sub class are called. It is responsible for reading file
# line by line, and call other member functions to parse. This function
# should not be re-implement by sub class.
#
HeadComments = []
TailComments = []
#======================================================================
# CurComments may pointer to HeadComments or TailComments
#======================================================================
CurObj = None
ItemNum = 0
#======================================================================
# Used to report error information if empty section found
#======================================================================
#==============================================================
# Have processed line in buffer
#==============================================================
Comment = ''
else:
#==============================================================
# No line in buffer, read next line
#==============================================================
if Line:
#==========================================================
# Set tail comments to previous statement if not empty.
#==========================================================
if not FromBuf:
del TailComments[:]
Comments = []
if Comment:
#==============================================================
# Try if last char of line has backslash
#==============================================================
#==============================================================
# Macro found
#==============================================================
del HeadComments[:]
del TailComments[:]
continue
#==========================================================
# This line does not belong to this parse,
# Save it, can be used by next parse
#==========================================================
break
ItemNum += 1
if Obj:
del HeadComments[:]
del TailComments[:]
else:
CurObj = None
else:
#==========================================================
# Check if this comment belongs to tail comment
#==========================================================
if Comment:
else:
del CurComments[:]
)
## _DecDefine
# Parse define section
#
#
# Each field has a function to validate
#
self.DefineValidation = {
}
## CheckRequiredFields
#
# Check required fields: DEC_SPECIFICATION, PACKAGE_NAME
# PACKAGE_GUID, PACKAGE_VERSION
#
else:
return Ret
pass
else:
return DefineItem
if not IsValidWord(Token):
if not CheckGuidRegFormat(Token):
else:
## _DecInclude
#
# Parse include section
#
return Item
## _DecLibraryclass
#
# Parse library class section
#
#
# Must end with .h
#
#
# Path must be existed
#
return Item
## _DecPcd
#
# Parse PCD section
#
#
# Used to check duplicate token
# Key is token space and token number (integer), value is C name
#
#
# Token space guid C name
#
#
# PCD C name
#
#
# Default value, may be C array, string or number
#
#
# PCD data type
#
if not Valid:
#
# Token value is the last element in list.
#
else:
return Item
## _DecGuid
#
# Parse GUID, PPI, Protocol section
#
self.ObjectDict = \
{
}
return None
return self.ProtocolObj
else:
#
# Convert C format GUID to GUID string and Simple error check
#
#
# Check C format GUID
#
return Item
## _DecUserExtension
#
# Parse user extention section
#
else:
break
else:
self._LocalMacro = {}
Item = None
if Item.UserString:
else:
return Item
## Dec
#
# Top dec parser
#
try:
except BaseException:
#
# DEC file supported data types (one type per section)
#
self._SectionParser = {
}
if Parse:
#
# Parsing done, check required fields
#
if not SectionParser.CheckRequiredFields():
return False
return True
##
# Parse DEC file
#
#
# Header must be pure comment
#
if Line != '':
break
if Comment:
#
# Double '#' indicates end of header comments
#
break
return
return False
return SectionObj.GetDataObject()
#
# User extention
#
#
# UserID
#
if not IsValidUserId(Token):
#
# IdString
#
if not IsValidIdString(Token):
Arch = 'COMMON'
if not IsValidArch(Arch):
)
break
## Section header parser
#
# The section header is always in following format:
#
# [section_name.arch<.platform|module_type>]
#
if self._RawData.CurrentLine[0] != DT.TAB_SECTION_START or self._RawData.CurrentLine[-1] != DT.TAB_SECTION_END:
#
# Check defines section which is only allowed to occur once and
# no arch can be followed
#
#
# Check user extension section
#
return self._UserExtentionSectionParser()
SectionNames = []
if Item == '':
#
# different types of PCD are permissible in one section
#
if SectionName not in SectionNames:
#
# In DEC specification, all section headers have at most two part:
# SectionName.Arch except UserExtention
#
#
# S1 is always Arch
#
if not IsValidArch(Str1):
else:
Str1 = 'COMMON'
#
# 'COMMON' must not be used with specific ARCHs at the same section
#
for Sec in SectionNames: