⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memory.c~

📁 《jsp编程起步》里面的所有源代码
💻 C~
字号:
/* * Copyright (c) 1999-2000 Caucho Technology.  All rights reserved. * * Caucho Technology permits redistribution, modification and use * of this file in source and binary form ("the Software") under the * Caucho Public License ("the License").  In particular, the following * conditions must be met: * * 1. Each copy or derived work of the Software must preserve the copyright *    notice and this notice unmodified. * * 2. Redistributions of the Software in source or binary form must include  *    an unmodified copy of the License, normally in a plain ASCII text * * 3. The names "Resin" or "Caucho" are trademarks of Caucho Technology and *    may not be used to endorse products derived from this software. *    "Resin" or "Caucho" may not appear in the names of products derived *    from this software. * * 4. Caucho Technology requests that attribution be given to Resin *    in any manner possible.  We suggest using the "Resin Powered" *    button or creating a "powered by Resin(tm)" link to *    http://www.caucho.com for each page served by Resin. * * This Software is provided "AS IS," without a warranty of any kind.  * ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. * Caucho Technology AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR * DISTRIBUTING SOFTWARE. IN NO EVENT WILL Caucho OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF HE HAS BEEN ADVISED OF THE POSSIBILITY * OF SUCH DAMAGES.       */#include <stdio.h>#include <ctype.h>#include <string.h>#include <time.h>#ifdef WIN32#include <windows.h>#endif#include "cse.h"/* * stream_t is a convenience class containing the parse state. */typedef struct rstream_t {  config_t *config;  /* configuration we're reading into */  FILE *file;        /* input stream to read */  char *path;        /* file name  */  int line;          /* current line */  char *buf;         /* expandable buffer for reading tokens */  int length;        /* current length of the token in the buffer */  int capacity;      /* total buffer capacity */} rstream_t;/* * Read a byte from the input stream, counting lines. */static intbuf_read(rstream_t *is){  int ch = fgetc(is->file);  if (ch == '\n')    is->line++;  return ch;}/* * append a character to the token, expanding if necessary */static voidbuf_append(rstream_t *is, int ch){  if (is->length + 2 >= is->capacity) {    char *old = is->buf;    is->capacity *= 2;        is->buf = cse_alloc(is->config, 2 * is->capacity);    cse_free(is->config, old);  }  is->buf[is->length++] = ch;}/* * Add a child to the current registry node. */static registry_t *registry_add(rstream_t *is, registry_t *node, char *key){  registry_t *child = (registry_t *) cse_alloc(is->config, sizeof(registry_t));  memset(child, 0, sizeof(registry_t));  child->parent = node;  child->key = key;  child->prev = node->last;    if (node->last) {    node->last->next = child;    node->last = child;  } else {    node->first = child;    node->last = child;  }  return child;}/* * Parse an attribute.   * * The 'id' attribute is equivalent to a value of the parent node. * * entity references are not handled, i.e. &apos;, &quot; and &amp;. */static int parse_attribute(rstream_t *is, registry_t *node, int ch){  registry_t *attr;  for (; isspace(ch); ch = buf_read(is)) {  }  is->length = 0;  for (;       ch >= 0 && ! isspace(ch) && ch != '=' && ch != '/' && ch != '>';       ch = buf_read(is)) {    buf_append(is, ch);  }  if (is->length == 0) {    ungetc(ch, is->file);    return 0;  }  is->buf[is->length] = 0;  if (! strcmp(is->buf, "id"))    attr = node;  else    attr = registry_add(is, node, cse_strdup(is->config, is->buf));    for (; isspace(ch); ch = buf_read(is)) {  }  if (ch != '=') {    ungetc(ch, is->file);    return 0;  }  for (ch = buf_read(is); isspace(ch); ch = buf_read(is)) {  }  if (ch < 0 || ch == '/' || ch == '>') {    cse_error(is->config, "%s:%d: expected attribute at '%c'\n",	      is->path, is->line, ch);    return -1;  }  if (ch == '\'' || ch == '\"') {    int end = ch;    is->length = 0;    for (ch = buf_read(is); ch >= 0 && ch != end; ch = buf_read(is))      buf_append(is, ch);    if (ch != end) {      cse_error(is->config, "%s:%d: expected '%c' at '%c'\n",		is->path, is->line, end, ch);      return -1;    }    is->buf[is->length] = 0;    attr->value = cse_strdup(is->config, is->buf);    return ' ';  }  else {    is->length = 0;    for (;	 ch >= 0 && ! isspace(ch) && ch != '/' && ch != '>';	 ch = buf_read(is)) {      buf_append(is, ch);    }    is->buf[is->length] = 0;    attr->value = cse_strdup(is->config, is->buf);    return ch;  }}/* * parses an open tag, including the attributes. */static intparse_tag(rstream_t *is, registry_t **p_node, int ch){  registry_t *node = *p_node;  registry_t *child = 0;  is->length = 0;  for (;       ch >= 0 && ! isspace(ch) && ch != '/' && ch != '>';       ch = buf_read(is)) {    buf_append(is, ch);  }  if (is->length == 0) {    cse_error(is->config, "%s:%d: unexpected char at '%c'\n",	      is->path, is->line, ch);    return -1;  }  is->buf[is->length] = 0;  child = registry_add(is, node, cse_strdup(is->config, is->buf));  while ((ch = parse_attribute(is, child, ch)) > 0) {  }  if (ch < 0) {    cse_error(is->config, "%s:%d: unexpected end of file\n",	      is->path, is->line);    return ch;  }  else if (ch == 0)    ch = buf_read(is);  for (; isspace(ch); ch = buf_read(is)) {  }  if (ch == '>') {    *p_node = child;    return 0;  }  else if (ch != '/') {    cse_error(is->config, "%s:%d: expected '/' at '%c'\n",	      is->path, is->line, ch);    return -1;  }  ch = buf_read(is);  if (ch == '>')    return 1;  else {    cse_error(is->config, "%s:%d: expected '>' at '%c'\n",	      is->path, is->line, ch);    return -1;  }}/* * parses a close tag */static intparse_end_tag(rstream_t *is, registry_t **node){  int ch;  is->length = 0;  for (ch = buf_read(is);       ch >= 0 && ! isspace(ch) && ch != '/' && ch != '>';       ch = buf_read(is)) {    buf_append(is, ch);  }  if (is->length == 0) {    cse_error(is->config, "%s:%d: expected end tag at '%c'\n",	      is->path, is->line, ch);    return -1;  }  for (; ch >= 0 && isspace(ch); ch = buf_read(is)) {  }  if (ch != '>') {    cse_error(is->config, "%s:%d: expected '>' at '%c'\n",	      is->path, is->line, ch);    return -1;  }  is->buf[is->length] = 0;  /* XXX: need to check */  *node = (*node)->parent;  return 1;}/* * skips to the end of the comment */static voidskip_comment(rstream_t *is){  int ch;  while ((ch = buf_read(is)) >= 0) {    while (ch == '-') {      ch = buf_read(is);      while (ch == '-') {	if ((ch = buf_read(is)) == '>')	  return;      }    }  }  cse_error(is->config, "%s:%d: expected comment end at end of file\n",	    is->path, is->line);}/* * skips to the end of the doctype declaration */static voidskip_doctype(rstream_t *is){  int ch;  while ((ch = buf_read(is)) >= 0) {    if (ch == '>')      return;    else if (ch == '"') {      for (ch = buf_read(is);           ch >= 0 && ch != '"';           ch = buf_read(is)) {      }    }    else if (ch == '\'') {      for (ch = buf_read(is);           ch >= 0 && ch != '\'';           ch = buf_read(is)) {      }    }  }  cse_error(is->config, "%s:%d: expected doctype end at end of file\n",	    is->path, is->line);}/* * skips to the end of the processing instruction */static voidskip_pi(rstream_t *is){  int ch;  while ((ch = buf_read(is)) >= 0) {    while (ch == '?') {      if ((ch = buf_read(is)) == '>')        return;    }  }  cse_error(is->config, "%s:%d: expected pi end at end of file\n",	    is->path, is->line);}static registry_t *parse_include(config_t *config, registry_t *node, char *path){  char buf[4096];  int p = strlen(path);  char *value = cse_find_value(node->first, "href");  char *subpath;  registry_t *subnode;  registry_t *ptr;  FILE *is;  LOG(("pi %s\n", path, value ? value : "null"));  if (! value || ! value[0])    return node;  for (p = strlen(path); p >= 0; p--) {    if (path[p] == '/' || path[p] == '\\')      break;  }  if (p < 0)    p = 0;    strcpy(buf, path);  buf[p] = 0;  if (value[0] == '/' || value[0] == '\\' ||      value[1] == ':' &&      ((value[0] >= 'a' && value[0] <= 'z') ||       (value[0] >= 'A' && value[0] <= 'Z'))) {    subpath = value;  }  else {    strcat(buf, "/");    strcat(buf, value);    subpath = buf;  }  LOG(("subpath %s\n", subpath));  is = fopen(subpath, "r");  if (! is)    return node;  subnode = cse_parse(is, config, subpath);  fclose(is);  if (! subnode || ! subnode->first)    return node;  /* Now insert the included configuration in place of the resin:include */  subnode->parent = node->parent;  if (node->prev)    node->prev->next = subnode->first;  else    node->parent->first = subnode;  subnode->prev = node->prev;  node->parent->last = subnode->last;  for (ptr = subnode->first; ptr; ptr = ptr->next) {    ptr->parent = node->parent;  }  return subnode;}/* * Parses the configuration file. */registry_t *cse_parse(FILE *file, config_t *config, char *path){  int ch;  rstream_t is;  int spaceOnly = 1;  registry_t *root;  registry_t *node;  depend_t *depend;  is.file = file;  is.path = path;  is.line = 1;  is.config = config;  is.length = 0;  is.capacity = 1024;  is.buf = cse_alloc(config, is.capacity);  root = (registry_t *) cse_alloc(config, sizeof(registry_t));  memset(root, 0, sizeof(registry_t));  root->key = "";  node = root;  while ((ch = buf_read(&is)) >= 0) {    switch (ch) {    case ' ': case '\t': case '\n': case '\f':      buf_append(&is, ch);      break;    case '<':      if (spaceOnly)	is.length = 0;      else if (! node->value && ! node->first) {	is.buf[is.length] = 0;	node->value = cse_strdup(config, is.buf);      }      ch = buf_read(&is);      if (ch == '!') {        if ((ch = buf_read(&is)) == 'D') {          skip_doctype(&is);          break;        }	else if (ch != '-')	  cse_error(config, "%s:%d: expected comment start at '%c'\n", is.path, is.line, ch);	if ((ch = buf_read(&is)) != '-')	  cse_error(config, "%s:%d: expected comment start at '%c'\n", is.path, is.line, ch);	skip_comment(&is);      }      else if (ch == '?') {        skip_pi(&is);      }      else if (ch != '/') {	if (parse_tag(&is, &node, ch) < 0)	  return 0;        if (node->last && ! strcmp(node->last->key, "resin:include"))          parse_include(config, node->last, path);      }      else {	if (parse_end_tag(&is, &node) < 0)	  return 0;        if (node->last && ! strcmp(node->last->key, "resin:include"))          parse_include(config, node->last, path);      }      break;    default:      spaceOnly = 0;      buf_append(&is, ch);      break;    }  }  return root;}/* * Returns the next matching node. * * e.g. to iterate through all foo *   for (node = cse_next_link(root->first, "foo"); *        node; *        node = cse_next_line(node->next, "foo")) { *   } * */registry_t *cse_next_link(registry_t *node, char *key){  for (; node; node = node->next) {    if (! strcmp(node->key, key))      return node;  }  return 0;}char *cse_find_value(registry_t *node, char *key){  for (; node; node = node->next) {    if (! strcmp(node->key, key))      return node->value;  }  return 0;}voidcse_print_registry(registry_t *registry){  if (! registry)    return;  for (; registry; registry = registry->next) {    if (registry->first) {      cse_log("<%s id=%s>\n", registry->key,	      registry->value ? registry->value : "");      cse_print_registry(registry->first);      cse_log("</%s>\n", registry->key);    }    else      cse_log("%s=%s\n", registry->key, registry->value ? registry->value : "");  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -