示例#1
0
文件: ops.c 项目: xupingmao/minipy
// func Object tm_str(Object a)
Object tm_str(Object a) {
    char buf[100];
    memset(buf, 0, sizeof(buf));
    switch (TM_TYPE(a)) {
    case TYPE_STR:
        return a;
    case TYPE_NUM: {
        char s[20];
        double v = GET_NUM(a);
        number_format(s, a);
        return string_new(s);
    }
    case TYPE_LIST: {
        Object str = string_new("");

        str = string_append_char(str, '[');
        int i, l = LIST_LEN(a);
        for (i = 0; i < l; i++) {
            Object obj = GET_LIST(a)->nodes[i];
            /* reference to self in list */
            if (obj_equals(a, obj)) {
                str = string_append_sz(str, "[...]");
            } else if (obj.type == TYPE_STR) {
                str = string_append_char(str, '"');
                str = string_append_obj(str, obj);
                str = string_append_char(str, '"');
            } else {
                str = string_append_obj(str, obj);
            }
            if (i != l - 1) {
                str = string_append_char(str, ',');
            }
        }
        str = string_append_char(str, ']');
        return str;
    }
    case TYPE_DICT:
        sprintf(buf, "<dict at %p>", GET_DICT(a));
        return string_new(buf);
    case TYPE_FUNCTION:
        function_format(buf, a);
        return string_new(buf);
    case TYPE_NONE:
        return sz_to_string("None");
    case TYPE_DATA:
        return GET_DATA(a)->str(GET_DATA(a));
    default:
        tm_raise("str: not supported type %d", a.type);
    }
    return string_alloc("", 0);
}
示例#2
0
static scheme_object* read_string(vm* context, FILE* in)
{
	string_t* str = string_create();
	
	//we read until the first unescaped double quote character
	int c;
	while((c = getc(in)) != '"')
	{
		if(c == '\\')
		{
			//this is an escaped character
			c = getc(in);
			if(c == 'n')
			{
				c = '\n';
			}
			else if(c == 't')
			{
				c = '\t';
			}
		}
		if(c == EOF)
		{
			fprintf(stderr, "Unexpected termination of a string literal");
			exit(1);
		}
		string_append_char(str, c);
	}
	return make_string(context, str);
}
示例#3
0
文件: strings.c 项目: raglandba/WebC
int string_replace_with(String* source, char* token, char* rep) {
	assert(source != NULL && token != NULL && rep != NULL);

	if (strcmp(token, rep) == 0) return 0;

	size_t tok_len = strlen(token);
	size_t rep_len = strlen(rep);

	String* result = new_string();

	for (size_t i = 0; i < tok_len; i++) {
		int mem_result = memcmp((source->string + i), token, tok_len);

		if (mem_result == 0) {
			string_append(result, rep);
			i += tok_len;
		} else {
			string_append_char(result, source->string[i]);
		}
	}

	if (strcmp(result->string, source->string) != 0) {
		free_string(source);
		source = result;
		return 1;
	} else {
		return 0;
	}

}
示例#4
0
/* create error message  */
char *pool_error_message(char *message)
{
	String *str;

	str = init_string("");
	string_append_char(str,message);
	return str->data;
}
示例#5
0
文件: lexer.c 项目: raglandba/WebC
Tokens* lex_file(FILE* file) {
	String* contents = new_string();
	Tokens* tokens = new_tokens();

	if (contents == NULL || tokens == NULL || file == NULL) return NULL;

	int c;
	while ((c = fgetc(file)) != EOF) {
		string_append_char(contents, (char) c);
	}

	for (size_t i = 0; i < contents->length; i++) {

	}
}
示例#6
0
bool file_readLine_delim(FILE *file, string_t *str, char delim)
{
    bool retval = false;

    int c;

    while((c = fgetc(file)) != EOF)
    {
        retval = true;

        if (c == delim)
            break;

        string_append_char(str, (char)c);
    }

    return retval;
}
示例#7
0
文件: lexer.c 项目: raglandba/WebC
void inline lex_plain(Tokens* tokens, String* file, size_t* pos) {
	enum token_type last_t = get_last_token_type(tokens);

	if (last_t == PLAIN || last_t == EX_END) {
		int is_exp = lex_ex_start(tokens, file, pos);

		String* content = new_string();

		while (!is_exp) {
			if ((*pos) >= file->length) break;

			string_append_char(content, file->string[*pos]);
			*pos += 1;
			is_exp = lex_ex_start(tokens, file, pos);
		}

		lex_content_token(tokens, content, PLAIN);
	}
}
示例#8
0
static scheme_object* read_symbol(vm* context, FILE* in)
{
	string_t* str = string_create();
	int c = getc(in);
	while(is_initial(c) || isdigit(c) || c == '+' || c == '-')
	{
		string_append_char(str, c);
		c = getc(in);
	}
	if(!is_delimiter(c))
	{
		fprintf(stderr, "symbol not folowed by delimiter\n");
		exit(1);
	}
	ungetc(c, in);
	scheme_object* rval = make_symbol(context, string_cstring(str));
	string_free(str);
	return rval;
}
示例#9
0
int main()
{
	string *s = string_init();
	string *o;
	string *subs;
	string *q = string_init_cstring("quit");
	
	string_read_line(s);
	
	while(string_cmp(s, q))
	{
		string_print(s);
		
		string_reset(s);
		string_read_line(s);
	}

	string_append(s, q);
	o = string_cat(s, q);
	string_print(s);
	string_print(o);
	string_append_cstring(o, "hello");
	string_append_char(o, 'J');
	string_print(o);
	subs = string_substring(o, 5, 6);

	printf("--\n");
	printf("%c\n", string_get(s, 5));
	printf("%d\n", string_index(o, 'o'));
	string_print(subs);
	printf("--\n");

	o = string_free(o);
	s = string_free(s);
	q = string_free(q);
	subs = string_free(subs);

	return 0;
}
示例#10
0
NEOERR *html_strip_alloc(const char *src, int slen,
                         char **out)
{
  NEOERR *err = STATUS_OK;
  STRING out_s;
  int x = 0;
  int strip_match = -1;
  int state = 0;
  char amp[10];
  int amp_start = 0;
  char buf[10];
  int ampl = 0;

  string_init(&out_s);
  err = string_append (&out_s, "");
  if (err) return nerr_pass (err);

  while (x < slen)
  {
    switch (state) {
      case 0:
	/* Default */
	if (src[x] == '&')
	{
	  state = 3;
	  ampl = 0;
	  amp_start = x;
	}
	else if (src[x] == '<')
	{
	  state = 1;
	}
	else
	{
	  if (strip_match == -1)
	  {
	    err = string_append_char(&out_s, src[x]);
	    if (err) break;
	  }
	}
	x++;
	break;
      case 1:
	/* Starting TAG */
	if (src[x] == '>')
	{
	  state = 0;
	}
	else if (src[x] == '/')
	{
	}
	else
	{
	}
	x++;
	break;
      case 2:
	/* In TAG */
	if (src[x] == '>')
	{
	  state = 0;
	}
	x++;
	break;
      case 3:
	/* In AMP */
	if (src[x] == ';')
	{
	  amp[ampl] = '\0';
	  state = 0;
	  err = string_append(&out_s, html_expand_amp_8859_1(amp, buf));
	  if (err) break;
	}
	else
	{
	  if (ampl < sizeof(amp)-1)
	    amp[ampl++] = tolower(src[x]);
	  else
	  {
	    /* broken html... just back up */
	    x = amp_start;
	    err = string_append_char(&out_s, src[x]);
	    if (err) break;
	    state = 0;
	  }
	}
	x++;
	break;
    }
    if (err) break;
  }


  if (err)
  {
    string_clear (&out_s);
    return nerr_pass (err);
  }
  *out = out_s.buf;
  return STATUS_OK;
}
示例#11
0
static NEOERR *split_and_convert (const char *src, int slen,
                                  STRING *out, HTML_CONVERT_OPTS *opts)
{
  NEOERR *err = STATUS_OK;
  regmatch_t email_match, url_match;
  int errcode;
  char *ptr, *esc;
  char errbuf[256];
  struct _parts *parts;
  int part_count;
  int part;
  int x, i;
  int spaces = 0;

  if (!CompiledRe)
  {
#ifdef HAVE_PTHREADS
    /* In threaded environments, we have to mutex lock to do this regcomp, but
     * we don't want to use a mutex every time to check that it was regcomp.
     * So, we only lock if our first test of compiled was false */
    err = mLock(&InitLock);
    if (err != STATUS_OK) return nerr_pass(err);
    if (CompiledRe == 0) {
#endif
    if ((errcode = regcomp (&EmailRegex, EmailRe, REG_ICASE | REG_EXTENDED)))
    {
      regerror (errcode, &EmailRegex, errbuf, sizeof(errbuf));
      err = nerr_raise (NERR_PARSE, "Unable to compile EmailRE: %s", errbuf);
    }
    if ((errcode = regcomp (&UrlRegex, URLRe, REG_ICASE | REG_EXTENDED)))
    {
      regerror (errcode, &UrlRegex, errbuf, sizeof(errbuf));
      err = nerr_raise (NERR_PARSE, "Unable to compile URLRe: %s", errbuf);
    }
    CompiledRe = 1;
#ifdef HAVE_PTHREADS
    }
    if (err) {
      mUnlock(&InitLock);
      return err;
    }
    err = mUnlock(&InitLock);
    if (err != STATUS_OK) return nerr_pass(err);
#else
    if (err) {
      return err;
    }
#endif
  }

  part_count = 20;
  parts = (struct _parts *) malloc (sizeof(struct _parts) * part_count);
  part = 0;

  x = 0;
  if (regexec (&EmailRegex, src+x, 1, &email_match, 0) != 0)
  {
    email_match.rm_so = -1;
    email_match.rm_eo = -1;
  }
  else
  {
    email_match.rm_so += x;
    email_match.rm_eo += x;
  }
  if (regexec (&UrlRegex, src+x, 1, &url_match, 0) != 0)
  {
    url_match.rm_so = -1;
    url_match.rm_eo = -1;
  }
  else
  {
    url_match.rm_so += x;
    url_match.rm_eo += x;
  }
  while ((x < slen) && !((email_match.rm_so == -1) && (url_match.rm_so == -1)))
  {
    if (part >= part_count)
    {
      void *new_ptr;

      part_count *= 2;
      new_ptr = realloc (parts, sizeof(struct _parts) * part_count);
      if (new_ptr == NULL) {
        free(parts);
        return nerr_raise (NERR_NOMEM,
                           "Unable to increase url matcher to %d urls",
                           part_count);
      }
      parts = (struct _parts *) new_ptr;
    }
    if ((url_match.rm_so != -1) && ((email_match.rm_so == -1) || (url_match.rm_so <= email_match.rm_so)))
    {
      parts[part].begin = url_match.rm_so;
      parts[part].end = url_match.rm_eo;
      parts[part].type = SC_TYPE_URL;
      x = parts[part].end + 1;
      part++;
      if (x < slen)
      {
	if (regexec (&UrlRegex, src+x, 1, &url_match, 0) != 0)
	{
	  url_match.rm_so = -1;
	  url_match.rm_eo = -1;
	}
	else
	{
	  url_match.rm_so += x;
	  url_match.rm_eo += x;
	}
	if ((email_match.rm_so != -1) && (x > email_match.rm_so))
	{
	  if (regexec (&EmailRegex, src+x, 1, &email_match, 0) != 0)
	  {
	    email_match.rm_so = -1;
	    email_match.rm_eo = -1;
	  }
	  else
	  {
	    email_match.rm_so += x;
	    email_match.rm_eo += x;
	  }
	}
      }
    }
    else
    {
      parts[part].begin = email_match.rm_so;
      parts[part].end = email_match.rm_eo;
      parts[part].type = SC_TYPE_EMAIL;
      x = parts[part].end + 1;
      part++;
      if (x < slen)
      {
	if (regexec (&EmailRegex, src+x, 1, &email_match, 0) != 0)
	{
	  email_match.rm_so = -1;
	  email_match.rm_eo = -1;
	}
	else
	{
	  email_match.rm_so += x;
	  email_match.rm_eo += x;
	}
	if ((url_match.rm_so != -1) && (x > url_match.rm_so))
	{
	  if (regexec (&UrlRegex, src+x, 1, &url_match, 0) != 0)
	  {
	    url_match.rm_so = -1;
	    url_match.rm_eo = -1;
	  }
	  else
	  {
	    url_match.rm_so += x;
	    url_match.rm_eo += x;
	  }
	}
      }
    }
  }

  i = 0;
  x = 0;
  while (x < slen)
  {
    if ((i >= part) || (x < parts[i].begin))
    {
      ptr = strpbrk(src + x, "&<>\r\n ");
      if (ptr == NULL)
      {
	if (spaces)
	{
	  int sp;
	  for (sp = 0; sp < spaces - 1; sp++)
	  {
	    err = string_append (out, "&nbsp;");
	    if (err != STATUS_OK) break;
	  }
	  if (err != STATUS_OK) break;
	  err = string_append_char (out, ' ');
	}
	spaces = 0;
	if (i < part)
	{
	  err = string_appendn (out, src + x, parts[i].begin - x);
	  x = parts[i].begin;
	}
	else
	{
	  err = string_append (out, src + x);
	  x = slen;
	}
      }
      else
      {
	if ((i >= part) || ((ptr - src) < parts[i].begin))
	{
	  if (spaces)
	  {
	    int sp;
	    for (sp = 0; sp < spaces - 1; sp++)
	    {
	      err = string_append (out, "&nbsp;");
	      if (err != STATUS_OK) break;
	    }
	    if (err != STATUS_OK) break;
	    err = string_append_char (out, ' ');
	  }
	  spaces = 0;
	  err = string_appendn (out, src + x, (ptr - src) - x);
	  if (err != STATUS_OK) break;
	  x = ptr - src;
	  if (src[x] == ' ')
	  {
	    if (opts->space_convert)
	    {
	      spaces++;
	    }
	    else
	      err = string_append_char (out, ' ');
	  }
	  else
	  {
	    if (src[x] != '\n' && spaces)
	    {
	      int sp;
	      for (sp = 0; sp < spaces - 1; sp++)
	      {
		err = string_append (out, "&nbsp;");
		if (err != STATUS_OK) break;
	      }
	      if (err != STATUS_OK) break;
	      err = string_append_char (out, ' ');
	    }
	    spaces = 0;

	    if (src[x] == '&')
	      err = string_append (out, "&amp;");
	    else if (src[x] == '<')
	      err = string_append (out, "&lt;");
	    else if (src[x] == '>')
	      err = string_append (out, "&gt;");
	    else if (src[x] == '\n')
	      if (opts->newlines_convert)
		err = string_append (out, "<br/>\n");
	      else if (x && src[x-1] == '\n')
		err = string_append (out, "<p/>\n");
	      else
		err = string_append_char (out, '\n');
	    else if (src[x] != '\r')
	      err = nerr_raise (NERR_ASSERT, "src[x] == '%c'", src[x]);
	  }
	  x++;
	}
	else
	{
	  if (spaces)
	  {
	    int sp;
	    for (sp = 0; sp < spaces - 1; sp++)
	    {
	      err = string_append (out, "&nbsp;");
	      if (err != STATUS_OK) break;
	    }
	    if (err != STATUS_OK) break;
	    err = string_append_char (out, ' ');
	  }
	  spaces = 0;
	  err = string_appendn (out, src + x, parts[i].begin - x);
	  x = parts[i].begin;
	}
      }
    }
    else
    {
      if (spaces)
      {
	int sp;
	for (sp = 0; sp < spaces - 1; sp++)
	{
	  err = string_append (out, "&nbsp;");
	  if (err != STATUS_OK) break;
	}
	if (err != STATUS_OK) break;
	err = string_append_char (out, ' ');
      }
      spaces = 0;
      if (parts[i].type == SC_TYPE_URL)
      {
        char last_char = src[parts[i].end-1];
        int suffix=0;
        if (last_char == '.' || last_char == ',') { suffix=1; }
	err = string_append (out, " <a ");
	if (err != STATUS_OK) break;
	if (opts->url_class)
	{
	    err = string_appendf (out, "class=%s ", opts->url_class);
	    if (err) break;
	}
	if (opts->url_target)
	{
	  err = string_appendf (out, "target=\"%s\" ", opts->url_target);
	  if (err) break;
	}
	err = string_append(out, "href=\"");
	if (err) break;
	if (opts->bounce_url)
	{
	  char *url, *esc_url, *new_url;
	  int url_len;
	  if (!strncasecmp(src + x, "www.", 4))
	  {
	    url_len = 7 + parts[i].end - x - suffix;
	    url = (char *) malloc(url_len+1);
	    if (url == NULL)
	    {
	      err = nerr_raise(NERR_NOMEM,
		  "Unable to allocate memory to convert url");
	      break;
	    }
	    strcpy(url, "http://");
	    strncat(url, src + x, parts[i].end - x - suffix);
	  }
	  else
	  {
	    url_len = parts[i].end - x - suffix;
	    url = (char *) malloc(url_len+1);
	    if (url == NULL)
	    {
	      err = nerr_raise(NERR_NOMEM,
		  "Unable to allocate memory to convert url");
	      break;
	    }
	    strncpy(url, src + x, parts[i].end - x - suffix);
	    url[url_len] = '\0';
	  }
	  err = cgi_url_escape(url, &esc_url);
	  free(url);
	  if (err) {
	    free(esc_url);
	    break;
	  }

	  new_url = sprintf_alloc(opts->bounce_url, esc_url);
	  free(esc_url);
	  if (new_url == NULL)
	  {
	    err = nerr_raise(NERR_NOMEM, "Unable to allocate memory to convert url");
	    break;
	  }
	  err = string_append (out, new_url);
	  free(new_url);
	  if (err) break;
	}
	else
	{
	  if (!strncasecmp(src + x, "www.", 4))
	  {
	    err = string_append (out, "http://");
	    if (err != STATUS_OK) break;
	  }
	  err = string_appendn (out, src + x, parts[i].end - x - suffix);
	  if (err != STATUS_OK) break;
	}
	err = string_append (out, "\">");
	if (err != STATUS_OK) break;
        if (opts->link_name) {
          err = html_escape_alloc((opts->link_name),
                                  strlen(opts->link_name), &esc);
        } else {
          err = html_escape_alloc((src + x), parts[i].end - x - suffix, &esc);
        }
	if (err != STATUS_OK) break;
	err = string_append (out, esc);
	free(esc);
	if (err != STATUS_OK) break;
	err = string_append (out, "</a>");
        if (suffix) {
            err  = string_appendn(out,src + parts[i].end - 1,1);
	    if (err != STATUS_OK) break;
        }
      }
      else /* type == SC_TYPE_EMAIL */
      {
	err = string_append (out, "<a ");
	if (err != STATUS_OK) break;
	if (opts->mailto_class)
	{
	    err = string_appendf (out, "class=%s ", opts->mailto_class);
	    if (err) break;
	}
	err = string_append(out, "href=\"mailto:");
	if (err) break;
	err = string_appendn (out, src + x, parts[i].end - x);
	if (err != STATUS_OK) break;
	err = string_append (out, "\">");
	if (err != STATUS_OK) break;
	err = html_escape_alloc(src + x, parts[i].end - x, &esc);
	if (err != STATUS_OK) break;
	err = string_append (out, esc);
	free(esc);
	if (err != STATUS_OK) break;
	err = string_append (out, "</a>");
      }
      x = parts[i].end;
      i++;
    }
    if (err != STATUS_OK) break;
  }
  free (parts);
  return err;
}
示例#12
0
文件: neo_hdf.c 项目: bigclean/moc
/* attributes are of the form [key1, key2, key3=value, key4="repr"] */
static NEOERR* parse_attr(char **str, HDF_ATTR **attr)
{
  NEOERR *err = STATUS_OK;
  char *s = *str;
  char *k, *v;
  int k_l, v_l;
  STRING buf;
  char c;
  HDF_ATTR *ha, *hal = NULL;

  *attr = NULL;

  string_init(&buf);
  while (*s && *s != ']')
  {
    k = s;
    k_l = 0;
    v = NULL;
    v_l = 0;
    while (*s && isalnum(*s)) s++;
    k_l = s-k;
    if (*s == '\0' || k_l == 0)
    {
      _dealloc_hdf_attr(attr);
      return nerr_raise(NERR_PARSE, "Misformed attribute specification: %s", *str);
    }
    SKIPWS(s);
    if (*s == '=')
    {
      s++;
      SKIPWS(s);
      if (*s == '"')
      {
	s++;
	while (*s && *s != '"')
	{
	  if (*s == '\\')
	  {
	    if (isdigit(*(s+1)))
	    {
	      s++;
	      c = *s - '0';
	      if (isdigit(*(s+1)))
	      {
		s++;
		c = (c * 8) + (*s - '0');
		if (isdigit(*(s+1)))
		{
		  s++;
		  c = (c * 8) + (*s - '0');
		}
	      }
	    }
	    else
	    {
	      s++;
	      if (*s == 'n') c = '\n';
	      else if (*s == 't') c = '\t';
	      else if (*s == 'r') c = '\r';
	      else c = *s;
	    }
	    err = string_append_char(&buf, c);
	  }
	  else
	  {
	    err = string_append_char(&buf, *s);
	  }
	  if (err)
	  {
	    string_clear(&buf);
	    _dealloc_hdf_attr(attr);
	    return nerr_pass(err);
	  }
	  s++;
	}
	if (*s == '\0')
	{
	  _dealloc_hdf_attr(attr);
	  string_clear(&buf);
	  return nerr_raise(NERR_PARSE, "Misformed attribute specification: %s", *str);
	}
	s++;
	v = buf.buf;
        v_l = buf.len;
      }
      else
      {
	v = s;
	while (*s && *s != ' ' && *s != ',' && *s != ']') s++;
	if (*s == '\0')
	{
	  _dealloc_hdf_attr(attr);
	  return nerr_raise(NERR_PARSE, "Misformed attribute specification: %s", *str);
	}
        v_l = s-v;
      }
    }
    else
    {
      v = "1";
    }
    ha = (HDF_ATTR*) calloc (1, sizeof(HDF_ATTR));
    if (ha == NULL)
    {
      _dealloc_hdf_attr(attr);
      string_clear(&buf);
      return nerr_raise(NERR_NOMEM, "Unable to load attributes: %s", s);
    }
    if (*attr == NULL) *attr = ha;
    ha->key = neos_strndup(k, k_l);
    if (v)
      ha->value = neos_strndup(v, v_l);
    else
      ha->value = strdup("");
    if (ha->key == NULL || ha->value == NULL)
    {
      _dealloc_hdf_attr(attr);
      string_clear(&buf);
      return nerr_raise(NERR_NOMEM, "Unable to load attributes: %s", s);
    }
    if (hal != NULL) hal->next = ha;
    hal = ha;
    string_clear(&buf);
    SKIPWS(s);
    if (*s == ',')
    {
      s++;
      SKIPWS(s);
    }
  }
  if (*s == '\0')
  {
    _dealloc_hdf_attr(attr);
    return nerr_raise(NERR_PARSE, "Misformed attribute specification: %s", *str);
  }
  *str = s+1;
  return STATUS_OK;
}
示例#13
0
void
string_append_string(String * string, String * data)
{
	string_append_char(string, data->data);
}
示例#14
0
/*
 * trigger_failover_command: execute specified command at failover.
 *                           command_line is null-terminated string.
 */
