tcl script to parse C++ source code for type identifiers Experimenting with vera++ to validate some C++ source files.
https://bitbucket.org/verateam/vera/wiki/Home

vera++ is expandable by providing your own rules in tcl. To interface with the vera++ parser the following interface is provided:
https://bitbucket.org/verateam/vera/wiki/ScriptAPI

Using the above I have written a rule to look for type identifiers and validate that they have an initial uppercase letter.

#!/usr/bin/tclsh
# Check that Type identifiers have an initial uppercase letter.

# namespace TypeName
# class TypeName
# struct TypeName
# enum TypeName {  EnumTypeName1, EnumTypeName2 }
#
# Will ignore `using clauses`
#   using &lt;Stuff&gt; ;
#
# Thus when "using" stuff from other namespace we don't check (as they don't belong to us)
# Also it allows you to convert any external types to local names.
#
#   #include &lt;sys/socket.h&gt;
#   #include &lt;sys/types.h&gt;
#   // STUFF
#           sockaddr_in serv_addr;
#           // STUFF
#           if (::connect(socket, reinterpret_cast&lt;struct sockaddr*&gt;(&amp;serv_addr), sizeof(serv_addr)) &lt; 0)
#                                                   ^^^^^^^^^^^^    this fails.
# But you can write it like this:
#
#           using SockAddr = struct sockaddr;   // Allowed because &gt;using &lt;stuff&gt;;&lt; is ignored.
#           if (::connect(socket, reinterpret_cast&lt;SockAddr*&gt;(&amp;serv_addr), sizeof(serv_addr)) &lt; 0)
#


set state "start"
foreach f [getSourceFileNames] {
    foreach t [getTokens $f 1 0 -1 -1 {}] {
        set tokenName [lindex $t 3]
        set checkTypeName 0
        if {$tokenName == "space"} {
            #ignore space
        } else {
            if {$state == "start" &amp;&amp; $tokenName == "namespace"} {
                set state "CheckIdnetifier"
            } elseif {$state == "start" &amp;&amp; $tokenName == "class"} {
                set state "CheckIdnetifier"
            } elseif {$state == "start" &amp;&amp; $tokenName == "struct"} {
                set state "CheckIdnetifier"
            } elseif {$state == "start" &amp;&amp; $tokenName == "using"} {
                set state "using"
            } elseif {$state == "using" &amp;&amp; $tokenName == "semicolon"} {
                set state "start"
            } elseif {$state == "using"} {
                #ignore
            } elseif {$state == "start" &amp;&amp; $tokenName == "enum"} {
                set state "enum"
            } elseif {$state == "enum" &amp;&amp; $tokenName == "identifier"} {
                set checkTypeName 1
            } elseif {$state == "enum" &amp;&amp; $tokenName == "leftbrace"} {
                set state "enumOpen"
            } elseif {$state == "enumOpen" &amp;&amp; $tokenName == "identifier"} {
                set checkTypeName 1
            } elseif {$state == "enumOpen" &amp;&amp; $tokenName == "comma"} {
                # ignore
            } elseif {$state == "enumOpen" &amp;&amp; $tokenName == "rightbrace"} {
                set state "start"
            } elseif {$state == "CheckIdnetifier" &amp;&amp; $tokenName == "identifier"} {
                set checkTypeName 1
                set state "start"
            } else {
                set state "start"
            }
        }
        if {$checkTypeName} {
            set identifier [lindex $t 0]
            set firstLetter [string index $identifier 0]
            if {[expr ! [string is upper $firstLetter]]} {
                set lineNumber [lindex $t 1]
                report $f $lineNumber "Objects &gt;$identifier&lt; (Type) should have an initial upper case letter"
            }
        }
    }
}
You are checking 5 times if $state equals to "start" and several times for the other "states". You should compact this and maybe a switch would be better.



You have a spelling error CheckIdnetifier which should be corrected.