Package licensechecker :: Module commentextractor
[hide private]
[frames] | no frames]

Source Code for Module licensechecker.commentextractor

  1  """ 
  2  Defines classes used to extract comment headers from source files with their associated information. 
  3  """ 
  4   
  5  import logging 
  6  import re 
  7  import os 
  8   
  9  import fileinfo 
 10   
11 -class CommentHeader:
12 """ 13 Class storing infomrmation about the actuel contents of a comment block and it's delimiters. 14 """
15 - def __init__(self,contents,linedelimiter,blockdelimiters,start,end):
16 """ 17 Builds a new instance of a C{CommentHeader}. 18 19 @param contents: a list of strings, where each component is a single line of the comment header. 20 @param linedelimiter: a string with the delimiter that was used for the commentblock if it was a line comment, otherwise C{None}. 21 @param blockdelimiters: a tuple of two strings with the opening and closing delimiters if the comment header was block-formatted, otherwise C{None} 22 @param start: the line number in the file where the comment header started. 23 @param end: the line number in the file where the comment header stopped. 24 25 """ 26 self.contents=contents 27 self.linedelimiter=linedelimiter 28 self.blockdelimiters=blockdelimiters 29 self.start=start 30 self.end=end
31 32
33 - def getContents(self):
34 """ 35 Returns the contents of the comment header. 36 37 @returns: a list of strings containing the lines of the comment header. 38 @rtype: [string,] 39 """ 40 return self.contents
41 42
43 - def getLineDelimiter(self):
44 """ 45 Returns the line delimiter of the comment header. 46 47 @returns: a string containing the line delimiter of the comment header (or C{None}). 48 @rtype: string 49 """ 50 return self.linedelimiter
51
52 - def getBlockDelimiters(self):
53 """ 54 Returns the block delimiter of the comment header. 55 56 @returns: a list of two strings containing the opening and closing delimiters of the comment header (or C{None}). 57 @rtype: [string,string] 58 """ 59 return self.blockdelimiters
60
61 - def getStart(self):
62 """ 63 Returns the first line of the comment header in the file. 64 65 @returns: the line number where the comment header starts (numbering starts at 1). 66 @rtype: integer. 67 """ 68 return self.start
69
70 - def getEnd(self):
71 """ 72 Returns the last line of the comment header in the file. 73 74 @returns: the line number where the comment header ends (numbering starts at 1). 75 @rtype: integer. 76 """ 77 return self.end
78 79
80 -class CommentExtractor:
81 """ 82 Class taking care of the extraction of the initial comment block in source files. 83 """ 84 85 __logger=logging.getLogger('lichk') 86
87 - def __init__(self,fd,commentinfo) :
88 """ 89 Builds a new instance of L{CommentExtractor}. 90 91 @param fd: a file object from which content will be read. 92 @param commentinfo: a L{CommentInfo} object defining how line and block comments are delimited in this file. 93 """ 94 self.fd=fd 95 self.commentinfo=commentinfo
96
97 - def getCommentHeader(self) :
98 """ 99 Returns a comment header if found. 100 101 @returns: an instance of L{CommentHeader} with the information about the comment header block, or C{None} if no such block was found. 102 @rtype: L{CommentHeader} 103 """ 104 105 # Initialise what will become attribute values for the resulting L{CommentBlock} instance. 106 commentheader=None 107 blockcontents=[] 108 linedelimiter=None 109 start=-1 110 end=-1 111 112 113 try : 114 # Read first line of file. 115 linebuffer=self.fd.readline() 116 linenumber=1 117 118 # Skip shebang if present. 119 if re.match('#!/',linebuffer): 120 self.__logger.debug("Skipping shebang.") 121 linebuffer=self.fd.readline() 122 linenumber=linenumber+1 123 124 # Skip blank header lines. 125 line=linebuffer.strip() 126 while len(line) == 0 : 127 linebuffer=self.fd.readline() 128 linenumber=linenumber+1 129 line=linebuffer.strip() 130 pass 131 132 # Initialise variable that will determine if after trying to 133 # look for a line-comment header, we'll need to look for a block 134 # comment header. 135 lookforblock=True 136 137 # Check if first non blank line starts with line-comment. 138 linecomments=self.commentinfo.getLineComments() 139 while 1 : 140 incomment=False 141 for linecomment in linecomments : 142 if line.startswith(linecomment): 143 incomment=True 144 lookforblock=False 145 blockcontents.append(linebuffer) 146 linedelimiter=linecomment 147 if start < 0 : 148 start=linenumber 149 end=linenumber 150 else : 151 end=linenumber 152 153 try : 154 linebuffer=self.fd.readline() 155 linenumber=linenumber+1 156 line=linebuffer.strip() 157 except IOError : 158 incomment=False 159 break 160 if incomment==False : 161 break 162 163 # Check if we need to parse for block comment header. 164 openingdelimiter=None 165 closingdelimiter=None 166 if lookforblock == True : 167 blockcomments=self.commentinfo.getBlockComments() 168 # Check if first non blank line starts with opening block delimiter. 169 incomment=False 170 for blockcomment in blockcomments : 171 # Look for opening block delimiter. 172 openingdelimiter=blockcomment[0] 173 if line.startswith(openingdelimiter): 174 self.__logger.debug("Found opening delimiter %s in (%s)"%(blockcomment[0],line)) 175 incomment=True 176 start=linenumber 177 blockcontents.append(linebuffer) 178 closingdelimiter=blockcomment[1] 179 # Check if block comment is single line... 180 if line.endswith(closingdelimiter): 181 self.__logger.debug("Found closing delimiter %s in (%s)"%(closingdelimiter,line)) 182 end=linenumber 183 incomment=False 184 break 185 while incomment==True: 186 try : 187 linebuffer=self.fd.readline() 188 linenumber=linenumber+1 189 blockcontents.append(linebuffer) 190 line=linebuffer.strip() 191 # Look for closing block delimiter 192 if line.endswith(closingdelimiter): 193 self.__logger.debug("Found closing delimiter %s in (%s)"%(closingdelimiter,line)) 194 end=linenumber 195 incomment=False 196 except IOError : 197 break 198 199 except IOError : 200 self.__logger.debug("IOError when reading comment block.") 201 pass 202 if len(blockcontents)>0 : 203 commentheader=CommentHeader(blockcontents,linedelimiter,(openingdelimiter,closingdelimiter),start,end) 204 205 206 return commentheader
207