static int trigger_failover_command(int node, const char *command_line)
{
	int r = 0;
	String *exec_cmd;
	char port_buf[6];
	char buf[2];
	BackendInfo *info;

	if (command_line == NULL || (strlen(command_line) == 0))
		return 0;

	/* check nodeID */
	if (node < 0 || node > NUM_BACKENDS)
		return -1;

	info = pool_get_node_info(node);
	if (!info)
		return -1;

	buf[1] = '\0';
	pool_memory = pool_memory_create(PREPARE_BLOCK_SIZE);
	if (!pool_memory)
	{
		pool_error("trigger_failover_command: pool_memory_create() failed");
		return -1;
	}
	exec_cmd = init_string("");

	while (*command_line)
	{
		if (*command_line == '%')
		{
			if (*(command_line + 1))
			{
				char val = *(command_line + 1);
				switch (val)
				{
					case 'p': /* port */
						snprintf(port_buf, sizeof(port_buf), "%d", info->backend_port);
						string_append_char(exec_cmd, port_buf);
						break;

					case 'D': /* database directory */
						string_append_char(exec_cmd, info->backend_data_directory);
						break;

					case 'd': /* node id */
						snprintf(port_buf, sizeof(port_buf), "%d", node);
						string_append_char(exec_cmd, port_buf);
						break;

					case 'h': /* host name */
						string_append_char(exec_cmd, info->backend_hostname);
						break;

					case 'm': /* new master node id */
						snprintf(port_buf, sizeof(port_buf), "%d", get_next_master_node());
						string_append_char(exec_cmd, port_buf);
						break;

					case 'M': /* old master node id */
						snprintf(port_buf, sizeof(port_buf), "%d", MASTER_NODE_ID);
						string_append_char(exec_cmd, port_buf);
						break;

					case '%': /* escape */
						string_append_char(exec_cmd, "%");
						break;

					default: /* ignore */
						break;
				}
				command_line++;
			}
		} else {
			buf[0] = *command_line;
			string_append_char(exec_cmd, buf);
		}
		command_line++;
	}

	if (strlen(exec_cmd->data) != 0)
	{
		pool_log("execute command: %s", exec_cmd->data);
		r = system(exec_cmd->data);
	}

	pool_memory_delete(pool_memory, 0);
	pool_memory = NULL;

	return r;
}