コード例 #1
0
ファイル: xmlparse.c プロジェクト: henryem/blinkdb-scheduling
/** Handle start tag */
static
void handle_starttag(
   PPOS*                 ppos
   )
{
   XML_NODE* node;
   char* name;

   assert(ppos != NULL);

   if ((name = get_name(ppos)) == NULL)
   {
      xml_error(ppos, "Missing name in tagstart");
      ppos->state = STATE_ERROR;
   }
   else
   {
      if (NULL == (node = xml_new_node(name, ppos->lineno)))
      {
         xml_error(ppos, "Can't create new node");
         ppos->state = STATE_ERROR;
      }
      else
      {
         xml_append_child(top_pstack(ppos), node);

         if ( push_pstack(ppos, node) )
            ppos->state = STATE_IN_TAG;
         else
            ppos->state = STATE_ERROR;
      }
      BMSfreeMemoryArray(&name);
   }
}
コード例 #2
0
ファイル: board.c プロジェクト: caidongyun/fbbs
int api_board_all(void)
{
	db_res_t *res = db_query(BOARD_SELECT_QUERY_BASE);
	if (!res)
		return WEB_ERROR_INTERNAL;

	xml_node_t *root = set_response_root("bbs-board-all",
			XML_NODE_ANONYMOUS_JSON, XML_ENCODING_UTF8);
	xml_node_t *boards = xml_new_node("boards", XML_NODE_CHILD_ARRAY);
	xml_add_child(root, boards);

	for (int i = db_res_rows(res) - 1; i >= 0; --i) {
		board_t board;
		res_to_board(res, i, &board);
		if (!has_read_perm(&board))
			continue;

		xml_node_t *node = xml_new_node("board", XML_NODE_ANONYMOUS_JSON);
		board_to_node(&board, node);
		xml_add_child(boards, node);
	}
	db_clear(res);
	return WEB_OK;
}
コード例 #3
0
ファイル: board.c プロジェクト: caidongyun/fbbs
/*
{
	groups: [
		{
			name: OPTIONAL TEXT,
			descr: OPTIONAL TEXT,
			boards: [
				{ id: INTEGER, name: TEXT, unread: OPTIONAL BOOLEAN },
				...
			]
		},
		...
	]
}
*/
int api_board_fav(void)
{
	if (!session_id())
		return WEB_ERROR_LOGIN_REQUIRED;

	xml_node_t *root = set_response_root("bbs-board-fav",
			XML_NODE_ANONYMOUS_JSON, XML_ENCODING_UTF8);
	xml_node_t *groups = xml_new_node("groups", XML_NODE_CHILD_ARRAY);
	xml_add_child(root, groups);

	query_t *q = query_new(0);
	query_select(q, "board, name, folder");
	query_from(q, "fav_boards");
	query_where(q, "user_id = %"DBIdUID, session_uid());
	db_res_t *boards = query_exec(q);

	q = query_new(0);
	query_select(q, "id, name, descr");
	query_from(q, "fav_board_folders");
	query_where(q, "user_id = %"DBIdUID, session_uid());
	db_res_t *folders = query_exec(q);

	if (folders && boards) {
		attach_group(groups, boards, FAV_BOARD_ROOT_FOLDER);
		for (int i = db_res_rows(folders) - 1; i >= 0; --i) {
			int id = db_get_integer(folders, i, 0);
			xml_node_t *group = attach_group(groups, boards, id);
			xml_attr_string(group, "name", db_get_value(folders, i, 1), true);
			xml_attr_string(group, "descr", db_get_value(folders, i, 2), true);
		}
	}

	db_clear(folders);
	db_clear(boards);
	return WEB_OK;
}
コード例 #4
0
ファイル: xmlparse.c プロジェクト: henryem/blinkdb-scheduling
/* Handles PCDATA */
static
void proc_pcdata(
   PPOS*                 ppos                /**< input stream position */
   )
{
   XML_NODE* node;
   char*   data   = NULL;
   size_t  size   = 0;
   size_t  len    = 0;
   int     c;

   assert(ppos        != NULL);
   assert(ppos->state == STATE_PCDATA);

#ifndef SPEC_LIKE_SPACE_HANDLING
   if ((c = skip_space(ppos)) != EOF)
      ungetsymbol(ppos, c);
#endif
   c = getsymbol(ppos);

   while ((c != EOF) && (c != '<'))
   {
      if (len >= size - 1) /* leave space for terminating '\0' */
      {
         size += DATA_EXT_SIZE;

         if ( data == NULL )
         {
            ALLOC_ABORT( BMSallocMemoryArray(&data, size) );
         }
         else
         {
            ALLOC_ABORT( BMSreallocMemoryArray(&data, size) );
         }
      }
      assert(data != NULL);
      assert(size > len + 1);

      data[len++] = (char)c;

      c = getsymbol(ppos);
   }
   if (data == NULL)
   {
      if (c == EOF)
         ppos->state = STATE_EOF;
      else if (c == '<')
      {
         ppos->state = STATE_BEFORE;
         ungetsymbol(ppos, c);
      }
      else
      {
         ppos->state = STATE_ERROR;
      }
   }
   else
   {
      assert(len < size);
      data[len] = '\0';

      if (c == EOF)
         ppos->state = STATE_ERROR;
      else
      {
         ungetsymbol(ppos, c);

         if (NULL == (node = xml_new_node("#PCDATA", ppos->lineno)))
         {
            xml_error(ppos, "Can't create new node");
            ppos->state = STATE_ERROR;
         }
         else
         {
            BMSduplicateMemoryArray(&node->data, data, strlen(data)+1);
            xml_append_child(top_pstack(ppos), node);
            ppos->state = STATE_BEFORE;
         }
         BMSfreeMemoryArray(&data);
      }
   }
}
コード例 #5
0
ファイル: xmlparse.c プロジェクト: henryem/blinkdb-scheduling
/** Handles declarations that start with a <!.
 *
 *  This includes comments. Does currenlty not work very well, because of DTDs.
 */
