* Partial evaluation of conditionals before recording and running the script. */
| 5100 | * Partial evaluation of conditionals before recording and running the script. |
| 5101 | */ |
| 5102 | static void |
| 5103 | CheckConditional(ParsedScript ps) |
| 5104 | { |
| 5105 | /* statically check conditional structure */ |
| 5106 | ConditionalStack cs = conditional_stack_create(); |
| 5107 | int i; |
| 5108 | |
| 5109 | for (i = 0; ps.commands[i] != NULL; i++) |
| 5110 | { |
| 5111 | Command *cmd = ps.commands[i]; |
| 5112 | |
| 5113 | if (cmd->type == META_COMMAND) |
| 5114 | { |
| 5115 | switch (cmd->meta) |
| 5116 | { |
| 5117 | case META_IF: |
| 5118 | conditional_stack_push(cs, IFSTATE_FALSE); |
| 5119 | break; |
| 5120 | case META_ELIF: |
| 5121 | if (conditional_stack_empty(cs)) |
| 5122 | ConditionError(ps.desc, i + 1, "\\elif without matching \\if"); |
| 5123 | if (conditional_stack_peek(cs) == IFSTATE_ELSE_FALSE) |
| 5124 | ConditionError(ps.desc, i + 1, "\\elif after \\else"); |
| 5125 | break; |
| 5126 | case META_ELSE: |
| 5127 | if (conditional_stack_empty(cs)) |
| 5128 | ConditionError(ps.desc, i + 1, "\\else without matching \\if"); |
| 5129 | if (conditional_stack_peek(cs) == IFSTATE_ELSE_FALSE) |
| 5130 | ConditionError(ps.desc, i + 1, "\\else after \\else"); |
| 5131 | conditional_stack_poke(cs, IFSTATE_ELSE_FALSE); |
| 5132 | break; |
| 5133 | case META_ENDIF: |
| 5134 | if (!conditional_stack_pop(cs)) |
| 5135 | ConditionError(ps.desc, i + 1, "\\endif without matching \\if"); |
| 5136 | break; |
| 5137 | default: |
| 5138 | /* ignore anything else... */ |
| 5139 | break; |
| 5140 | } |
| 5141 | } |
| 5142 | } |
| 5143 | if (!conditional_stack_empty(cs)) |
| 5144 | ConditionError(ps.desc, i + 1, "\\if without matching \\endif"); |
| 5145 | conditional_stack_destroy(cs); |
| 5146 | } |
| 5147 | |
| 5148 | /* |
| 5149 | * Parse a script (either the contents of a file, or a built-in script) |
no test coverage detected