Jabberd14-1.6.0/jabberd/config.c/do_include

Last-modified: 2007-03-10 (土) 21:42:44

このページを編集する際は,編集に関する方針に従ってください.

概要

* check the parsed configuration file for include instructions, process these instructions, and check again

引数

* @param nesting_lefel nesting level of includes, used to stop recursion if nesting_level is bigger than ::MAX_INCLUDE_NESTING
* @param x the parsed configuration (modified by this function)

実装

static void do_include(int nesting_level,xmlnode x) {
    xmlnode cur;
  • 関数は名前からなんとなく理解できるけど、定数はexpatを調べないとだめ。NTYPE_TAGってなによ?
    よくみたらJabberd14-1.6.0/jabberd/lib/jabberdlib.hに定義されていた。xmlnode関連はxmlnode.cに定義されてる。expatを使っているのはxstream.c?みたいだ。構造体にXML_Parserが定義されているし。
    cur=xmlnode_get_firstchild(x);
    for(;cur!=NULL;)
    {
  • NTYPE_TAG(element tag)以外のタグは処理しない
	 if(cur->type!=NTYPE_TAG)
	 {
	     cur=xmlnode_get_nextsibling(cur);
	     continue;
	 }
  • include ファイルを読み込んで置き換える処理を行う
	 if(j_strcmp(xmlnode_get_localname(cur),"include") == 0 &&
	    j_strcmp(xmlnode_get_namespace(cur),
                    NS_JABBERD_CONFIGFILE_REPLACE)        == 0)
	 {
	     xmlnode include;
	     char *include_file=xmlnode_get_data(cur);
	     xmlnode include_x=xmlnode_file(include_file);
	     /* check for bad nesting */
	     if(nesting_level>MAX_INCLUDE_NESTING)
	     {
		 fprintf(stderr, "ERROR: Included files nested %d levels deep.  Possible Recursion\n",nesting_level);
		 exit(1);
	     }
	     include=cur;
	     xmlnode_hide(include);
	     /* check to see what to insert...
	      * if root tag matches parent tag of the <include/> -- firstchild
	      * otherwise, insert the whole file
	      */
	      if (   j_strcmp(xmlnode_get_localname(xmlnode_get_parent(cur)),
	                      xmlnode_get_localname(include_x)) == 0
                 && j_strcmp(xmlnode_get_namespace(xmlnode_get_parent(cur)),
                             xmlnode_get_namespace(include_x)) == 0
	         ) {
		 xmlnode_insert_node(x,xmlnode_get_firstchild(include_x));
	      } else {
		  if (j_strcmp(xmlnode_get_localname(xmlnode_get_parent(cur)),
	                       xmlnode_get_localname(include_x)) == 0) {
		      xmlnode example_root_element = xmlnode_dup(xmlnode_get_parent(cur));
		      while (xmlnode_get_firstchild(example_root_element) != NULL)
			  xmlnode_hide(xmlnode_get_firstchild(example_root_element));
		      fprintf(stderr, "WARNING (while including file '%s'):\n", include_file);
		      fprintf(stderr, "Local name (%s) of the included file's root element matches the\n", xmlnode_get_localname(include_x));
		      fprintf(stderr, "parent element, but namespaces are different. This means the two elements\n");
		      fprintf(stderr, "are different and are handled as different elements. You might want this,\n");
		      fprintf(stderr, "and in that case you can just ignore this warning. But in most cases this\n");
		      fprintf(stderr, "is a configuration bug, and not what the writer of the configuration file\n");
		      fprintf(stderr, "intends. In that case you might want to update the root element of the\n");
		      fprintf(stderr, "included file to declare the right namespace.\n\n");
		      fprintf(stderr, "Currently the namespace of the parent element is '%s',\n", xmlnode_get_namespace(xmlnode_get_parent(cur)));
		      fprintf(stderr, "and the namespace of the included root element is '%s'.\n\n", xmlnode_get_namespace(include_x));
		      fprintf(stderr, "What you probably want is the following root element in the included file:\n");
		      fprintf(stderr, "%s\n\n", xmlnode_serialize_string(example_root_element, NULL, NULL, 0));
		      xmlnode_free(example_root_element);
		  }
		 xmlnode_insert_node(x,include_x);
	      }
	      do_include(nesting_level+1,include_x);
	      cur=xmlnode_get_nextsibling(cur);
	      continue;
	 }
  • 子要素にincludeタグがないか再帰的にチェックする
	 else
	 {
	     do_include(nesting_level,cur);
	 }
  • 現在のタグの処理は完了したので次へ
	 cur=xmlnode_get_nextsibling(cur);
    }
}

呼出元

#related: relatedプラグインは廃止されました。