| 4850 | |
| 4851 | |
| 4852 | Line *Script::PreparseBlocks(Line *aStartingLine, bool aFindBlockEnd, Line *aParentLine) |
| 4853 | // aFindBlockEnd should be true, only when this function is called |
| 4854 | // by itself. The end of this function relies upon this definition. |
| 4855 | // Will return NULL to the top-level caller if there's an error, or if |
| 4856 | // mLastLine is NULL (i.e. the script is empty). |
| 4857 | { |
| 4858 | // Not thread-safe, so this can only parse one script at a time. |
| 4859 | // Not a problem for the foreseeable future: |
| 4860 | static nest_level; // Level zero is the outermost one: outside all blocks. |
| 4861 | static bool abort; |
| 4862 | if (aParentLine == NULL) |
| 4863 | { |
| 4864 | // We were called from outside, not recursively, so init these. This is |
| 4865 | // very important if this function is ever to be called from outside |
| 4866 | // more than once, even though it isn't currently: |
| 4867 | nest_level = 0; |
| 4868 | abort = false; |
| 4869 | } |
| 4870 | |
| 4871 | // Don't check aStartingLine here at top: only do it at the bottom |
| 4872 | // for its differing return values. |
| 4873 | for (Line *line = aStartingLine; line != NULL;) |
| 4874 | { |
| 4875 | // All lines in our recursion layer are assigned to the block that the caller specified: |
| 4876 | if (line->mParentLine == NULL) // i.e. don't do it if it's already "owned" by an IF or ELSE. |
| 4877 | line->mParentLine = aParentLine; // Can be NULL. |
| 4878 | |
| 4879 | if (ACT_IS_IF(line->mActionType) || line->mActionType == ACT_ELSE |
| 4880 | || line->mActionType == ACT_LOOP || line->mActionType == ACT_REPEAT) |
| 4881 | { |
| 4882 | // Make the line immediately following each ELSE, IF or LOOP be enclosed by that stmt. |
| 4883 | // This is done to make it illegal for a Goto or Gosub to jump into a deeper layer, |
| 4884 | // such as in this example: |
| 4885 | // #y:: |
| 4886 | // ifwinexist, pad |
| 4887 | // { |
| 4888 | // goto, label1 |
| 4889 | // ifwinexist, pad |
| 4890 | // label1: |
| 4891 | // ; With or without the enclosing block, the goto would still go to an illegal place |
| 4892 | // ; in the below, resulting in an "unexpected else" error: |
| 4893 | // { |
| 4894 | // msgbox, ifaction |
| 4895 | // } ; not necessary to make this line enclosed by the if because labels can't point to it? |
| 4896 | // else |
| 4897 | // msgbox, elseaction |
| 4898 | // } |
| 4899 | // return |
| 4900 | |
| 4901 | // In this case, the loader should have already ensured that line->mNextLine is not NULL: |
| 4902 | line->mNextLine->mParentLine = line; |
| 4903 | // Go onto the IF's or ELSE's action in case it too is an IF, rather than skipping over it: |
| 4904 | line = line->mNextLine; |
| 4905 | continue; |
| 4906 | } |
| 4907 | |
| 4908 | switch (line->mActionType) |
| 4909 | { |
nothing calls this directly
no test coverage detected