Example #1
0
        private ErrType add_remove(SpreadsheetCell toAlter, ExpTree mainTree, bool removing)
        {
            /*Adding to and removing from the reference table occurs in this function*/
            ErrType Error = ErrType.None;

            if (toAlter.VarList != null && toAlter.VarList.Count > 0)
            {
                string referencedBy = CellToString(toAlter);
                if (removing)
                {
                    foreach (string referencedCell in toAlter.VarList) // Removes all variables from the old tree
                    {
                        if (refTable.ContainsKey(referencedCell))
                        {
                            if (refTable[referencedCell].Contains(referencedBy))
                                refTable[referencedCell].Remove(referencedBy); // Removes the current cell from any other cells referencing hash
                            if (refTable[referencedCell].Count < 1) // If an entry in the table has no cells referencing it, then it is removed
                                refTable.Remove(referencedCell);
                        }
                    }

                    toAlter.VarList.Clear(); // Empty that variable list (will be rebuild below)
                }
                else // Adding value to the reference this
                {
                    foreach (string s in toAlter.VarList) // Updates the reference table with all of the referenced cells (variables in the expTree's context)
                    {
                        double CellValue = 0.0;
                        SpreadsheetCell next = StringToCell(s);
                        if (next != null)
                        {
                            if (s == CellToString(toAlter)) // SELF-REFERENCING
                            {
                                Error = ErrType.SelfRef;
                                CheckErr(toAlter, Error, CellToString(toAlter));
                                UpdateErrorReferecedBy(toAlter, ErrType.SelfRef, CellToString(toAlter)); // Updates all cells referencing this cell that there is a value
                                return ErrType.SelfRef;
                            }
                            else if (next.Value.Contains("REF")) // Won't check for already occuring errors (in referenced cell) 
                            {
                                if (next.Value.Contains("=<BAD_REF")) // If this cell REFERENCES a cell that contains a bad_ref error
                                {
                                    CheckErr(toAlter, ErrType.BadRef, s);
                                    UpdateErrorReferecedBy(toAlter, ErrType.BadRef, s);
                                    Error = ErrType.BadRef;
                                }
                                else if (next.Value.Contains("=<SELF_REF")) // If this cell REFERENCES a cell that contains a self_ref error
                                {
                                    CheckErr(toAlter, ErrType.SelfRef, s);
                                    UpdateErrorReferecedBy(toAlter, ErrType.SelfRef, CellToString(toAlter));
                                    Error = ErrType.SelfRef;
                                }
                                else if (next.Value.Contains("=<CIRC_REF"))
                                {
                                    CheckErr(toAlter, ErrType.CircRef, s);
                                    UpdateErrorReferecedBy(toAlter, ErrType.CircRef, CellToString(toAlter));
                                    Error = ErrType.CircRef;
                                }
                            }
                            if (next.Text != "")
                            {
                                Double.TryParse(next.Value, out CellValue); // Gets the cell's value
                                mainTree.SetVar(s, CellValue); // Sets the variable in the expression tree's dictionary (0 if not yet set)
                            }
                            if (refTable.ContainsKey(s)) // If The variable already has references, just add to its hash
                                refTable[s].Add(referencedBy);
                            else // Otherwise create the new variable key with a new list containing the cell that references it
                                refTable.Add(s, new HashSet<string>() { referencedBy });
                        }
                        else // If Cell parsing return null (cell not recovered), the there is a bad reference
                        {
                            Error = ErrType.BadRef;
                            CheckErr(toAlter, Error, CellToString(toAlter));
                            UpdateErrorReferecedBy(toAlter, ErrType.BadRef, CellToString(toAlter));
                            return ErrType.BadRef;
                        }
                    }
                    if (Error == ErrType.CircRef)
                        return Error;

                    if (Error != ErrType.SelfRef && CheckCircularRef(toAlter, CellToString(toAlter))) // Checks for circular references here ***
                    {
                        Error = ErrType.CircRef;
                        CheckErr(toAlter, Error, CellToString(toAlter));
                        UpdateErrorReferecedBy(toAlter, ErrType.CircRef, CellToString(toAlter));
                    }
                }
            }

            return Error;
        }