1425bb815Sopenharmony_ci#!/usr/bin/tclsh 2425bb815Sopenharmony_ci 3425bb815Sopenharmony_ci# Copyright JS Foundation and other contributors, http://js.foundation 4425bb815Sopenharmony_ci# 5425bb815Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 6425bb815Sopenharmony_ci# you may not use this file except in compliance with the License. 7425bb815Sopenharmony_ci# You may obtain a copy of the License at 8425bb815Sopenharmony_ci# 9425bb815Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 10425bb815Sopenharmony_ci# 11425bb815Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 12425bb815Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS 13425bb815Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14425bb815Sopenharmony_ci# See the License for the specific language governing permissions and 15425bb815Sopenharmony_ci# limitations under the License. 16425bb815Sopenharmony_ci 17425bb815Sopenharmony_ci# switch-case 18425bb815Sopenharmony_ci 19425bb815Sopenharmony_ciforeach fileName [getSourceFileNames] { 20425bb815Sopenharmony_ci set is_in_comment "no" 21425bb815Sopenharmony_ci set is_in_pp_define "no" 22425bb815Sopenharmony_ci 23425bb815Sopenharmony_ci foreach token [getTokens $fileName 1 0 -1 -1 {}] { 24425bb815Sopenharmony_ci set type [lindex $token 3] 25425bb815Sopenharmony_ci set lineNumber [lindex $token 1] 26425bb815Sopenharmony_ci 27425bb815Sopenharmony_ci if {$is_in_comment == "yes"} { 28425bb815Sopenharmony_ci set is_in_comment "no" 29425bb815Sopenharmony_ci } 30425bb815Sopenharmony_ci 31425bb815Sopenharmony_ci if {$type == "newline"} { 32425bb815Sopenharmony_ci set is_in_pp_define "no" 33425bb815Sopenharmony_ci } elseif {$type == "ccomment"} { 34425bb815Sopenharmony_ci set is_in_comment "yes" 35425bb815Sopenharmony_ci } elseif {[string first "pp_" $type] == 0} { 36425bb815Sopenharmony_ci if {$type == "pp_define"} { 37425bb815Sopenharmony_ci set is_in_pp_define "yes" 38425bb815Sopenharmony_ci } 39425bb815Sopenharmony_ci } elseif {$type == "space"} { 40425bb815Sopenharmony_ci } elseif {$type != "eof"} { 41425bb815Sopenharmony_ci if {$is_in_pp_define == "no" && $type == "switch"} { 42425bb815Sopenharmony_ci set next_token_start [lindex $token 2] 43425bb815Sopenharmony_ci incr next_token_start 1 44425bb815Sopenharmony_ci set line_num 0 45425bb815Sopenharmony_ci set state "switch" 46425bb815Sopenharmony_ci set case_block "no" 47425bb815Sopenharmony_ci set seen_braces 0 48425bb815Sopenharmony_ci foreach next_token [getTokens $fileName $lineNumber $next_token_start -1 -1 {}] { 49425bb815Sopenharmony_ci set next_token_type [lindex $next_token 3] 50425bb815Sopenharmony_ci set next_token_value [lindex $next_token 0] 51425bb815Sopenharmony_ci if {$state == "switch"} { 52425bb815Sopenharmony_ci if {$next_token_type == "ccomment" || $next_token_type == "space" || $next_token_type == "newline"} { 53425bb815Sopenharmony_ci continue 54425bb815Sopenharmony_ci } elseif {$next_token_type == "leftbrace"} { 55425bb815Sopenharmony_ci set state "first-case" 56425bb815Sopenharmony_ci continue 57425bb815Sopenharmony_ci } else { 58425bb815Sopenharmony_ci # TODO: check switch 59425bb815Sopenharmony_ci continue 60425bb815Sopenharmony_ci } 61425bb815Sopenharmony_ci } elseif {$state == "first-case"} { 62425bb815Sopenharmony_ci if {$next_token_type == "ccomment" || $next_token_type == "space" || $next_token_type == "newline"} { 63425bb815Sopenharmony_ci continue 64425bb815Sopenharmony_ci } elseif {$next_token_type == "case"} { 65425bb815Sopenharmony_ci set state "case" 66425bb815Sopenharmony_ci continue 67425bb815Sopenharmony_ci } elseif {$next_token_type == "default"} { 68425bb815Sopenharmony_ci set state "default" 69425bb815Sopenharmony_ci continue 70425bb815Sopenharmony_ci } else { 71425bb815Sopenharmony_ci # Macros magic: give up 72425bb815Sopenharmony_ci break 73425bb815Sopenharmony_ci } 74425bb815Sopenharmony_ci } elseif {$state == "case"} { 75425bb815Sopenharmony_ci if {$next_token_type == "space"} { 76425bb815Sopenharmony_ci set state "space-after-case" 77425bb815Sopenharmony_ci continue 78425bb815Sopenharmony_ci } else { 79425bb815Sopenharmony_ci report $fileName [lindex $next_token 1] "There should be single space character after 'case' keyword (state $state)" 80425bb815Sopenharmony_ci } 81425bb815Sopenharmony_ci } elseif {$state == "space-after-case"} { 82425bb815Sopenharmony_ci if {$next_token_type != "identifier" && $next_token_type != "intlit" && $next_token_type != "charlit" && $next_token_type != "sizeof"} { 83425bb815Sopenharmony_ci report $fileName [lindex $next_token 1] "There should be single space character after 'case' keyword (state $state, next_token_type $next_token_type)" 84425bb815Sopenharmony_ci } else { 85425bb815Sopenharmony_ci set state "case-label" 86425bb815Sopenharmony_ci continue 87425bb815Sopenharmony_ci } 88425bb815Sopenharmony_ci } elseif {$state == "case-label" || $state == "default"} { 89425bb815Sopenharmony_ci set case_block "no" 90425bb815Sopenharmony_ci if {$next_token_type != "colon"} { 91425bb815Sopenharmony_ci continue 92425bb815Sopenharmony_ci } else { 93425bb815Sopenharmony_ci set state "colon" 94425bb815Sopenharmony_ci continue 95425bb815Sopenharmony_ci } 96425bb815Sopenharmony_ci } elseif {$state == "after-colon-preprocessor"} { 97425bb815Sopenharmony_ci if {$next_token_type == "newline"} { 98425bb815Sopenharmony_ci set state "colon" 99425bb815Sopenharmony_ci } 100425bb815Sopenharmony_ci } elseif {$state == "colon"} { 101425bb815Sopenharmony_ci if {$next_token_type == "space" || $next_token_type == "newline"} { 102425bb815Sopenharmony_ci continue 103425bb815Sopenharmony_ci } elseif {$next_token_type == "ccomment"} { 104425bb815Sopenharmony_ci if {[string match "*FALL*" $next_token_value]} { 105425bb815Sopenharmony_ci set state "fallthru" 106425bb815Sopenharmony_ci set line_num [lindex $next_token 1] 107425bb815Sopenharmony_ci continue 108425bb815Sopenharmony_ci } else { 109425bb815Sopenharmony_ci continue 110425bb815Sopenharmony_ci } 111425bb815Sopenharmony_ci } elseif {$next_token_type == "case"} { 112425bb815Sopenharmony_ci set state "case" 113425bb815Sopenharmony_ci continue 114425bb815Sopenharmony_ci } elseif {$next_token_type == "default"} { 115425bb815Sopenharmony_ci set state "default" 116425bb815Sopenharmony_ci continue 117425bb815Sopenharmony_ci } elseif {$next_token_type == "leftbrace"} { 118425bb815Sopenharmony_ci set case_block "yes" 119425bb815Sopenharmony_ci set state "wait-for-break" 120425bb815Sopenharmony_ci continue 121425bb815Sopenharmony_ci } elseif {$next_token_type == "identifier"} { 122425bb815Sopenharmony_ci if {[string compare "JERRY_UNREACHABLE" $next_token_value] == 0 123425bb815Sopenharmony_ci || [string first "JERRY_UNIMPLEMENTED" $next_token_value] == 0} { 124425bb815Sopenharmony_ci set state "wait-for-semicolon" 125425bb815Sopenharmony_ci continue 126425bb815Sopenharmony_ci } else { 127425bb815Sopenharmony_ci set state "wait-for-break" 128425bb815Sopenharmony_ci continue 129425bb815Sopenharmony_ci } 130425bb815Sopenharmony_ci } elseif {$next_token_type == "break" 131425bb815Sopenharmony_ci || $next_token_type == "continue" 132425bb815Sopenharmony_ci || $next_token_type == "return"} { 133425bb815Sopenharmony_ci set state "wait-for-semicolon" 134425bb815Sopenharmony_ci continue 135425bb815Sopenharmony_ci } elseif {[string first "pp_" $next_token_type] == 0} { 136425bb815Sopenharmony_ci set state "after-colon-preprocessor" 137425bb815Sopenharmony_ci } else { 138425bb815Sopenharmony_ci set state "wait-for-break" 139425bb815Sopenharmony_ci continue 140425bb815Sopenharmony_ci } 141425bb815Sopenharmony_ci } elseif {$state == "wait-for-semicolon"} { 142425bb815Sopenharmony_ci if {$next_token_type == "semicolon"} { 143425bb815Sopenharmony_ci set state "break" 144425bb815Sopenharmony_ci } 145425bb815Sopenharmony_ci continue 146425bb815Sopenharmony_ci } elseif {$state == "wait-for-break"} { 147425bb815Sopenharmony_ci if {$next_token_type == "case" || $next_token_type == "default"} { 148425bb815Sopenharmony_ci report $fileName [lindex $next_token 1] "Missing break, continue or FALLTHRU comment before case (state $state)" 149425bb815Sopenharmony_ci } elseif {$next_token_type == "leftbrace"} { 150425bb815Sopenharmony_ci set state "inside-braces" 151425bb815Sopenharmony_ci incr seen_braces 1 152425bb815Sopenharmony_ci continue 153425bb815Sopenharmony_ci } elseif {$next_token_type == "rightbrace"} { 154425bb815Sopenharmony_ci if {$case_block == "yes"} { 155425bb815Sopenharmony_ci set state "case-blocks-end" 156425bb815Sopenharmony_ci continue 157425bb815Sopenharmony_ci } else { 158425bb815Sopenharmony_ci break 159425bb815Sopenharmony_ci } 160425bb815Sopenharmony_ci } elseif {[string compare "JERRY_UNREACHABLE" $next_token_value] == 0 161425bb815Sopenharmony_ci || [string first "JERRY_UNIMPLEMENTED" $next_token_value] == 0} { 162425bb815Sopenharmony_ci set state "wait-for-semicolon" 163425bb815Sopenharmony_ci continue 164425bb815Sopenharmony_ci } elseif {$next_token_type == "ccomment" && [string match "*FALL*" $next_token_value]} { 165425bb815Sopenharmony_ci set state "fallthru" 166425bb815Sopenharmony_ci set line_num [lindex $next_token 1] 167425bb815Sopenharmony_ci continue 168425bb815Sopenharmony_ci } elseif {$next_token_type == "break" 169425bb815Sopenharmony_ci || $next_token_type == "continue" 170425bb815Sopenharmony_ci || $next_token_type == "return" 171425bb815Sopenharmony_ci || $next_token_type == "goto"} { 172425bb815Sopenharmony_ci set state "wait-for-semicolon" 173425bb815Sopenharmony_ci continue 174425bb815Sopenharmony_ci } 175425bb815Sopenharmony_ci continue 176425bb815Sopenharmony_ci } elseif {$state == "break" || $state == "fallthru"} { 177425bb815Sopenharmony_ci if {$case_block == "no"} { 178425bb815Sopenharmony_ci if {$next_token_type == "ccomment" || $next_token_type == "space" || $next_token_type == "newline"} { 179425bb815Sopenharmony_ci continue 180425bb815Sopenharmony_ci } elseif {$next_token_type == "case"} { 181425bb815Sopenharmony_ci set state "case" 182425bb815Sopenharmony_ci continue 183425bb815Sopenharmony_ci } elseif {$next_token_type == "default"} { 184425bb815Sopenharmony_ci set state "default" 185425bb815Sopenharmony_ci continue 186425bb815Sopenharmony_ci } elseif {$next_token_type == "leftbrace"} { 187425bb815Sopenharmony_ci set state "inside-braces" 188425bb815Sopenharmony_ci incr seen_braces 1 189425bb815Sopenharmony_ci continue 190425bb815Sopenharmony_ci } elseif {$next_token_type == "rightbrace"} { 191425bb815Sopenharmony_ci lappend switch_ends [lindex $next_token 1] 192425bb815Sopenharmony_ci break 193425bb815Sopenharmony_ci } elseif {$next_token_type == "break" 194425bb815Sopenharmony_ci || $next_token_type == "continue" 195425bb815Sopenharmony_ci || $next_token_type == "return"} { 196425bb815Sopenharmony_ci set state "wait-for-semicolon" 197425bb815Sopenharmony_ci continue 198425bb815Sopenharmony_ci } else { 199425bb815Sopenharmony_ci set state "wait-for-break" 200425bb815Sopenharmony_ci continue 201425bb815Sopenharmony_ci } 202425bb815Sopenharmony_ci } else { 203425bb815Sopenharmony_ci if {$next_token_type == "ccomment" || $next_token_type == "space" || $next_token_type == "newline"} { 204425bb815Sopenharmony_ci continue 205425bb815Sopenharmony_ci } elseif {$next_token_type == "case"} { 206425bb815Sopenharmony_ci set state "case" 207425bb815Sopenharmony_ci continue 208425bb815Sopenharmony_ci } elseif {$next_token_type == "default"} { 209425bb815Sopenharmony_ci set state "default" 210425bb815Sopenharmony_ci continue 211425bb815Sopenharmony_ci } elseif {$next_token_type == "leftbrace"} { 212425bb815Sopenharmony_ci set state "inside-braces" 213425bb815Sopenharmony_ci incr seen_braces 1 214425bb815Sopenharmony_ci continue 215425bb815Sopenharmony_ci } elseif {$next_token_type == "rightbrace"} { 216425bb815Sopenharmony_ci set state "after-rightbrace" 217425bb815Sopenharmony_ci continue 218425bb815Sopenharmony_ci } elseif {$next_token_type == "break" 219425bb815Sopenharmony_ci || $next_token_type == "continue" 220425bb815Sopenharmony_ci || $next_token_type == "return"} { 221425bb815Sopenharmony_ci set state "wait-for-semicolon" 222425bb815Sopenharmony_ci continue 223425bb815Sopenharmony_ci } else { 224425bb815Sopenharmony_ci set state "wait-for-break" 225425bb815Sopenharmony_ci continue 226425bb815Sopenharmony_ci } 227425bb815Sopenharmony_ci } 228425bb815Sopenharmony_ci } elseif {$state == "inside-braces"} { 229425bb815Sopenharmony_ci if {$next_token_type == "rightbrace"} { 230425bb815Sopenharmony_ci incr seen_braces -1 231425bb815Sopenharmony_ci if {$seen_braces == 0} { 232425bb815Sopenharmony_ci set state "wait-for-break" 233425bb815Sopenharmony_ci continue 234425bb815Sopenharmony_ci } 235425bb815Sopenharmony_ci } elseif {$next_token_type == "leftbrace"} { 236425bb815Sopenharmony_ci incr seen_braces 1 237425bb815Sopenharmony_ci } 238425bb815Sopenharmony_ci continue 239425bb815Sopenharmony_ci } elseif {$state == "after-rightbrace-preprocessor"} { 240425bb815Sopenharmony_ci if {$next_token_type == "newline"} { 241425bb815Sopenharmony_ci set state "after-rightbrace" 242425bb815Sopenharmony_ci } 243425bb815Sopenharmony_ci } elseif {$state == "after-rightbrace"} { 244425bb815Sopenharmony_ci if {$next_token_type == "ccomment" || $next_token_type == "space" || $next_token_type == "newline"} { 245425bb815Sopenharmony_ci continue 246425bb815Sopenharmony_ci } elseif {$next_token_type == "case"} { 247425bb815Sopenharmony_ci set state "case" 248425bb815Sopenharmony_ci continue 249425bb815Sopenharmony_ci } elseif {$next_token_type == "default"} { 250425bb815Sopenharmony_ci set state "default" 251425bb815Sopenharmony_ci continue 252425bb815Sopenharmony_ci } elseif {$next_token_type == "rightbrace"} { 253425bb815Sopenharmony_ci lappend switch_ends [lindex $next_token 1] 254425bb815Sopenharmony_ci break 255425bb815Sopenharmony_ci } elseif {[string first "pp_" $next_token_type] == 0} { 256425bb815Sopenharmony_ci set state "after-rightbrace-preprocessor" 257425bb815Sopenharmony_ci } else { 258425bb815Sopenharmony_ci report $fileName [lindex $next_token 1] "There should be 'case' or 'default' (state $state)" 259425bb815Sopenharmony_ci } 260425bb815Sopenharmony_ci } elseif {$state == "case-blocks-end-preprocessor"} { 261425bb815Sopenharmony_ci if {$next_token_type == "newline"} { 262425bb815Sopenharmony_ci set state "case-blocks-end" 263425bb815Sopenharmony_ci } 264425bb815Sopenharmony_ci } elseif {$state == "case-blocks-end"} { 265425bb815Sopenharmony_ci if {$next_token_type == "ccomment" || $next_token_type == "space" || $next_token_type == "newline"} { 266425bb815Sopenharmony_ci continue 267425bb815Sopenharmony_ci } elseif {$next_token_type == "rightbrace"} { 268425bb815Sopenharmony_ci lappend switch_ends [lindex $next_token 1] 269425bb815Sopenharmony_ci break 270425bb815Sopenharmony_ci } elseif {[string first "pp_" $next_token_type] == 0} { 271425bb815Sopenharmony_ci set state "case-blocks-end-preprocessor" 272425bb815Sopenharmony_ci } else { 273425bb815Sopenharmony_ci report $fileName [lindex $next_token 1] "Missing break, continue or FALLTHRU comment before rightbrace (state $state)" 274425bb815Sopenharmony_ci } 275425bb815Sopenharmony_ci } else { 276425bb815Sopenharmony_ci report $fileName [lindex $next_token 1] "Unknown state: $state" 277425bb815Sopenharmony_ci } 278425bb815Sopenharmony_ci } 279425bb815Sopenharmony_ci } 280425bb815Sopenharmony_ci } 281425bb815Sopenharmony_ci } 282425bb815Sopenharmony_ci} 283