Lot of untested changes.
[confparser-old] / mfvalidator.py
1 from validator import *
2
3 #
4 # Configuration parser check *syntax*.
5 # Validator check *structure*, and eventually some values.
6 #
7
8 #-----------------------------------------------------------------------------
9
10 class Keyword( Validator ) : pass
11
12 class Header( Validator ) :
13
14         allowedMatches = [ 'is' , 'contains' , 'match' ]
15
16         def check( self , values ) :
17
18                 if len( values ) != 3 :
19                         error( 'header HEADER-NAME MATCH-TYPE MATCH-ARGUMENT ;' )
20                 elif values[ 1 ] not in self.allowedMatches :
21                         error( 'Allowed matches type in header rule are: %r' % self.allowedMatches )
22
23 #-----------------------------------------------------------------------------
24
25 class Logical( Validator , MixinNonEmpty ) :
26
27         def descend( self , item ) :
28
29                 self.children += 1
30                 return ruleValidator( item )
31
32 class Reject( Validator , MixinNonEmpty ) :
33
34         def descend( self , item ) :
35
36                 self.children += 1
37                 return ruleValidator( item )
38
39         def check( self , values ) :
40
41                 if len( values ) != 1 :
42                         error( 'reject CODE { .. }' )
43
44 class Folder( Validator , MixinNonEmpty ) :
45
46         def descend( self , item ) :
47
48                 self.children += 1
49                 return ruleValidator( item )
50
51         def check( self , values ) :
52
53                 if len( values ) != 1 :
54                         error( 'folder FOLDER-NAME { .. }' )
55
56 #-----------------------------------------------------------------------------
57
58 def ruleValidator( item ) :
59
60         if item in [ 'broken' , 'infected' , 'spam' ] :
61                 return Keyword( item )
62         elif item in [ 'or' , 'and' , 'not' ] :
63                 return Logical( item )
64         elif item == 'header' :
65                 return Header( item )
66         else :
67                 error( 'Invalid keyword `%r\'.' % item )
68
69 #-----------------------------------------------------------------------------
70
71 class Root( Validator ) :
72
73         def descend( self , item ) :
74
75                 if item == 'reject' :
76                         return Reject( item )
77                 elif item == 'folder' :
78                         return Folder( item )
79                 else :
80                         error( 'Invalid keyword `%r\'.' % item )
81
82         def values( self , values ) :
83
84                 raise Exception( 'Internal error' )
85
86 #-----------------------------------------------------------------------------
87
88 def checkConf( confNode ) :
89
90         checkConf.lastNode = confNode
91
92         def _checkConf( confNode , syntaxNode ) :
93
94                 checkConf.lastNode = confNode
95                 name , values , contents , meta = confNode
96                 r = syntaxNode.descend( name )
97                 r.check( values )
98                 for item in contents :
99                         _checkConf( item , r )
100                 r.valid()
101
102         name , values , contents , info = confNode
103         root = Root( '__root__' )
104         try :
105                 for item in contents :
106                         _checkConf( item , root )
107         except ValidatorError , e :
108                 return e , checkConf.lastNode
109
110 def checkFile( filename ) :
111
112         import confparser
113
114         doc = open( filename ).read()
115         doc = confparser.parse( doc )
116         r = checkConf( doc )
117         print '%s:' % filename ,
118         if r :
119                 exception , node = r
120                 meta = node[ 3 ]
121                 msg = 'at line %s, column %s' % ( meta[ 0 ] , meta[ 1 ] )
122                 if meta[ 2 ] :
123                         msg = 'in file %s, ' % meta[ 2 ] + msg
124                 print '%s: %s' % ( msg , exception )
125         else :
126                 print 'ok'