(flow_group, value)
| 156 | |
| 157 | |
| 158 | def traverse_flow(flow_group, value) -> Case: |
| 159 | # Root flow node |
| 160 | flow_idx = 0 |
| 161 | flow = flow_group[flow_idx] |
| 162 | |
| 163 | # Traverse flow |
| 164 | while True: |
| 165 | # Set up CR |
| 166 | cr = 0 |
| 167 | if value < flow.imm: |
| 168 | cr |= CR.LT |
| 169 | if value == flow.imm: |
| 170 | cr |= CR.EQ |
| 171 | if value > flow.imm: |
| 172 | cr |= CR.GT |
| 173 | assert (cr & (CR.GT | CR.LT)) != (CR.GT | CR.LT), "Illegal CR" |
| 174 | |
| 175 | # Take branch |
| 176 | dst = -1 |
| 177 | b = BranchInst.NONE |
| 178 | for branch in flow.branches: |
| 179 | if branch.inst == BranchInst.ALWAYS: |
| 180 | dst = int(branch.dest[4:], 16) |
| 181 | b = branch.inst |
| 182 | break |
| 183 | elif branch.inst == BranchInst.EQ and (cr & CR.EQ): |
| 184 | dst = int(branch.dest[4:], 16) |
| 185 | b = branch.inst |
| 186 | break |
| 187 | elif branch.inst == BranchInst.NOT_EQ and (cr & CR.EQ) == 0: |
| 188 | dst = int(branch.dest[4:], 16) |
| 189 | b = branch.inst |
| 190 | break |
| 191 | elif branch.inst == BranchInst.GREATER and (cr & CR.GT): |
| 192 | dst = int(branch.dest[4:], 16) |
| 193 | b = branch.inst |
| 194 | break |
| 195 | elif branch.inst == BranchInst.LESS and (cr & CR.LT): |
| 196 | dst = int(branch.dest[4:], 16) |
| 197 | b = branch.inst |
| 198 | break |
| 199 | elif branch.inst == BranchInst.GREATER_OR_EQ and ((cr & CR.GT) or (cr & CR.EQ)): |
| 200 | dst = int(branch.dest[4:], 16) |
| 201 | b = branch.inst |
| 202 | break |
| 203 | elif branch.inst == BranchInst.LESS_OR_EQ and ((cr & CR.LT) or (cr & CR.EQ)): |
| 204 | dst = int(branch.dest[4:], 16) |
| 205 | b = branch.inst |
| 206 | break |
| 207 | |
| 208 | # Did we take a branch? |
| 209 | if dst != -1: |
| 210 | # Check if branch exits switch |
| 211 | flow_idx = flow_group_get_node(flow_group, dst) |
| 212 | if flow_idx != -1: |
| 213 | flow = flow_group[flow_idx] |
| 214 | else: |
| 215 | flow = None |
no test coverage detected