static
void handle_decl(
   PPOS*                 ppos
   )
{
   enum XmlSection {
      IS_COMMENT,
      IS_ATTLIST,
      IS_DOCTYPE,
      IS_ELEMENT,
      IS_ENTITY,
      IS_NOTATION,
      IS_CDATA
   };
   typedef enum XmlSection XMLSECTION;
   
   static struct
   {
      const char* name;
      XMLSECTION  what;
   } key[] =
   {
      { "--",       IS_COMMENT  },
      { "ATTLIST",  IS_ATTLIST  },
      { "DOCTYPE",  IS_DOCTYPE  },
      { "ELEMENT",  IS_ELEMENT  },
      { "ENTITY",   IS_ENTITY   },
      { "NOTATION", IS_NOTATION },
      { "[CDATA[",  IS_CDATA    }
   };
   XML_NODE* node;
   char*   data;
   int     c;
   int     k      = 0;
   int     beg    = 0;
   int     end    = (sizeof(key) / sizeof(key[0])) - 1;

   assert(ppos        != NULL);
   assert(ppos->state == STATE_BEFORE);

   do
   {
      c = getsymbol(ppos);

      for(; (beg <= end) && (c != key[beg].name[k]); beg++)
         ;
      for(; (end >= beg) && (c != key[end].name[k]); end--)
         ;
      k++;
   } while(beg < end);

   if (beg != end)
   {
      xml_error(ppos, "Unknown declaration");

      while((c != EOF) && (c != '>'))
         c = getsymbol(ppos);
   }
   else
   {
      assert(beg == end);
      assert(beg <  (int)(sizeof(key) / sizeof(*key)));

      switch(key[beg].what)
      {
      case IS_COMMENT :
         if (do_comment(ppos))
            ppos->state = STATE_ERROR;
         break;
      case IS_CDATA :
         if ((data = do_cdata(ppos)) == NULL)
            ppos->state = STATE_ERROR;
         else
         {
            if (NULL == (node = xml_new_node("#CDATA", ppos->lineno)))
            {
               xml_error(ppos, "Can't create new node");
               ppos->state = STATE_ERROR;
            }
            else
            {
               BMSduplicateMemoryArray(&node->data, data, strlen(data)+1);
               BMSfreeMemoryArray(&data);
               xml_append_child(top_pstack(ppos), node);
            }
         }
         break;
      case IS_ATTLIST :
      case IS_ELEMENT :
      case IS_NOTATION :
      case IS_ENTITY :
      case IS_DOCTYPE :
         break;
      default :
         abort();
      }
   }
}
コード例 #6
0
ファイル: xmlparse.c プロジェクト: henryem/blinkdb-scheduling
/** Parse file */
XML_NODE* xml_process(
   const char*           filename            /**< XML file name */
   )
{
   PPOS      ppos;
   XML_NODE* node = NULL;
   XML_ATTR* attr;
   int       result = FALSE;
   char*     myfilename;

   ALLOC_FALSE( BMSduplicateMemoryArray(&myfilename, filename, strlen(filename) + 5) );

#ifdef WITH_ZLIB
   if (access(filename, R_OK) != 0)
   {
      strcat(myfilename, ".gz");

      /* If .gz also does not work, revert to the old name
       * to get a better error message.
       */
      if (access(myfilename, R_OK) != 0)
         strcpy(myfilename, filename);
   }
#endif
   ppos.fp = FOPEN(myfilename, "r");
   if ( ppos.fp == NULL )
      perror(myfilename);
   else
   {
      ppos.filename = myfilename;
      ppos.buf[0]   = '\0';
      ppos.pos      = 0;
      ppos.lineno   = 1;
      ppos.nextsym  = 0;
      ppos.lastsym  = 0;
      ppos.state    = STATE_BEFORE;
      ppos.top      = NULL;

      node = xml_new_node("#ROOT", ppos.lineno);
      if ( node == NULL )
      {
         xml_error(&ppos, "Can't create new node");
      }
      else
      {
         attr = xml_new_attr("filename", myfilename);
         if ( attr == NULL )
            xml_error(&ppos, "Can't create new attribute");
         else
         {
            xml_add_attr(node, attr);

            /* push root node on stack and start to process */
            if ( push_pstack(&ppos, node) )
            {
               result = xml_parse(&ppos);

               clear_pstack(&ppos);
            }
         }
      }

      if ( ! result && (node != NULL) )
      {
         xml_errmsg(&ppos, "Parsing error, processing stopped", TRUE, __FILE__, __LINE__);
         xml_free_node(node);
         node = NULL;
      }
      if (FCLOSE(ppos.fp))
         perror(myfilename);
   }
   BMSfreeMemoryArray(&myfilename);

   return node;
}
コード例 #7
0
ファイル: parse.c プロジェクト: Litres/turboxsl
XMLNODE *do_parse(XSLTGLOBALDATA *gctx, char *document, char *uri)
{
  XMLNODE *ret;
  XMLNODE *current = NULL;
  XMLNODE *attr;
  XMLNODE *previous = NULL;
  char *p = document;
  char *c;
  unsigned comment_depth = 0;
  unsigned ln = 0;

  PARSE_STATE state = INIT;
  ret = xml_new_node(NULL,xsl_s_root,EMPTY_NODE);
  ret->file = uri;

  while(*p) {
    if(state==ERROR)
      break;

    switch(state) {
      case INIT:  // skip all until opening element
        if(*p == '\n')
          ++ln;
        if(*p++ == '<')
          state = OPEN;
        break;
      case XMLDECL:
        while(p[0]!='?' || p[1]!='>') {
          p++;
        }
        p+=2;
        state = INIT;
        break;
      case COMMENT:
        if(*p=='\n')
          ++ln;
        if(p[0]=='-' && p[1]=='-' && p[2]=='>') {
          p += 3;
          if(--comment_depth == 0)
            state = TEXT;
        } else {
          ++p;
        }
        break;
      case OPEN:
        if(*p == '?') {
          ++p;
          state = XMLDECL; // skip until ?>
        }
        else if(p[0]=='!' && p[1]=='-' && p[2]=='-') { // comment
          p += 3;
          comment_depth++;
          state = COMMENT;
        } else if(!memcmp(p,"![CDATA[",8)) {// cdata
          p+=8;
          state = CDATA;
        } else if(!memcmp(p,"!DOCTYPE",8)) {
          p+=8;
          state = DOCTYPE;
        } else if(*p=='!') {
          error("do_parse:: unknown instruction");
          return NULL;
        } else if(*p=='/') {// closing </element>
          state = CLOSE;
          ++p;
        } else {// start of element
          p = skip_spaces(p,&ln);
          for(c=p; can_name(*c);++c)
            ;
          current = xml_new_node(NULL, xmls_new_string(p, c - p), ELEMENT_NODE);
          current->prev = previous;
          current->file = uri;
          current->line = ln;
          if(previous)
            previous->next = current;
          else  // no previous sibling, add as first child to parent node
            ret->children = current;
          current->parent = ret;
          current->next = NULL;
          if(!ret)
            ret = current; // XXX first node treated as root!
          p = skip_spaces(c,&ln);
          state = INSIDE_TAG;
        }
        break;
      case CLOSE:
        p = skip_spaces(p,&ln);
        for(c=p; can_name(*c);++c)
            ;
        if(!memcmp(ret->name->s,p,c-p)) {
            for(p=c;*p!='>';++p)
              ;
            ++p;
            state = TEXT;
            previous = ret;
            ret = previous->parent;
        } else {
          *c = 0;
          error("do_parse:: closing tag mismatch <%s> </%s>", ret->name->s, p);
          state = ERROR;
        }
        break;
      case INSIDE_TAG:
        if(*p=='\n')
          ++ln;
        if(*p=='>') { // tag ended, possible children follow
          ++p;
          ret = current;
          current = previous = NULL;
          state = TEXT;
        } else if(p[0]=='/' && p[1]=='>') { // self closed tag, make it previous and proceed to next;
          previous = current;
          p+=2;
          state = TEXT;
        } else { // must be an attribute of the tag
          p = skip_spaces(p,&ln);
          for(c=p; can_name(*c);++c)
            ;
          attr = xml_new_node(NULL, xmls_new_string(p, c - p), ATTRIBUTE_NODE);
          attr->file = uri;
          attr->line = ln;
          attr->next = current->attributes;
          current->attributes = attr;
          attr->parent = current;
          p = skip_spaces(c,&ln);
          if(*p == '=') {
            p=skip_spaces(p+1,&ln);
            state = ATTR_VALUE;
          }
        }
        break;
      case CDATA:
        for(c=p;*c;++c) {
          if(*c=='\n')
            ++ln;
          if(c[0]==']' && c[1]==']' && c[2]=='>') {
            break;
          }
        }
        if(c>p)
        {
          current = xml_new_node(NULL,NULL, TEXT_NODE);
          current->file = uri;
          current->line = ln;
          current->content = xmls_new_string(p, c - p);
          current->flags = XML_FLAG_NOESCAPE;
          current->prev = previous;
          if(previous)
            previous->next = current;
          else  // no previous sibling, add as first child to parent node
            ret->children = current;
          current->parent = ret;
          current->next = NULL;
          previous = current;
          p = c + 3;
        }
        state = TEXT;
        break;
      case DOCTYPE:
        while(!(p[0]==']' && p[1]=='>')) p++;
        p+=2;
        state = TEXT;
        break;
      case TEXT:
        for(c=p;(*c && *c != '<');++c)
          if(*c=='\n')
          ++ln;
        if(c>p)
        {
          current = xml_new_node(NULL, NULL, TEXT_NODE);
          current->file = uri;
          current->line = ln;
          current->content = make_unescaped_string(p,c);
          current->prev = previous;
          if(previous)
            previous->next = current;
          else  // no previous sibling, add as first child to parent node
            ret->children = current;
          current->parent = ret;
          current->next = NULL;
          previous = current;
          p = c;
        }
        state = INIT;
        break;
      case ATTR_VALUE:
        if(!(*p == '"' || *p=='\'' || *p=='`')) {
          state = ERROR;
        } else {
          char endchar = *p++;
          for(c=p;*c != endchar;++c)
            ;
          attr->content = make_unescaped_string(p,c);
        }
        p = skip_spaces(c+1,&ln);
        state = INSIDE_TAG;
        break;
    }
  }
  return state==ERROR?NULL:ret;
}