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<header>.*)")
self.define = re.compile("^#\W*define\W+(?P<header>.*)")
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
syntax highlighted by Code2HTML, v. 0.9.1