| 4975 | |
| 4976 | |
| 4977 | Line *Script::PreparseIfElse(Line *aStartingLine, ExecUntilMode aMode, AttributeType aLoopTypeFile |
| 4978 | , AttributeType aLoopTypeReg, AttributeType aLoopTypeRead, AttributeType aLoopTypeParse) |
| 4979 | // Zero is the default for aMode, otherwise: |
| 4980 | // Will return NULL to the top-level caller if there's an error, or if |
| 4981 | // mLastLine is NULL (i.e. the script is empty). |
| 4982 | // Note: This function should be called with aMode == ONLY_ONE_LINE |
| 4983 | // only when aStartingLine's ActionType is something recursable such |
| 4984 | // as IF and BEGIN_BLOCK. Otherwise, it won't return after only one line. |
| 4985 | { |
| 4986 | // Don't check aStartingLine here at top: only do it at the bottom |
| 4987 | // for it's differing return values. |
| 4988 | Line *line_temp; |
| 4989 | // Although rare, a statement can be enclosed in more than one type of special loop, |
| 4990 | // e.g. both a file-loop and a reg-loop: |
| 4991 | AttributeType loop_type_file, loop_type_reg, loop_type_read, loop_type_parse; |
| 4992 | for (Line *line = aStartingLine; line != NULL;) |
| 4993 | { |
| 4994 | if (ACT_IS_IF(line->mActionType) || line->mActionType == ACT_LOOP || line->mActionType == ACT_REPEAT) |
| 4995 | { |
| 4996 | // ActionType is an IF or a LOOP. |
| 4997 | line_temp = line->mNextLine; // line_temp is now this IF's or LOOP's action-line. |
| 4998 | if (line_temp == NULL) // This is an orphan IF/LOOP (has no action-line) at the end of the script. |
| 4999 | // Update: this is now impossible because all scripts end in ACT_EXIT. |
| 5000 | return line->PreparseError("This if-statement or loop has no action."); |
| 5001 | if (line_temp->mActionType == ACT_ELSE || line_temp->mActionType == ACT_BLOCK_END) |
| 5002 | return line->PreparseError("The line beneath this IF or LOOP is an invalid action."); |
| 5003 | |
| 5004 | // We're checking for ATTR_LOOP_FILE here to detect whether qualified commands enclosed |
| 5005 | // in a true file loop are allowed to omit their filename paremeter: |
| 5006 | loop_type_file = ATTR_NONE; |
| 5007 | if (aLoopTypeFile == ATTR_LOOP_FILE || line->mAttribute == ATTR_LOOP_FILE) |
| 5008 | // i.e. if either one is a file-loop, that's enough to establish |
| 5009 | // the fact that we're in a file loop. |
| 5010 | loop_type_file = ATTR_LOOP_FILE; |
| 5011 | else if (aLoopTypeFile == ATTR_LOOP_UNKNOWN || line->mAttribute == ATTR_LOOP_UNKNOWN) |
| 5012 | // ATTR_LOOP_UNKNOWN takes precedence over ATTR_LOOP_NORMAL because |
| 5013 | // we can't be sure if we're in a file loop, but it's correct to |
| 5014 | // assume that we are (otherwise, unwarranted syntax errors may be reported |
| 5015 | // later on in here). |
| 5016 | loop_type_file = ATTR_LOOP_UNKNOWN; |
| 5017 | else if (aLoopTypeFile == ATTR_LOOP_NORMAL || line->mAttribute == ATTR_LOOP_NORMAL) |
| 5018 | loop_type_file = ATTR_LOOP_NORMAL; |
| 5019 | |
| 5020 | // The section is the same as above except for registry vs. file loops: |
| 5021 | loop_type_reg = ATTR_NONE; |
| 5022 | if (aLoopTypeReg == ATTR_LOOP_REG || line->mAttribute == ATTR_LOOP_REG) |
| 5023 | loop_type_reg = ATTR_LOOP_REG; |
| 5024 | else if (aLoopTypeReg == ATTR_LOOP_UNKNOWN || line->mAttribute == ATTR_LOOP_UNKNOWN) |
| 5025 | loop_type_reg = ATTR_LOOP_UNKNOWN; |
| 5026 | else if (aLoopTypeReg == ATTR_LOOP_NORMAL || line->mAttribute == ATTR_LOOP_NORMAL) |
| 5027 | loop_type_reg = ATTR_LOOP_NORMAL; |
| 5028 | |
| 5029 | // Same as above except for READ-FILE loops: |
| 5030 | loop_type_read = ATTR_NONE; |
| 5031 | if (aLoopTypeRead == ATTR_LOOP_READ_FILE || line->mAttribute == ATTR_LOOP_READ_FILE) |
| 5032 | loop_type_read = ATTR_LOOP_READ_FILE; |
| 5033 | else if (aLoopTypeRead == ATTR_LOOP_UNKNOWN || line->mAttribute == ATTR_LOOP_UNKNOWN) |
| 5034 | loop_type_read = ATTR_LOOP_UNKNOWN; |
nothing calls this directly
no test coverage detected