Example #1
0
File: test-sax.c Project: rjp/tcx_c
void
sax_cb(mxml_node_t *node, mxml_sax_event_t event, void *data)
{
    const char *node_name = mxmlGetElement(node);

    if (event == MXML_SAX_DATA) {
        if (! strcmp(current_tag[tag_ptr], "DistanceMeters")) {
            if (! strcmp(current_tag[tag_ptr-1], "Lap")) {
                const char *x = mxmlGetText(node, NULL);
                lap_distances[lap_count] = atof(x);
                lap_count++;
            }
        }
    }

    if (event == MXML_SAX_ELEMENT_OPEN) {
        tag_ptr++;
        strcpy(current_tag[tag_ptr], node_name);

        if(! strcmp(node_name, "Activity")) {
            const char *t = mxmlElementGetAttr(node, "Sport");
            strcpy(sport, t);
        }
    }

    if (event == MXML_SAX_ELEMENT_CLOSE) {
        tag_ptr--;
    }
}
Example #2
0
static int l_get_name(lua_State *L)
{
	mxml_node_t *node = l_checkMXML(L, 1);

	lua_pushstring(L, mxmlGetElement(node));

	return 1;
}
Example #3
0
const char* IAPointsSerializer::retornoCarro_Callback(mxml_node_t *node, int where)
{
      const char *name;

      name = mxmlGetElement(node);

      if (!strcmp(name,"IAPoints")) // Si la etiqueta es IAPoints le metemos un retorno de carro donde...
          if (where == MXML_WS_BEFORE_OPEN || where == MXML_WS_AFTER_CLOSE || where == MXML_WS_AFTER_OPEN)
            return ("\n");
      if (!strcmp(name, "point")) // Si la etiqueta es point...
      {
        if (where == MXML_WS_BEFORE_OPEN) // Insertamos un tabulador antes de abrir <point>
           return ("\t");
        if (where == MXML_WS_AFTER_OPEN || where == MXML_WS_BEFORE_CLOSE || where == MXML_WS_AFTER_CLOSE) // Insertamos retorno carro después de abrir etiqueta <point>
           return ("\n");                                                                                 // y antes y después de cerrar <point>
      }

    return NULL;
}
Example #4
0
static const char* whitespaceCallback(mxml_node_t* node, int where)
{
	const char* name = mxmlGetElement(node);

	if (where == MXML_WS_BEFORE_CLOSE) 
	{
		if (!strcmp("tracks", name))
			return NULL; 

		return "\t";
	}

	if (where == MXML_WS_AFTER_CLOSE) 
		return "\n";

	if (where == MXML_WS_BEFORE_OPEN)
	{
		if (!strcmp("key", name))
			return "\t\t";

		if (!strcmp("tracks", name))
			return NULL; 

		if (!strcmp("track", name))
			return "\t";

		if (!strcmp("group", name))
			return "\t";

		if (!strcmp("bookmark", name))
			return "\t";
	}

	if (where == MXML_WS_AFTER_OPEN) 
		return "\n";

	return NULL;
}
Example #5
0
// whitespace callback utility function used with mini-xml
const char * mxmlWhitespaceCB(mxml_node_t *node, int loc) {
    const char *name;

    name = mxmlGetElement(node);

    if (loc == MXML_WS_BEFORE_OPEN) {
        // Single indentation
        if (!strcmp(name, "target") || !strcmp(name, "counters"))
            return("\n  ");

        // Double indentation
        if (!strcmp(name, "counter"))
            return("\n    ");

        // Avoid a carriage return on the first line of the xml file
        if (!strncmp(name, "?xml", 4))
            return(NULL);

        // Default - no indentation
        return("\n");
    }

    if (loc == MXML_WS_BEFORE_CLOSE) {
        // No indentation
        if (!strcmp(name, "captured"))
            return("\n");

        // Single indentation
        if (!strcmp(name, "counters"))
            return("\n  ");

        // Default - no carriage return
        return(NULL);
    }

    return(NULL);
}
Example #6
0
File: main.c Project: FTCr/sie-elf
void main(void)
{
	FILE *fp;
	char str[128];
	const char *xml_path = "0:\\Zbin\\Utilities\\mxmltest\\test.xml";
	
	fp = fopen(xml_path, "r");
	
	if (fp == NULL)
	{
		sprintf(str, "Can't open file: %s", xml_path);
		ShowMSG(1, (int)str);
		return;
	}
	mxml_node_t *tree = mxmlLoadFile(NULL, fp, MXML_TEXT_CALLBACK);
	fclose(fp);
	
	if (tree == NULL)
	{
		ShowMSG(1, (int)"mxmlLoadFile = NULL");
		return;
	}
	
	const char *log_path = "0:\\Zbin\\Log\\mxmltest.log";
	fp = fopen(log_path, "a");
	if (fp == NULL)
	{
		sprintf(str, "Can't open file: %s", log_path);
		ShowMSG(1, (int)str);
		mxmlDelete(tree);
		return;
	}
	
	mxml_node_t *node = tree;
	mxml_node_t *next = NULL;
	while (node != NULL)
	{
		switch (mxmlGetType(node))
		{
			case MXML_ELEMENT:
				sprintf(str, "MXML_ELEMENT = %s\n", mxmlGetElement(node));
				fwrite(str, sizeof(char), strlen(str), fp);
			break;
			case MXML_TEXT:
				sprintf(str, "MXML_TEXT = %s\n", mxmlGetText(node, 0));
				fwrite(str, sizeof(char), strlen(str), fp);
			break;
		}
		
		
		
		next = mxmlGetFirstChild(node);
		if (next != NULL)
		{
			node = next;
		}
		else
		{
			next = mxmlGetNextSibling(node);
			if (next == NULL)
			{
				next = mxmlWalkNext(node, NULL, MXML_DESCEND);
			}
			node = next;
		}
	}
	fclose(fp);
	mxmlDelete(tree);
}
Example #7
0
std::unique_ptr<mxml_node_t, void (*)(mxml_node_t *)> getTree(lib::Span<const GatorCpu> clusters)
{
#include "events_xml.h" // defines and initializes char events_xml[] and int events_xml_len
    char path[PATH_MAX];
    mxml_node_t *xml = NULL;
    FILE *fl;

    // Avoid unused variable warning
    (void) events_xml_len;

    // Load the provided or default events xml
    if (gSessionData.mEventsXMLPath) {
        strncpy(path, gSessionData.mEventsXMLPath, PATH_MAX);
        fl = lib::fopen_cloexec(path, "r");
        if (fl) {
            xml = mxmlLoadFile(NULL, fl, MXML_NO_CALLBACK);
            if (xml == NULL) {
                logg.logError("Unable to parse %s", gSessionData.mEventsXMLPath);
                handleException();
            }
            fclose(fl);
        }
    }
    if (xml == NULL) {
        logg.logMessage("Unable to locate events.xml, using default");
        xml = mxmlLoadString(NULL, reinterpret_cast<const char *>(events_xml), MXML_NO_CALLBACK);
    }

    // Append additional events XML
    if (gSessionData.mEventsXMLAppend) {
        fl = lib::fopen_cloexec(gSessionData.mEventsXMLAppend, "r");
        if (fl == NULL) {
            logg.logError("Unable to open additional events XML %s", gSessionData.mEventsXMLAppend);
            handleException();
        }
        mxml_node_t *append = mxmlLoadFile(NULL, fl, MXML_NO_CALLBACK);
        if (append == NULL) {
            logg.logError("Unable to parse %s", gSessionData.mEventsXMLAppend);
            handleException();
        }
        fclose(fl);

        mxml_node_t *events = mxmlFindElement(xml, xml, TAG_EVENTS, NULL, NULL, MXML_DESCEND);
        if (!events) {
            logg.logError("Unable to find <events> node in the events.xml, please ensure the first two lines of events XML starts with:\n"
                    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
                    "<events>");
            handleException();
        }

        XMLList *categoryList = NULL;
        XMLList *eventList = NULL;
        XMLList *counterSetList = NULL;
        {
            // Make list of all categories in xml
            mxml_node_t *node = xml;
            while (true) {
                node = mxmlFindElement(node, xml, TAG_CATEGORY, NULL, NULL, MXML_DESCEND);
                if (node == NULL) {
                    break;
                }
                categoryList = new XMLList(categoryList, node);
            }

            // Make list of all events in xml
            node = xml;
            while (true) {
                node = mxmlFindElement(node, xml, TAG_EVENT, NULL, NULL, MXML_DESCEND);
                if (node == NULL) {
                    break;
                }
                eventList = new XMLList(eventList, node);
            }

            // Make list of all counter_sets in xml
            node = xml;
            while (true) {
                node = mxmlFindElement(node, xml, TAG_COUNTER_SET, NULL, NULL, MXML_DESCEND);
                if (node == NULL) {
                    break;
                }
                counterSetList = new XMLList(counterSetList, node);
            }
        }

        // Handle counter_sets
        for (mxml_node_t *node =
                strcmp(mxmlGetElement(append), TAG_COUNTER_SET) == 0 ?
                        append : mxmlFindElement(append, append, TAG_COUNTER_SET, NULL, NULL, MXML_DESCEND),
                *next = mxmlFindElement(node, append, TAG_COUNTER_SET, NULL, NULL, MXML_DESCEND); node != NULL;
                node = next, next = mxmlFindElement(node, append, TAG_COUNTER_SET, NULL, NULL, MXML_DESCEND)) {

            const char * const name = mxmlElementGetAttr(node, ATTR_NAME);
            if (name == NULL) {
                logg.logError("Not all event XML counter_sets have the required name attribute");
                handleException();
            }

            // Replace any duplicate counter_sets
            bool replaced = false;
            for (XMLList *counterSet = counterSetList; counterSet != NULL; counterSet = counterSet->getPrev()) {
                const char * const name2 = mxmlElementGetAttr(counterSet->getNode(), ATTR_NAME);
                if (name2 == NULL) {
                    logg.logError("Not all event XML nodes have the required title and name and parent name attributes");
                    handleException();
                }

                if (strcmp(name, name2) == 0) {
                    logg.logMessage("Replacing counter %s", name);
                    mxml_node_t *parent = mxmlGetParent(counterSet->getNode());
                    mxmlDelete(counterSet->getNode());
                    mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node);
                    counterSet->setNode(node);
                    replaced = true;
                    break;
                }
            }

            if (replaced) {
                continue;
            }

            // Add new counter_sets
            logg.logMessage("Appending counter_set %s", name);
            mxmlAdd(events, MXML_ADD_AFTER, mxmlGetLastChild(events), node);
        }

        // Handle events
        for (mxml_node_t *node = mxmlFindElement(append, append, TAG_EVENT, NULL, NULL, MXML_DESCEND),
                *next = mxmlFindElement(node, append, TAG_EVENT, NULL, NULL, MXML_DESCEND); node != NULL;
                node = next, next = mxmlFindElement(node, append, TAG_EVENT, NULL, NULL, MXML_DESCEND)) {
            const char * const category = mxmlElementGetAttr(mxmlGetParent(node), ATTR_NAME);
            const char * const title = mxmlElementGetAttr(node, ATTR_TITLE);
            const char * const name = mxmlElementGetAttr(node, ATTR_NAME);
            if (category == NULL || title == NULL || name == NULL) {
                logg.logError("Not all event XML nodes have the required title and name and parent name attributes");
                handleException();
            }

            // Replace any duplicate events
            for (XMLList *event = eventList; event != NULL; event = event->getPrev()) {
                const char * const category2 = mxmlElementGetAttr(mxmlGetParent(event->getNode()), ATTR_NAME);
                const char * const title2 = mxmlElementGetAttr(event->getNode(), ATTR_TITLE);
                const char * const name2 = mxmlElementGetAttr(event->getNode(), ATTR_NAME);
                if (category2 == NULL || title2 == NULL || name2 == NULL) {
                    logg.logError("Not all event XML nodes have the required title and name and parent name attributes");
                    handleException();
                }

                if (strcmp(category, category2) == 0 && strcmp(title, title2) == 0 && strcmp(name, name2) == 0) {
                    logg.logMessage("Replacing counter %s %s: %s", category, title, name);
                    mxml_node_t *parent = mxmlGetParent(event->getNode());
                    mxmlDelete(event->getNode());
                    mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node);
                    event->setNode(node);
                    break;
                }
            }
        }

        // Handle categories
        for (mxml_node_t *node =
                strcmp(mxmlGetElement(append), TAG_CATEGORY) == 0 ?
                        append : mxmlFindElement(append, append, TAG_CATEGORY, NULL, NULL, MXML_DESCEND),
                *next = mxmlFindElement(node, append, TAG_CATEGORY, NULL, NULL, MXML_DESCEND); node != NULL;
                node = next, next = mxmlFindElement(node, append, TAG_CATEGORY, NULL, NULL, MXML_DESCEND)) {
            // After replacing duplicate events, a category may be empty
            if (mxmlGetFirstChild(node) == NULL) {
                continue;
            }

            const char * const name = mxmlElementGetAttr(node, ATTR_NAME);
            if (name == NULL) {
                logg.logError("Not all event XML category nodes have the required name attribute");
                handleException();
            }

            // Merge identically named categories
            bool merged = false;
            for (XMLList *category = categoryList; category != NULL; category = category->getPrev()) {
                const char * const name2 = mxmlElementGetAttr(category->getNode(), ATTR_NAME);
                if (name2 == NULL) {
                    logg.logError("Not all event XML category nodes have the required name attribute");
                    handleException();
                }

                if (strcmp(name, name2) == 0) {
                    logg.logMessage("Merging category %s", name);
                    while (true) {
                        mxml_node_t *child = mxmlGetFirstChild(node);
                        if (child == NULL) {
                            break;
                        }
                        mxmlAdd(category->getNode(), MXML_ADD_AFTER, mxmlGetLastChild(category->getNode()), child);
                    }
                    merged = true;
                    break;
                }
            }

            if (merged) {
                continue;
            }

            // Add new categories
            logg.logMessage("Appending category %s", name);
            mxmlAdd(events, MXML_ADD_AFTER, mxmlGetLastChild(events), node);
        }

        XMLList::free(eventList);
        XMLList::free(categoryList);
        XMLList::free(counterSetList);

        mxmlDelete(append);
    }

    // Resolve ${cluster}
    for (mxml_node_t *node = mxmlFindElement(xml, xml, TAG_EVENT, NULL, NULL, MXML_DESCEND), *next = mxmlFindElement(
            node, xml, TAG_EVENT, NULL, NULL, MXML_DESCEND); node != NULL;
            node = next, next = mxmlFindElement(node, xml, TAG_EVENT, NULL, NULL, MXML_DESCEND)) {
        const char *counter = mxmlElementGetAttr(node, ATTR_COUNTER);
        if (counter != NULL && strncmp(counter, CLUSTER_VAR, sizeof(CLUSTER_VAR) - 1) == 0) {
            for (const GatorCpu & cluster : clusters) {
                mxml_node_t *n = mxmlNewElement(mxmlGetParent(node), TAG_EVENT);
                copyMxmlElementAttrs(n, node);
                char buf[1 << 7];
                snprintf(buf, sizeof(buf), "%s%s", cluster.getPmncName(),
                         counter + sizeof(CLUSTER_VAR) - 1);
                mxmlElementSetAttr(n, ATTR_COUNTER, buf);
            }
            mxmlDelete(node);
        }
    }

    return {xml, &mxmlDelete};
}
//!!!!!!!!!!!!! yahoo
int parse_weather_yahoo(weather_t *w, char *buffer_orig){
  int code,retcode=0;
  char img_buf[MAX_BUF];

  mxml_node_t *top, *tree, *node;
  const char *text;

  top = mxmlLoadString(NULL, buffer_orig, MXML_TEXT_CALLBACK);
  tree = mxmlFindElement(top, top, "item",NULL,NULL,MXML_DESCEND);
  node = mxmlFindElement(tree, top, "yweather:condition",NULL,NULL,MXML_DESCEND);
  text=mxmlElementGetAttr(node,"code");
  code=get_code(text);
  mylog("Now code=%02d\n",code);
  if(code==NO_CODE)
    return RSS_RETRY;
  w->now_weather_text=codes[lang][code+1];
  sprintf(img_buf,BASE_URL "%02d.gif",code);
  w->now_image_index=get_icon_index(img_buf);
  if(w->now_image_index==0)
    retcode=IMAGE_RETRY;
  else if(w->today_image_index<0)
    retcode=0;

  text=mxmlElementGetAttr(node,"temp");
  sscanf(text,"%d",&(w->now_celsium));

  node = mxmlFindElement(tree, top, "yweather:forecast",NULL,NULL,MXML_DESCEND);
  text=mxmlElementGetAttr(node,"code");
  code=get_code(text);
  mylog("Today code=%02d\n",code);
  if(code==NO_CODE)
    return RSS_RETRY;

  w->today_forecast_text=codes[lang][code+1];
  sprintf(img_buf,BASE_URL "%02d.gif",code);
  w->today_image_index=get_icon_index(img_buf);
  if(w->today_image_index==0)
    retcode=IMAGE_RETRY;
  else if(w->today_image_index<0)
    retcode=0;

  text=mxmlElementGetAttr(node,"low");
  sscanf(text,"%d",&(w->today_celsium_low));
  text=mxmlElementGetAttr(node,"high");
  sscanf(text,"%d",&(w->today_celsium_high));

  node = mxmlFindElement(node, top, "yweather:forecast",NULL,NULL,MXML_DESCEND);
//  node = mxmlFindElement(node, top, "yweather:forecast",NULL,NULL,MXML_NO_DESCEND);
//  node = mxmlWalkNext(node, top,MXML_NO_DESCEND);
  text=mxmlElementGetAttr(node,"code");
  code=get_code(text);
  if(code==NO_CODE)
    return RSS_RETRY;
  w->tomorrow_forecast_text=codes[lang][code+1];
  sprintf(img_buf,BASE_URL "%02d.gif",code);
  w->tomorrow_image_index=get_icon_index(img_buf);

//  w->tomorrow_image_index=code;
  if(w->tomorrow_image_index==0)
    retcode=IMAGE_RETRY;
  else if(w->today_image_index<0)
    retcode=0;

  text=mxmlElementGetAttr(node,"low");
  sscanf(text,"%d",&(w->tomorrow_celsium_low));
  text=mxmlElementGetAttr(node,"high");
  sscanf(text,"%d",&(w->tomorrow_celsium_high));


#ifdef YAHOO_DYNAMIC_ICON_LOAD
  node = mxmlFindElement(tree, tree, "description",NULL,NULL,MXML_DESCEND);
  node=mxmlGetFirstChild(node);
  text=mxmlGetElement(node);

  img=strstr(text,"<img src=\"");
  if(img==NULL)
    return RSS_RETRY;
  img+=10;
  strncpy(img_buf,img,MAX_BUF);
  end=strstr(img_buf,"\"");
  if(end==NULL)
    return RSS_RETRY;
  *end='\0';

  if(w->now_weather_icon==NULL)
    {w->now_weather_icon=malloc(1);w->now_weather_icon[0]='\0';}
  len=strlen(img_buf)+1;
  if(strncmp(w->now_weather_icon,img_buf,len)){
    if(w->now_weather_icon)
      free(w->now_weather_icon);
    w->now_weather_icon=malloc(len);
    strncpy(w->now_weather_icon,img_buf,len);
    w->now_weather_icon[len]='\0';
    w->now_image_index=get_icon_index(w->now_weather_icon);
  }
#endif
#ifdef DEBUG
    print_weather(w);
#endif
  return retcode;
}
Example #9
0
static void parseXml(mxml_node_t* rootNode, TrackData* trackData)
{
	struct track_key k;
	int g, i, foldedGroupCount = 0, is_key, track_index = 0;
	mxml_node_t* node = rootNode;

	free(trackData->bookmarks);
	trackData->bookmarks = NULL;
	trackData->bookmarkCount = 0;
	trackData->highlightRowStep = 8;

	// Traverse the tracks node data

	while (1)
	{
		node = mxmlWalkNext(node, rootNode, MXML_DESCEND);

		if (!node)
			break;

		switch (mxmlGetType(node))
		{
			case MXML_ELEMENT:
			{
				const char* element_name = mxmlGetElement(node);

				if (!strcmp("bookmark", element_name))
				{
                    const char* row = mxmlElementGetAttr(node, "row");

                    if (row)
						TrackData_toggleBookmark(trackData, atoi(row));
				}

				if (!strcmp("group", element_name))
				{
                    s_foldedGroupNames[foldedGroupCount++] = strdup(mxmlElementGetAttr(node, "name"));
				}

				if (!strcmp("tracks", element_name))
				{
                    const char* start_row = mxmlElementGetAttr(node, "startRow");
                    const char* end_row = mxmlElementGetAttr(node, "endRow");
                    const char* hlrow_step = mxmlElementGetAttr(node, "highlightRowStep");

                    if (start_row)
						trackData->startRow = atoi(start_row);

                    if (end_row)
						trackData->endRow = atoi(end_row);

                    if (hlrow_step)
						trackData->highlightRowStep = atoi(hlrow_step);
				}

				if (!strcmp("track", element_name))
				{
					int i;
					struct sync_track* track;
					Track* t;

					// TODO: Create the new track/channel here
			
                    const char* track_name = mxmlElementGetAttr(node, "name");
                    const char* color_text = mxmlElementGetAttr(node, "color");
                    const char* folded_text = mxmlElementGetAttr(node, "folded");
                    
					track_index = TrackData_createGetTrack(trackData, track_name);

					t = &trackData->tracks[track_index];
					track = trackData->syncData.tracks[track_index];

					if (!color_text && t->color == 0)
					{
						t->color = TrackData_getNextColor(trackData);
					}
					else
					{
						if (color_text)
							t->color = strtoul(color_text, 0, 16);
					}

					if (folded_text)
					{
						if (folded_text[0] == '1')
							t->folded = true;
					}

					// If we already have this track loaded we delete all the existing keys
					
					for (i = 0; i < track->num_keys; ++i)
					{
						int row = track->keys[i].row;
						RemoteConnection_sendDeleteKeyCommand(track->name, row);
					}

					free(track->keys);

					track->keys = 0;
					track->num_keys = 0;
				}
				else if (!strcmp("key", element_name))
				{
					struct sync_track* track = trackData->syncData.tracks[track_index];

					const char* row = mxmlElementGetAttr(node, "row"); 
					const char* value = mxmlElementGetAttr(node, "value"); 
					const char* interpolation = mxmlElementGetAttr(node, "interpolation"); 

					k.row = atoi(row);
					k.value = (float)(atof(value));
					k.type = (atoi(interpolation));

					is_key = is_key_frame(track, k.row);

					assert(!is_key);
					sync_set_key(track, &k);

					RemoteConnection_sendSetKeyCommand(track->name, &k);
				}
			}

			default: break;
		}
	}

	TrackData_linkGroups(trackData);

	// Apply fold status on the groups

	for (i = 0; i < foldedGroupCount; ++i)
	{
		for (g = 0; g < trackData->groupCount; ++g)
		{
            Group* group = &trackData->groups[g];
            const char* groupName = group->name;
            const char* foldedName = s_foldedGroupNames[i];
         
            // groups with 1 track is handled as non-grouped
            
            if (group->trackCount == 1)
                continue;
            
			if (!strcmp(foldedName, groupName))
			{
				trackData->groups[g].folded = true;
				break;
			}
		}

		free(s_foldedGroupNames[i]);
	}

	trackData->tracks[0].selected = true;
}
Example #10
0
                      //区域编号  节点编号      功能编号   (家电名称          家电类型  (空调等等 没有均为NULL))
