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
78
79
81 """
82 Class taking care of the extraction of the initial comment block in source files.
83 """
84
85 __logger=logging.getLogger('lichk')
86
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
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
106 commentheader=None
107 blockcontents=[]
108 linedelimiter=None
109 start=-1
110 end=-1
111
112
113 try :
114
115 linebuffer=self.fd.readline()
116 linenumber=1
117
118
119 if re.match('#!/',linebuffer):
120 self.__logger.debug("Skipping shebang.")
121 linebuffer=self.fd.readline()
122 linenumber=linenumber+1
123
124
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
133
134
135 lookforblock=True
136
137
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
164 openingdelimiter=None
165 closingdelimiter=None
166 if lookforblock == True :
167 blockcomments=self.commentinfo.getBlockComments()
168
169 incomment=False
170 for blockcomment in blockcomments :
171
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
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
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