CString get_name(const CXmlTree::CElt &ee) { ASSERT(!ee.IsEmpty()); CString elt_type = ee.GetName(); if (elt_type == "define_struct") { return ee.GetAttr("type_name") + CString(" [STRUCT DEFN]"); } else if (elt_type == "struct") { return ee.GetAttr("name") + CString(" [STRUCT]"); } else if (elt_type == "use_struct") { return ee.GetAttr("name") + CString(" - using ") + ee.GetAttr("type_name"); } else if (elt_type == "for") { CString name = ee.GetAttr("name"); if (name.IsEmpty()) return CString("[FOR] - ") + get_name(ee.GetFirstChild()); else return name + CString(" [FOR]"); } else if (elt_type == "if") { CString name1 = get_name(ee.GetFirstChild()); CString name2; if (ee.GetNumChildren() > 1) { // Get name for else part ASSERT(ee.GetNumChildren() == 3 && ee.GetChild(1).GetName() == "else"); name2 = get_name(ee.GetChild(2)); } if (name1.IsEmpty()) name1 = name2; // no name for IF part so use else part else if (!name2.IsEmpty() && name1 != name2) name1 += "/" + name2; // Combine both names return CString("[IF] - ") + name1; } else if (elt_type == "switch") { return CString("[CASE] ") + ee.GetAttr("test"); } else if (elt_type == "jump") { return CString("[JUMP] - ") + get_name(ee.GetFirstChild()); } else if (elt_type == "eval") { return CString("[EVAL] ") + ee.GetAttr("expr"); } else if (elt_type == "data") { CString name = ee.GetAttr("name"); if (name.IsEmpty()) return CString("[DATA]"); else return name; } else ASSERT(0); return CString("ERROR"); }
// Static functions used by make_var_menu_tree (below) static void add_menu_items(CMenu *pmenu, int &item_no, const CXmlTree::CElt ¤t_elt, CString name) { CString ss = current_elt.GetName(); // type of this node // Add element name unless parent is FOR (or we are IF/SWITCH/JUMP which use child name) if (ss != "if" && ss != "switch" && ss != "jump" && name.Right(1) != "]") name += current_elt.GetAttr("name"); if (ss == "data") { pmenu->AppendMenu(MF_ENABLED, item_no++, name); } else if (ss == "for") { // Add array access operator [] and add item(s) for sub-element ASSERT(current_elt.GetNumChildren() <= 1); // May be zero for new elt if (current_elt.GetNumChildren() > 0) add_menu_items(pmenu, item_no, current_elt.GetFirstChild(), name+"[ ]"); } else if (ss == "struct") { // Add items for all sub-elements of the struct for (CXmlTree::CElt ee = current_elt.GetFirstChild(); !ee.IsEmpty(); ++ee) { add_menu_items(pmenu, item_no, ee, name+"."); } } else if (ss == "use_struct") { CString ss = current_elt.GetAttr("type_name"); // Find struct name to use CXmlTree::CElt ee = current_elt.GetOwner()->GetRoot().GetFirstChild(); for ( ; !ee.IsEmpty() && ee.GetName() == "define_struct"; ++ee) if (ss == ee.GetAttr("type_name")) { // Check if recursive call to same defined struct for (std::vector<CString>::const_iterator ps = prev_defined.begin(); ps != prev_defined.end(); ++ps) { if (*ps == ss) return; // avoid recursion into same define_struct } prev_defined.push_back(ss); // Add items for all sub-elements of the struct for (CXmlTree::CElt ee2 = ee.GetFirstChild(); !ee2.IsEmpty(); ++ee2) { add_menu_items(pmenu, item_no, ee2, name+"."); } break; // Found the (hopefully) only one with the correct name } } else if (ss == "if") { if (current_elt.GetNumChildren() > 0) add_menu_items(pmenu, item_no, current_elt.GetFirstChild(), name); if (current_elt.GetNumChildren() > 1) { // Add a separate item for the else part ASSERT(current_elt.GetNumChildren() == 3 && current_elt.GetChild(1).GetName() == "else"); add_menu_items(pmenu, item_no, current_elt.GetChild(2), name); } } else if (ss == "switch") { // Add names of all case sub-elements CStringList found; // just used to eliminate duplicate data elts for (CXmlTree::CElt ee = current_elt.GetFirstChild(); !ee.IsEmpty(); ++ee) { ASSERT(ee.GetName() == "case"); if (ee.GetFirstChild().GetName() == "data") { CString ss = ee.GetFirstChild().GetAttr("name"); if (!ss.IsEmpty()) { if (found.Find(ss) != NULL) continue; // ignore data elements with the same name else found.AddTail(ss); // store this one for later checks } } add_menu_items(pmenu, item_no, ee.GetFirstChild(), name); } } else if (ss == "jump") { if (current_elt.GetNumChildren() > 0) add_menu_items(pmenu, item_no, current_elt.GetFirstChild(), name); } else if (ss == "define_struct" || ss == "eval") { // Do nothing here } else ASSERT(0); }