int xml_add_node(char * area, char *node, char * fun, char *app, char * app_type)
{
    mxml_node_t * xml = xml_root;
    mxml_node_t * xml_area;
    mxml_node_t * xml_node;
    mxml_node_t * xml_fun;
    mxml_node_t * xml_app;
    mxml_node_t * xml_app_type;
    const char * pelm;
    int ret = -1;

    XML_LOCK();
    do {

        xml_area = mxmlFindElement(xml, xml, area, NULL, NULL, MXML_DESCEND_FIRST);//超找area区域
        if (xml_area == NULL)
            break;




        xml_node = mxmlFindElement(xml_area, xml, node, NULL, NULL, MXML_DESCEND_FIRST);//查看是否有node节点
        if (xml_node == NULL) { //没有找到添加
            xml_node = mxmlNewElement(xml_area, node);      //添加node节点
            if (xml_node == NULL)
                break;
            ret = 0;
        }

        if (fun == NULL)
            break;
        //找到节点
        xml_fun = mxmlFindElement(xml_node, xml, fun, NULL, NULL , MXML_DESCEND_FIRST);//查看是否已经有了
        if (xml_fun == NULL) {  //没有此功能号
            xml_fun = mxmlNewElement(xml_node, fun);       //添加fun功能结合节点
            if (xml_fun == NULL) {
                ret = -1;
                break;
            }
            ret = 0;
        }

        if (app == NULL || app_type == NULL)
            break;

        pelm = mxmlGetElement(xml_fun);

        if (!strcmp(pelm, APPLIANCE)) {                 //名称匹配 是否是zigbee 转红外模块
            //家电
            xml_app = mxmlFindElement(xml_fun, xml, fun, NULL, NULL , MXML_DESCEND_FIRST);//查找app节点
            if (xml_app == NULL) {  //节点不存在则创建节点
                xml_app = mxmlNewElement(xml_fun, app);
                if (xml_app == NULL) {
                    ret = -1;
                    break;
                }
            }
            xml_app_type = mxmlFindElement(xml_app, xml, app_type, NULL, NULL, MXML_DESCEND_FIRST);//查找app_type节点
            if (xml_app_type == NULL) {         //节点不存在创建节点
                xml_app_type = mxmlNewElement(xml_fun, app_type);
                if (xml_app_type == NULL)
                    ret = -1;
                break;
            }
        }
    } while (0);

    XML_UNLOCK();
    return ret;
}
Example #11
0
mxml_node_t *EventsXML::getTree() {
#include "events_xml.h" // defines and initializes char events_xml[] and int events_xml_len
	char path[PATH_MAX];
	mxml_node_t *xml = NULL;
	FILE *fl;

	// Avoid unused variable warning
	(void)events_xml_len;

	// Load the provided or default events xml
	if (gSessionData->mEventsXMLPath) {
		strncpy(path, gSessionData->mEventsXMLPath, PATH_MAX);
		fl = fopen_cloexec(path, "r");
		if (fl) {
			xml = mxmlLoadFile(NULL, fl, MXML_NO_CALLBACK);
			fclose(fl);
		}
	}
	if (xml == NULL) {
		logg->logMessage("Unable to locate events.xml, using default");
		xml = mxmlLoadString(NULL, (const char *)events_xml, MXML_NO_CALLBACK);
	}

	// Append additional events XML
	if (gSessionData->mEventsXMLAppend) {
		fl = fopen_cloexec(gSessionData->mEventsXMLAppend, "r");
		if (fl == NULL) {
			logg->logError("Unable to open additional events XML %s", gSessionData->mEventsXMLAppend);
			handleException();
		}
		mxml_node_t *append = mxmlLoadFile(NULL, fl, MXML_NO_CALLBACK);
		fclose(fl);

		mxml_node_t *events = mxmlFindElement(xml, xml, "events", NULL, NULL, MXML_DESCEND);
		if (!events) {
			logg->logError("Unable to find <events> node in the events.xml, please ensure the first two lines of events XML starts with:\n"
				       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
				       "<events>");
			handleException();
		}

		XMLList *categoryList = NULL;
		XMLList *eventList = NULL;
		{
			// Make list of all categories in xml
			mxml_node_t *node = xml;
			while (true) {
				node = mxmlFindElement(node, xml, "category", NULL, NULL, MXML_DESCEND);
				if (node == NULL) {
					break;
				}
				categoryList = new XMLList(categoryList, node);
			}

			// Make list of all events in xml
			node = xml;
			while (true) {
				node = mxmlFindElement(node, xml, "event", NULL, NULL, MXML_DESCEND);
				if (node == NULL) {
					break;
				}
				eventList = new XMLList(eventList, node);
			}
		}

		// Handle events
		for (mxml_node_t *node = mxmlFindElement(append, append, "event", NULL, NULL, MXML_DESCEND),
		       *next = mxmlFindElement(node, append, "event", NULL, NULL, MXML_DESCEND);
		     node != NULL;
		     node = next, next = mxmlFindElement(node, append, "event", NULL, NULL, MXML_DESCEND)) {
			const char *const category = mxmlElementGetAttr(mxmlGetParent(node), "name");
			const char *const title = mxmlElementGetAttr(node, "title");
			const char *const name = mxmlElementGetAttr(node, "name");
			if (category == NULL || title == NULL || name == NULL) {
				logg->logError("Not all event XML nodes have the required title and name and parent name attributes");
				handleException();
			}

			// Replace any duplicate events
			for (XMLList *event = eventList; event != NULL; event = event->getPrev()) {
				const char *const category2 = mxmlElementGetAttr(mxmlGetParent(event->getNode()), "name");
				const char *const title2 = mxmlElementGetAttr(event->getNode(), "title");
				const char *const name2 = mxmlElementGetAttr(event->getNode(), "name");
				if (category2 == NULL || title2 == NULL || name2 == NULL) {
					logg->logError("Not all event XML nodes have the required title and name and parent name attributes");
					handleException();
				}

				if (strcmp(category, category2) == 0 && strcmp(title, title2) == 0 && strcmp(name, name2) == 0) {
					logg->logMessage("Replacing counter %s %s: %s", category, title, name);
					mxml_node_t *parent = mxmlGetParent(event->getNode());
					mxmlDelete(event->getNode());
					mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node);
					event->setNode(node);
					break;
				}
			}
		}

		// Handle categories
		for (mxml_node_t *node = strcmp(mxmlGetElement(append), "category") == 0 ? append : mxmlFindElement(append, append, "category", NULL, NULL, MXML_DESCEND),
		       *next = mxmlFindElement(node, append, "category", NULL, NULL, MXML_DESCEND);
		     node != NULL;
		     node = next, next = mxmlFindElement(node, append, "category", NULL, NULL, MXML_DESCEND)) {
			// After replacing duplicate events, a category may be empty
			if (mxmlGetFirstChild(node) == NULL) {
				continue;
			}

			const char *const name = mxmlElementGetAttr(node, "name");
			if (name == NULL) {
				logg->logError("Not all event XML categories have the required name attribute");
				handleException();
			}

			// Merge identically named categories
			bool merged = false;
			for (XMLList *category = categoryList; category != NULL; category = category->getPrev()) {
				const char *const name2 = mxmlElementGetAttr(category->getNode(), "name");
				if (name2 == NULL) {
					logg->logError("Not all event XML categories have the required name attribute");
					handleException();
				}

				if (strcmp(name, name2) == 0) {
					logg->logMessage("Merging category %s", name);
					while (true) {
						mxml_node_t *child = mxmlGetFirstChild(node);
						if (child == NULL) {
							break;
						}
						mxmlAdd(category->getNode(), MXML_ADD_AFTER, mxmlGetLastChild(category->getNode()), child);
					}
					merged = true;
					break;
				}
			}

			if (merged) {
				continue;
			}

			// Add new categories
			logg->logMessage("Appending category %s", name);
			mxmlAdd(events, MXML_ADD_AFTER, mxmlGetLastChild(events), node);
		}

		XMLList::free(eventList);
		XMLList::free(categoryList);

		mxmlDelete(append);
	}

	return xml;
}