import re import sys import string import clint class Stack: def __init__(self, start=[]): self.stack = None for i in range(-len(start), 0): self.push(start[-i - 1]) def push(self,node): self.stack = node, self.stack def pop(self): node, self.stack = self.stack return node def top(self): node = self.pop() self.push(node) return node def empty(self): return not self.stack class header_guard(clint.Rule): def initialize(self): self.stack = Stack() self.gather_info() self.ifndef = re.compile("^#\W*ifndef\W+(?P
.*)") self.define = re.compile("^#\W*define\W+(?P
.*)") def gather_info(self): self.current_info = {} self.current_info['filename'] = self.file() self.current_info['have_ifndef'] = 0 self.current_info['have_define'] = 0 self.current_info['reported_error'] = 0 self.current_info['guard_name'] = "" def pop(self): self.current_info = self.stack.pop() def top(self): return self.stack.top() def push(self): self.stack.push(self.current_info) self.gather_info() def pre_cpp(self,line): # deal with changing files if self.current_info['filename'] != self.file(): # The file has changed if self.top()['filename'] == self.file(): # we have gone back a file self.pop() else: # We are in a new file self.push() # now preform the test if self.is_header() and not self.is_system_header and not self.current_info['reported_error']: # strip comments and then whitespace from the line line = string.strip(self.remove_comments(line)) if line != "": #and self.current_info['have_ifndef'] == 0 and self.current_info['have_define'] == 0: if self.current_info['have_ifndef'] == 0: # we haven't found #ifndef yet match = self.ifndef.match(line) if match: # we have found #ifndef self.current_info['have_ifndef'] = self.line() self.current_info['guard_name'] = match.group('header') else: # we haven't found a #ifndef self.error() elif self.current_info['have_define'] == 0: # we have found #ifndef, now look for #define match = self.define.match(line) if match: # we found a #define self.current_info['have_define'] = self.line() if self.current_info['guard_name'] != match.group('header'): # the guard name doesn't match the #define self.error() else: # we haven't found a #define self.error() def error(self): self.message("You should protect the header file with #ifndef / #define") self.current_info['reported_error'] = 1