Beispiel #1
0
/**
 * virConfParseString:
 * @ctxt: the parsing context
 *
 * Parse one string
 *
 * Returns a pointer to the string or NULL in case of error
 */
static char *
virConfParseString(virConfParserCtxtPtr ctxt)
{
    const char *base;
    char *ret = NULL;

    if (CUR == '\'') {
        NEXT;
        base = ctxt->cur;
        while ((ctxt->cur < ctxt->end) && (CUR != '\'') && (!IS_EOL(CUR)))
            NEXT;
        if (CUR != '\'') {
            virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
            return NULL;
        }
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
        NEXT;
    } else if ((ctxt->cur + 6 < ctxt->end) &&
               (STRPREFIX(ctxt->cur, "\"\"\""))) {
        /* String starts with python-style triple quotes """ */
        ctxt->cur += 3;
        base = ctxt->cur;

        /* Find the ending triple quotes */
        while ((ctxt->cur + 2 < ctxt->end) &&
               !(STRPREFIX(ctxt->cur, "\"\"\""))) {
            if (CUR == '\n')
                ctxt->line++;
            NEXT;
        }

        if (!STRPREFIX(ctxt->cur, "\"\"\"")) {
            virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
            return NULL;
        }
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
        ctxt->cur += 3;
    } else if (CUR == '"') {
        NEXT;
        base = ctxt->cur;
        while ((ctxt->cur < ctxt->end) && (CUR != '"') && (!IS_EOL(CUR)))
            NEXT;
        if (CUR != '"') {
            virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
            return NULL;
        }
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
        NEXT;
    }
    return ret;
}
Beispiel #2
0
/**
 * virConfParseStatement:
 * @ctxt: the parsing context
 *
 * Parse one statement in the conf file
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
virConfParseStatement(virConfParserCtxtPtr ctxt)
{
    const char *base;
    char *name;
    virConfValuePtr value;
    char *comm = NULL;

    SKIP_BLANKS_AND_EOL;
    if (CUR == '#') {
        return virConfParseComment(ctxt);
    }
    name = virConfParseName(ctxt);
    if (name == NULL)
        return -1;
    SKIP_BLANKS;
    if (CUR != '=') {
        virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("expecting an assignment"));
        VIR_FREE(name);
        return -1;
    }
    NEXT;
    SKIP_BLANKS;
    value = virConfParseValue(ctxt);
    if (value == NULL) {
        VIR_FREE(name);
        return -1;
    }
    SKIP_BLANKS;
    if (CUR == '#') {
        NEXT;
        base = ctxt->cur;
        while ((ctxt->cur < ctxt->end) && (!IS_EOL(CUR))) NEXT;
        comm = strndup(base, ctxt->cur - base);
        if (comm == NULL) {
            virReportOOMError();
            VIR_FREE(name);
            virConfFreeValue(value);
            return -1;
        }
    }
    if (virConfAddEntry(ctxt->conf, name, value, comm) == NULL) {
        VIR_FREE(name);
        virConfFreeValue(value);
        VIR_FREE(comm);
        return -1;
    }
    return 0;
}
Beispiel #3
0
/**
 * virConfParseSeparator:
 * @ctxt: the parsing context
 *
 * Parse one separator between statement if not at the end.
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
virConfParseSeparator(virConfParserCtxtPtr ctxt)
{
    SKIP_BLANKS;
    if (ctxt->cur >= ctxt->end)
        return 0;
    if (IS_EOL(CUR)) {
        SKIP_BLANKS_AND_EOL;
    } else if (CUR == ';') {
        NEXT;
        SKIP_BLANKS_AND_EOL;
    } else {
        virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("expecting a separator"));
        return -1;
    }
    return 0;
}
Beispiel #4
0
/**
 * virConfParseComment:
 * @ctxt: the parsing context
 *
 * Parse one standalone comment in the configuration file
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
virConfParseComment(virConfParserCtxtPtr ctxt)
{
    const char *base;
    char *comm;

    if (CUR != '#')
        return -1;
    NEXT;
    base = ctxt->cur;
    while ((ctxt->cur < ctxt->end) && (!IS_EOL(CUR))) NEXT;
    if (VIR_STRNDUP(comm, base, ctxt->cur - base) < 0)
        return -1;
    if (virConfAddEntry(ctxt->conf, NULL, NULL, comm) == NULL) {
        VIR_FREE(comm);
        return -1;
    }
    return 0;
}
Beispiel #5
0
/**
 * virConfParseComment:
 * @ctxt: the parsing context
 *
 * Parse one standalone comment in the configuration file
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
virConfParseComment(virConfParserCtxtPtr ctxt)
{
    const char *base;
    char *comm;

    if (CUR != '#')
        return -1;
    NEXT;
    base = ctxt->cur;
    while ((ctxt->cur < ctxt->end) && (!IS_EOL(CUR))) NEXT;
    comm = strndup(base, ctxt->cur - base);
    if (comm == NULL) {
        virReportOOMError();
        return -1;
    }
    virConfAddEntry(ctxt->conf, NULL, NULL, comm);
    return 0;
}
Beispiel #6
0
/**
 * utils_handle_output:
 * @output: buffer containing vpnc output
 * @server_message: buffer in which to store a message from the VPN server
 * @server_message_done: flag which is set to %TRUE when a server message is
 *   complete
 * @prompt_fn: function to call when vpnc (or the server) sends a request for
 *   passwords or more information
 * @prompt_fn_data: pointer to pass to @prompt_fn
 *
 * Parses new vpnc output to extract server messages and detect prompts for
 * more information.  Since vpnc can print variable numbers of bytes at a time,
 * not necessarily a complete line or block, this function should be called
 * multiple times on the same buffer.  It will return the number of bytes which
 * it consumed, and that number of bytes should be removed from the start of
 * @output.  If a request for a password or username is parsed, it will call
 * @prompt_fn with the prompt message.
 *
 * Returns: the number of bytes consumed, which should be removed from the
 * start of @output.
 **/
gsize
utils_handle_output (GString *output,
                     GString *server_message,
                     gboolean *server_message_done,
                     PromptFn prompt_fn,
                     gpointer prompt_fn_data)
{
	guint32 i;

	g_return_val_if_fail (output != NULL, 0);
	g_return_val_if_fail (server_message != NULL, 0);
	g_return_val_if_fail (server_message_done != NULL, 0);
	g_return_val_if_fail (prompt_fn != NULL, 0);

	/* vpnc output is loosely formatted, with "blocks of interest" starting with
	 * no leading whitespace, and separated by double newlines, but unfortunately
	 * it doesn't output both newlines at the same time (one newline is printed
	 * at the end of one block and a second at the start of the next block with
	 * variable time in between) and some input prompts don't print newlines at
	 * all.
	 *
	 * S5.4 xauth type check
	 *  [2011-06-03 11:11:13]
	 *
	 * Wait for token to change,          (server message line #1)
	 * then enter the new tokencode:      (server message line #2)
	 *
	 * S5.5 do xauth authentication
	 *  [2011-06-03 11:11:13]
	 * Password for VPN [email protected]:   (waits for input without newline)
	 *    size = 42, blksz = 16, padding = 6
	 *
	 * So we can't just listen for '\n\n' or we won't react immediately to
	 * input prompts or correctly process service messages.
	 *
	 * Instead we pay attention to any lines that have no leading whitespace
	 * and do not start with "S[1 - 9]".  If the line ends with ":" it is an
	 * input prompt.  If it doesn't then we cache it and wait for the next line
	 * or newline, in which case it's a server message.
	 */

	if (output->len == 0)
		return 0;

	/* Find the end of the line or the end of the string; all lines *except*
	 * prompts will be newline terminated, while prompts stop at the end of the
	 * buffer because vpnc is waiting for the input.
	 */
	for (i = 0; i < output->len; i++) {
		if (!output->str[i] || IS_EOL (output->str[i]))
			break;
	}

	/* Decide whether to stop parsing a server message, which is terminated by
	 * a single empty line or some whitespace; it looks like:
	 *
	 * <stuff>
	 *
	 * Wait for token to change,
	 * then enter the new tokencode:
	 *
	 * <more stuff>
	 */
	if (server_message->len) {
		if (g_ascii_isspace (output->str[0]) || IS_EOL (output->str[0]))
		    *server_message_done = TRUE;
	}

	if (i < output->len) {
		/* Lines starting with whitespace are debug output that we don't care
		 * about.
		 */
		if (g_ascii_isspace (output->str[0]))
			return i + 1;
	} else if (i == output->len) {
		/* Check for a prompt; it will not begin with whitespace, and will end
		 * with a ':' and no newline, because vpnc will be waiting for the response.
		 */
		if (!g_ascii_isspace (output->str[0]) &&
		    (i > 2) &&
		    (strncmp ((output->str + (i - 2)), ": ", 2) == 0)) {
			/* Note: if vpnc sent a server message ending with ':' but we
			 * happened to only read up to the ':' but not the EOL, we'll
			 * confuse the server message with an input prompt.  vpnc is not
			 * helpful here.
			 */
			prompt_fn (output->str, i, prompt_fn_data);
			return i;
		}

		/* No newline and no ending semicolon; probably a partial read so wait
		 * for more output
		 */
		return 0;
	} else
		g_assert_not_reached ();

	/* No newline at the end, wait for one */
	if (!IS_EOL (output->str[i]))
		return 0;

	/* Ignore vpnc version debug output */
	if (i >= strlen (VPNC_VERSION_STR) &&
	    strncmp (output->str, VPNC_VERSION_STR, strlen (VPNC_VERSION_STR)) == 0)
		return i + 1;

	/* Ignore vpnc debug messages like "S1 init_sockaddr" */
	if (i > 2 && output->str[0] == 'S' && g_ascii_isdigit (output->str[1]))
		return i + 1;

	/* What's left is probably a server message */
	if (*server_message_done) {
		g_string_truncate (server_message, 0);
		*server_message_done = FALSE;
	}
	g_string_append_len (server_message, output->str, i + 1);
	return i + 1;
}
Beispiel #7
0
int  AmConfigReader::loadFile(const string& path)
{
  FILE* fp = fopen(path.c_str(),"r");
  if(!fp){
      WARN("could not open configuration file '%s': %s\n",
	   path.c_str(),strerror(errno));
      return -1;
  }
  
  int  lc = 0;
  int  ls = 0;
  char lb[MAX_CONFIG_LINE] = {'\0'};

  char *c,*key_beg,*key_end,*val_beg,*val_end,*inc_beg,*inc_end;

  c=key_beg=key_end=val_beg=val_end=inc_beg=inc_end=0;
  while(!feof(fp) && ((ls = fifo_get_line(fp, lb, MAX_CONFIG_LINE)) != -1)){
	
    c=key_beg=key_end=val_beg=val_end=0;
    lc++;

    c = lb;
    TRIM(c);

    if(IS_EOL(*c)) continue;

    if (*c == '@') { /* process included config file */
	c++;
	TRIM(c);
	inc_beg = c++;
	while( !IS_EOL(*c) && !IS_SPACE(*c) ) c++;
	inc_end = c;
	string fname = string(inc_beg,inc_end-inc_beg);
	if (fname.length() && fname[0] != '/')
	  fname = AmConfig::ModConfigPath + fname;
	if(loadFile(fname))
	    goto error;
	continue;
    }

    key_beg = c;
    while( (*c != '=') && !IS_SPACE(*c) ) c++;
    
    key_end = c;
    if(IS_SPACE(*c))
      TRIM(c);
    else if( !(c - key_beg) )
      goto syntax_error;

    if(*c != '=')
      goto syntax_error;

    c++;
    TRIM(c);

    if(*c == '"'){
      char last_c = ' ';
      val_beg = ++c;

      while( ((*c != '"') || (last_c == '\\')) && (*c != '\0') ) {
	last_c = *c;
	c++;
      }

      if(*c == '\0')
	goto syntax_error;

      val_end = c;
    }
    else {
      val_beg = c;

      while( !IS_EOL(*c) && !IS_SPACE(*c) ) c++;

      val_end = c;
    }

    if((key_beg < key_end) && (val_beg <= val_end)) {
      string keyname = string(key_beg,key_end-key_beg);
      string val = string(val_beg,val_end-val_beg);
      if (hasParameter(keyname)) {
	WARN("while loading '%s': overwriting configuration "
	     "'%s' value '%s' with  '%s'\n",
	     path.c_str(), keyname.c_str(), 
	     getParameter(keyname).c_str(), val.c_str());
      }

      keys[keyname] = val;

      // small hack to make include work with right path
      if (keyname == "plugin_config_path")
	AmConfig::ModConfigPath = val;

    } else
      goto syntax_error;
  }

  fclose(fp);
  return 0;

 syntax_error:
  ERROR("syntax error line %i in %s\n",lc,path.c_str());
 error:
  fclose(fp);
  return -1;
}
Beispiel #8
0
int AmConfigReader::loadString(const char* cfg_lines, size_t cfg_len)
{
  int  lc = 0;
  int  ls = 0;
  char lb[MAX_CONFIG_LINE] = {'\0'};

  char *c,*key_beg,*key_end,*val_beg,*val_end,*inc_beg,*inc_end;

  const char* cursor = cfg_lines;
  const char* cfg_end = cursor + cfg_len;

  c=key_beg=key_end=val_beg=val_end=inc_beg=inc_end=0;
  while((cursor < cfg_end) && 
	((ls = str_get_line(&cursor, cfg_end, lb, MAX_CONFIG_LINE)) != -1)){
	
    c=key_beg=key_end=val_beg=val_end=0;
    lc++;

    c = lb;
    TRIM(c);

    if(IS_EOL(*c)) continue;

    key_beg = c;
    while( (*c != '=') && !IS_SPACE(*c) ) c++;
    
    key_end = c;
    if(IS_SPACE(*c))
      TRIM(c);
    else if( !(c - key_beg) )
      goto syntax_error;

    if(*c != '=')
      goto syntax_error;

    c++;
    TRIM(c);

    if(*c == '"'){
      char last_c = ' ';
      val_beg = ++c;

      while( ((*c != '"') || (last_c == '\\')) && (*c != '\0') ) {
	last_c = *c;
	c++;
      }

      if(*c == '\0')
	goto syntax_error;

      val_end = c;
    }
    else {
      val_beg = c;

      while( !IS_EOL(*c) && !IS_SPACE(*c) ) c++;

      val_end = c;
    }

    if((key_beg < key_end) && (val_beg <= val_end)) {
      string keyname = string(key_beg,key_end-key_beg);
      string val = string(val_beg,val_end-val_beg);
      if (hasParameter(keyname)) {
	WARN("while loading string: overwriting configuration "
	     "'%s' value '%s' with  '%s'\n",
	     keyname.c_str(), getParameter(keyname).c_str(), 
	     val.c_str());
      }

      keys[keyname] = val;
    } else
      goto syntax_error;
  }

  return 0;

 syntax_error:
  ERROR("syntax error line %i\n",lc);
  return -1;
}
Beispiel #9
0
/**
 * virConfParseString:
 * @ctxt: the parsing context
 *
 * Parse one string
 *
 * Returns a pointer to the string or NULL in case of error
 */
static char *
virConfParseString(virConfParserCtxtPtr ctxt)
{
    const char *base;
    char *ret = NULL;

    if (CUR == '\'') {
        NEXT;
        base = ctxt->cur;
        while ((ctxt->cur < ctxt->end) && (CUR != '\'') && (!IS_EOL(CUR)))
            NEXT;
        if (CUR != '\'') {
            virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
            return NULL;
        }
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
        NEXT;
    } else if ((ctxt->cur + 6 < ctxt->end) &&
               (STRPREFIX(ctxt->cur, "\"\"\""))) {
        /* String starts with python-style triple quotes """ */
        ctxt->cur += 3;
        base = ctxt->cur;

        /* Find the ending triple quotes */
        while ((ctxt->cur + 2 < ctxt->end) &&
                !(STRPREFIX(ctxt->cur, "\"\"\""))) {
            if (CUR == '\n')
                ctxt->line++;
            NEXT;
        }

        if (!STRPREFIX(ctxt->cur, "\"\"\"")) {
            virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
            return NULL;
        }
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
        ctxt->cur += 3;
    } else if (CUR == '"') {
        NEXT;
        base = ctxt->cur;
        while ((ctxt->cur < ctxt->end) && (CUR != '"') && (!IS_EOL(CUR)))
            NEXT;
        if (CUR != '"') {
            virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
            return NULL;
        }
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
        NEXT;
    } else if (ctxt->conf->flags & VIR_CONF_FLAG_LXC_FORMAT) {
        base = ctxt->cur;
        /* LXC config format doesn't support comments after the value */
        while ((ctxt->cur < ctxt->end) && (!IS_EOL(CUR)))
            NEXT;
        /* Reverse to exclude the trailing blanks from the value */
        while ((ctxt->cur > base) && (c_isblank(CUR)))
            ctxt->cur--;
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
    }
    return ret;
}
Beispiel #10
0
int main(int argc, char *argv[])
	{
	char *uncompressed = (char *)malloc(128 * 1024);
	char *compressed;
	char *trace = uncompressed;
	int i;
	int compressedSize;
	int uncompressedSize;
	char *src, *dst;
	FILE *f;
	time_t currentTimeT;
	struct tm *currentTime;
	char cleverTime[32];

	time(&currentTimeT);
	currentTime = localtime(&currentTimeT);
	strftime(cleverTime, sizeof(cleverTime), "%Y/%m/%d %H:%M:%S", currentTime);

	*trace++ = ' ';

	for (i = 1; i < argc; i++)
		{
		int size;
		/*
		** This ensures there's always whitespace space between files.   It *also*
		** ensures that src[-1] is always safe in comment detection code below.
		** (Any leading whitespace will be thrown away in a later pass.)
		** --lch
		*/
		*trace++ = ' ';

		f = fopen(argv[i], "rb");
		fseek(f, 0, SEEK_END);
		size = ftell(f);
		fseek(f, 0, SEEK_SET);
		fread(trace, 1, size, f);
		fclose(f);
		trace += size;
		}
	*trace = 0;
	
#define IS_EOL(x) ((*x == '\n') || (*x == '\r'))
#define IS_EOL_COMMENT(x) (((x[0] == '\\') && isspace(x[1]))  || ((x[0] == '/') && (x[1] == '/') && isspace(x[2])))
#define IS_BLOCK_COMMENT(x) ((x[0] == '(') && isspace(x[1]) && isspace(x[-1]))

	src = dst = uncompressed;
	while (*src)
		{
		/* ignore leading whitespace, or entirely blank lines */
		while (isspace(*src))
			src++;
		/* if the line is commented out */
		if (IS_EOL_COMMENT(src))
			{
			/* throw away this entire line */
			while (*src && !IS_EOL(src))
				src++;
			continue;
			}
		/*
		** This is where we'd throw away mid-line comments, but
		** that's simply unsafe.  Things like
		**      start-prefixes
		**      : \ postpone \ ;
		**      : ( postpone ( ;
		** get broken that way.
		** --lch
		*/
		while (*src && !IS_EOL(src))
		{
			*dst++ = *src++;
		}

		/* strip trailing whitespace */
		dst--;
		while (isspace(*dst))
			dst--;
		dst++;

		/* and end the line */
		*dst++ = '\n';
		}

	*dst = 0;

	/* now make a second pass to collapse all contiguous whitespace to a single space. */
	src = dst = uncompressed;
	while (*src)
	{
		*dst++ = *src;
		if (!isspace(*src))
			src++;
		else
		{
			while (isspace(*src))
				src++;
		}
	}
	*dst = 0;

	f = fopen("../softcore.c", "wt");
	if (f == NULL)
		{
		printf("couldn't open ../softcore.c for writing!  giving up.\n");
		exit(-1);
		}

	fprintf(f,
"/*\n"
"** Ficl softcore\n"
"** both uncompressed and Lempel-Ziv compressed versions.\n"
"**\n"
"** Generated %s\n"
"**/\n"
"\n"
"#include \"ficl.h\"\n"
"\n"
"\n",
	cleverTime);
	
	uncompressedSize = dst - uncompressed;
	ficlLzCompress(uncompressed, uncompressedSize, &compressed, &compressedSize);

	fprintf(f, "static size_t ficlSoftcoreUncompressedSize = %d; /* not including trailing null */\n", uncompressedSize);
	fprintf(f, "\n");
	fprintf(f, "#if !FICL_WANT_LZ_SOFTCORE\n");
	fprintf(f, "\n");
	fprintf(f, "static char ficlSoftcoreUncompressed[] =\n");
	fprintDataAsQuotedString(f, uncompressed);
	fprintf(f, ";\n");
	fprintf(f, "\n");
	fprintf(f, "#else /* !FICL_WANT_LZ_SOFTCORE */\n");
	fprintf(f, "\n");
	fprintf(f, "static unsigned char ficlSoftcoreCompressed[%d] = {\n", compressedSize);
	fprintDataAsHex(f, compressed, compressedSize);
	fprintf(f, "\t};\n");
	fprintf(f, "\n");
	fprintf(f, "#endif /* !FICL_WANT_LZ_SOFTCORE */\n");
	fprintf(f,
"\n"
"\n"
"void ficlSystemCompileSoftCore(ficlSystem *system)\n"
"{\n"
"    ficlVm *vm = system->vmList;\n"
"    int returnValue;\n"
"    ficlCell oldSourceID = vm->sourceId;\n"
"    ficlString s;\n"
"#if FICL_WANT_LZ_SOFTCORE\n"
"    char *ficlSoftcoreUncompressed = NULL;\n"
"    size_t gotUncompressedSize = 0;\n"
"    returnValue = ficlLzUncompress(ficlSoftcoreCompressed, (unsigned char **)&ficlSoftcoreUncompressed, &gotUncompressedSize);\n"
"    FICL_VM_ASSERT(vm, returnValue == 0);\n"
"    FICL_VM_ASSERT(vm, gotUncompressedSize == ficlSoftcoreUncompressedSize);\n"
"#endif /* FICL_WANT_LZ_SOFTCORE */\n"
"    vm->sourceId.i = -1;\n"
"    FICL_STRING_SET_POINTER(s, (char *)(ficlSoftcoreUncompressed));\n"
"    FICL_STRING_SET_LENGTH(s, ficlSoftcoreUncompressedSize);\n" 
"    returnValue = ficlVmExecuteString(vm, s);\n"
"    vm->sourceId = oldSourceID;\n"
"#if FICL_WANT_LZ_SOFTCORE\n"
"    free(ficlSoftcoreUncompressed);\n"
"#endif /* FICL_WANT_LZ_SOFTCORE */\n"
"    FICL_VM_ASSERT(vm, returnValue != FICL_VM_STATUS_ERROR_EXIT);\n"
"    return;\n"
"}\n"
"\n"
"/* end-of-file */\n"
		);
	free(uncompressed);
	free(compressed);

	return 0;
	}
Beispiel #11
0
std::string read_user_format_number(std::ifstream &ifs, UserFormatColumn<DATA_T> &ufc,
                                    std::string &line, bool &need_readline, encode_result &encres, char* argv[] = 0)
{
    std::string ret, fm_buffer;
    DATA_T val = 0;
    char* c;

    ret.clear();

    while (std::getline(ifs, line)) {

        encres.line_nr++;
        encres.line_in_blk++;
        c = const_cast<char*>(line.c_str());
        fm_buffer.clear();

        if (IS_COMMENT(line))
            continue;

        /* end of FORMATs of a user block */
        if (IS_BLANK(line)) {

            need_readline = false;
            break;
        }

        while (!IS_EOL(*c) && !IS_EOS(*c)) {

            /* Meeting the next FORMAT, which means this format is done */
            if (IS_LETTER(*c)) {

                need_readline = false;
                break;

            } else if (IS_PLACEHOLD(*c)) {

                if (!TEMPLATE_MODE)
                    throw E2promValueException("Placehold should be used in template file",
                                               to_string<int>(encres.line_nr), usage_allowed_user_format_type);

                E2promMsg("Reading parameter for user "+to_string<uint16_t>(ufc.uheader.ID)+
                          " @ line "+to_string<int>(encres.line_nr));

                read_user_parameters(fm_buffer, ufc.uheader.ID, encres, argv);
                break;

            } else if (IS_DIGIT(*c) || IS_PERIOD(*c)) {

                fm_buffer += *c++;

            } else if (IS_SPACE(*c) || (IS_COMMENT_SIGN(*c))) {

                break;

            } else {

                throw E2promValueException(
                    "Unexpected characters found for type",
                    to_string<int>(encres.line_nr),
                    usage_allowed_user_format_type
                );
            }
        } /* end of read-char while-loop */

//		if (TEMPLATE_MODE)
//			process_fm_buffer(fm_buffer, ufc.uheader.ID);

        if (!fm_buffer.empty()) {

            val = to_digits<DATA_T>(fm_buffer);
            ufc += val;
        }

        if (!IS_LETTER(*c) && !IS_BLANK(line)) {

            need_readline = true;

        } else {

            break;
        }
    } /* end of read-line while-loop */

//		ret += strize_formats<DATA_T>(ufc);
    std::stringstream ss;
//	ss.width(decres.GLOBAL_ALIGNMENT);
    ss << ufc;

    return ss.str();
}
Beispiel #12
0
int cfg_get_token(cfg_token_t* token, cfg_parser_t* st, unsigned int flags)
{
	static int look_ahead = EOF;
	int c;
	enum st state;

	state = ST_S;
	
	token->val.s = token->buf;
	token->val.len = 0;

	if (look_ahead != EOF) {
		c = look_ahead;
		look_ahead = EOF;
	} else {
		READ_CHAR;
	}

	while(c != EOF) {
		switch(state) {
		case ST_S:
			if (flags & CFG_EXTENDED_ALPHA) {
				if (IS_WHITESPACE(c)) {
					     /* Do nothing */
				} else if (IS_ALPHA(c) ||
					   IS_ESCAPE(c) ||
					   IS_DELIM(c)) {
					PUSH(c);
					state = ST_A;
				} else if (IS_QUOTE(c)) {
					state = ST_Q;
				} else if (IS_COMMENT(c)) {
					state = ST_C;
				} else if (IS_EOL(c)) {
					PUSH(c);
					RETURN(c);
				} else {
					ERR("%s:%d:%d: Invalid character 0x%x\n", 
					    st->file, st->line, st->col, c);
					return -1;
				}
			} else {
				if (IS_WHITESPACE(c)) {
					     /* Do nothing */
				} else if (IS_ALPHA(c)) {
					PUSH(c);
					state = ST_A;
				} else if (IS_QUOTE(c)) {
					state = ST_Q;
				} else if (IS_COMMENT(c)) {
					state = ST_C;
				} else if (IS_ESCAPE(c)) {
					state = ST_E;
				} else if (IS_DELIM(c) || IS_EOL(c)) {
					PUSH(c);
					RETURN(c);
				} else {
					ERR("%s:%d:%d: Invalid character 0x%x\n", 
					    st->file, st->line, st->col, c);
					return -1;
				}
			}
			break;

		case ST_A:
			if (flags & CFG_EXTENDED_ALPHA) {
				if (IS_ALPHA(c) ||
				    IS_DELIM(c) ||
				    IS_QUOTE(c)) {
					PUSH(c);
				} else if (IS_ESCAPE(c)) {
					state = ST_AE;
				} else if (IS_COMMENT(c) || IS_EOL(c) || IS_WHITESPACE(c)) {
					look_ahead = c;
					RETURN(CFG_TOKEN_ALPHA);
				} else {
					ERR("%s:%d:%d: Invalid character 0x%x\n", 
					    st->file, st->line, st->col, c);
					return -1;
				}
			} else {
				if (IS_ALPHA(c)) {
					PUSH(c);
				} else if (IS_ESCAPE(c)) {
					state = ST_AE;
				} else if (IS_WHITESPACE(c) ||
					   IS_DELIM(c) ||
					   IS_QUOTE(c) ||
					   IS_COMMENT(c) ||
					   IS_EOL(c)) {
					look_ahead = c;
					RETURN(CFG_TOKEN_ALPHA);
				} else {
					ERR("%s:%d:%d: Invalid character 0x%x\n", 
					    st->file, st->line, st->col, c);
					return -1;
				}
			}
			break;

		case ST_AE:
			if (IS_COMMENT(c) ||
			    IS_QUOTE(c) ||
			    IS_ESCAPE(c)) {
				PUSH(c);
			} else if (c == 'r') {
				PUSH('\r');
			} else if (c == 'n') {
				PUSH('\n');
			} else if (c == 't') {
				PUSH('\t');
			} else if (c == ' ') {
				PUSH(' ');
			} else if (IS_EOL(c)) {
				     /* Do nothing */
			} else {
				ERR("%s:%d:%d: Unsupported escape character 0x%x\n", 
				    st->file, st->line, st->col, c);
				return -1;
			}
			state = ST_A;
			break;

		case ST_Q:
			if (IS_QUOTE(c)) {
				RETURN(CFG_TOKEN_STRING);
			} else if (IS_ESCAPE(c)) {
				state = ST_QE;
				break;
			} else {
				PUSH(c);
			}
			break;

		case ST_QE:
			if (IS_ESCAPE(c) ||
			    IS_QUOTE(c)) {
				PUSH(c);
			} else if (c == 'n') {
				PUSH('\n');
			} else if (c == 'r') {
				PUSH('\r');
			} else if (c == 't') {
				PUSH('\t');
			} else if (IS_EOL(c)) {
				     /* Do nothing */
			} else {
				ERR("%s:%d:%d: Unsupported escape character 0x%x\n", 
				    st->file, st->line, st->col, c);
				return -1;
			}
			state = ST_Q;
			break;

		case ST_C:
			if (IS_ESCAPE(c)) {
				state = ST_CE;
			} else if (IS_EOL(c)) {
				state = ST_S;
				continue; /* Do not read a new char, return EOL */
			} else {
				     /* Do nothing */
			}
			break;

		case ST_CE:
			state = ST_C;
			break;

		case ST_E:
			if (IS_COMMENT(c) ||
			    IS_QUOTE(c) ||
			    IS_ESCAPE(c)) {
				PUSH(c);
				RETURN(c);
			} else if (c == 'r') {
				PUSH('\r');
				RETURN('\r');
			} else if (c == 'n') {
				PUSH('\n');
				RETURN('\n');
			} else if (c == 't') {
				PUSH('\t');
				RETURN('\t');
			} else if (c == ' ') {
				PUSH(' ');
				RETURN(' ');
			} else if (IS_EOL(c)) {
				     /* Escped eol means no eol */
				state = ST_S;
			} else {
				ERR("%s:%d:%d: Unsupported escape character 0x%x\n", 
				    st->file, st->line, st->col, c);
				return -1;
			}
			break;
		}

		READ_CHAR;
	};

	switch(state) {
	case ST_S: 
	case ST_C:
	case ST_CE:
		return 1;

	case ST_A:
		RETURN(CFG_TOKEN_ALPHA);

	case ST_Q:
		ERR("%s:%d:%d: Premature end of file, missing closing quote in"
			" string constant\n", st->file, st->line, st->col);
		return -1;

	case ST_QE:
	case ST_E:
	case ST_AE:
		ERR("%s:%d:%d: Premature end of file, missing escaped character\n", 
		    st->file, st->line, st->col);
		return -1;
	}
	BUG("%s:%d:%d: Invalid state %d\n",
		st->file, st->line, st->col, state);
	return -1;
}
Beispiel #13
0
const char* skip_tochar(const char *p, char end)
{
    while (!IS_EOL(p) && (*p != end)) p++;
    return p;
}
Beispiel #14
0
const char* skip_toeol(const char* p)       { while (*p && !IS_EOL(p)) p++; return p; }                                 // Skip to end of line
Beispiel #15
0
const char* skip_token(const char* p)       { while (*p && !IS_EOL(p) && !IS_SPACE(p) && (*p != '=')) p++; return p; }  // Skip past current token value
Beispiel #16
0
static int add_to_variable_list(char *text_line, FORMAT_PTR format)
{
	VARIABLE_PTR var = NULL;

	char save_char = STR_END;

	char *token = NULL;
	char *endptr = NULL;

	int error = 0;

	if (!format->variables)
	{
		format->variables = dll_init();
		if (!format->variables)
			return(ERR_MEM_LACK);
	}

	token = text_line;
	token = get_token(token, &save_char);
	if (FF_STRLEN(token))
	{
		var = ff_create_variable(token);
		if (var == NULL)
			return ERR_MEM_LACK;
#if 0
			error = ERR_MEM_LACK;
#endif
		if (var->name[0] == '"' && var->name[strlen(var->name) - 1] == '"')
		{
			memmove(var->name, var->name + 1, strlen(var->name) - 2);
			var->name[strlen(var->name) - 2] = STR_END;
		}
	}
	else
	{
		error = err_push(ERR_VARIABLE_DESC, "Expecting a variable name (\"%s\")", format->name);
		goto add_to_variable_list_exit;
	}

	if (!dll_add(format->variables))
	{
		ff_destroy_variable(var);
		error = ERR_MEM_LACK;
		goto add_to_variable_list_exit;
	}

	dll_assign(var, DLL_VAR, dll_last(format->variables));

	token = get_token(token, &save_char);
	if (FF_STRLEN(token))
	{
		errno = 0;
		var->start_pos = strtol(token, &endptr, 10);
		if (errno || FF_STRLEN(endptr))
		{
			error = err_push(errno ? errno : ERR_PARAM_VALUE, "Bad number for variable start position: %s", token);
			goto add_to_variable_list_exit;
		}
	}
	else
	{
		error = err_push(ERR_VARIABLE_DESC, "Expecting a start position for \"%s\"", var->name);
		goto add_to_variable_list_exit;
	}

	token = get_token(token, &save_char);
	if (FF_STRLEN(token))
	{
		errno = 0;
		var->end_pos = strtol(token, &endptr, 10);
		if (errno || FF_STRLEN(endptr))
		{
			error = err_push(errno ? errno : ERR_PARAM_VALUE, "Bad number for variable end position: %s", token);
			goto add_to_variable_list_exit;
		}
	}
	else
	{
		error = err_push(ERR_VARIABLE_DESC, "Expecting an end position for \"%s\"", var->name);
		goto add_to_variable_list_exit;
	}

	token = get_token(token, &save_char);
	if (FF_STRLEN(token))
	{
		FFV_TYPE(var) = ff_lookup_number(variable_types, token);
		if (FFV_TYPE(var) == FF_VAR_TYPE_FLAG)
		{
			if (os_strncmpi("ARRAY", token, 5) == 0)
			{
				RESTORE_CHAR(token, save_char);
				save_char = STR_END;
				error = parse_array_variable(&token, var);
				if (error)
					goto add_to_variable_list_exit;

				format->type |= FF_ARRAY;
			}
			else
			{
				/* Is this a keyworded variable type?  If so, remember name of keyword in record_title */
				if (IS_KEYWORDED_PARAMETER(token))
				{
					FFV_TYPE(var) = 0;

					assert(!var->record_title);

					if (var->record_title)
						memFree(var->record_title, "var->record_title");

					var->record_title = (char *)memStrdup(token, "token");
					if (!var->record_title)
					{
						error = err_push(ERR_MEM_LACK, "");
						goto add_to_variable_list_exit;
					}
				}
				else
				{
					error = err_push(ERR_UNKNOWN_VAR_TYPE, token);
					goto add_to_variable_list_exit;
				}
			}
		}
	}
	else
	{
		error = err_push(ERR_VARIABLE_DESC, "Expecting a variable type or array description for \"%s\"", var->name);
		goto add_to_variable_list_exit;
	}

	token = get_token(token, &save_char);
	if (FF_STRLEN(token))
	{
		errno = 0;
		var->precision = (short)strtol(token, &endptr, 10);
		if (errno || FF_STRLEN(endptr))
		{
			error = err_push(errno ? errno : ERR_PARAM_VALUE, "Bad number for variable precision: %s", token);
			goto add_to_variable_list_exit;
		}
	}
	else
	{
		if (IS_ARRAY(var))
		{
			error = err_push(ERR_VARIABLE_DESC, "Expecting a precision for \"%s\"", var->name);
			goto add_to_variable_list_exit;
		}
	}

	if (var->end_pos < var->start_pos)
	{
		error = err_push(ERR_VARIABLE_DESC,"End Position < Start Position\n%s", text_line);
		goto add_to_variable_list_exit;
	}

	/* Determine The Variable Type */
	if (var->start_pos == 0 && var->end_pos == 0)
	{
		if (IS_BINARY(format))
		{
			error = err_push(ERR_UNKNOWN_FORMAT_TYPE, "Illegal to have delimited binary format");
			goto add_to_variable_list_exit;
		}
		else if (IS_ARRAY(format))
		{
			error = err_push(ERR_UNKNOWN_FORMAT_TYPE, "Illegal to have delimited array format");
			goto add_to_variable_list_exit;
		}

		format->type |= FFF_VARIED;
	}

	if (NEED_TO_CHECK_VARIABLE_SIZE(format, var))
	{
		if (ffv_type_size(var->type) != var->end_pos - var->start_pos + 1)
		{
			char save_eol_char = STR_END;
			char *end_of_line = find_EOL(text_line);

			if (end_of_line)
			{
				save_eol_char = *end_of_line;
				*end_of_line = STR_END;
			}

			error = err_push(ERR_VARIABLE_SIZE,"Expecting ending position for binary field %s to be %d", var->name, var->start_pos + ffv_type_size(var->type) - 1);

			if (end_of_line)
				*end_of_line = save_eol_char;

			goto add_to_variable_list_exit;
		}
	}

	check_old_style_EOL_var(var);
	
	/* Does length of CONSTANT variable name equal length of variable? */
	if (IS_CONSTANT(var) && !IS_EOL(var))
	{
		if (FF_STRLEN(var->name) > FF_VAR_LENGTH(var))
		{
			error = err_push(ERR_VARIABLE_SIZE, "Constant variable initializer (%s) is too long for field", var->name);

			goto add_to_variable_list_exit;
		}
		else if (FF_STRLEN(var->name) < FF_VAR_LENGTH(var))
			error = err_push(ERR_WARNING_ONLY + ERR_VARIABLE_SIZE, "Constant variable initializer (%s) is shorter than field", var->name);
	}

	format->num_vars++;
	format->length = max(format->length, var->end_pos);

add_to_variable_list_exit:

	if (error)
	{
		char *cp;
		char EOL_char = STR_END;

		/* Don't destroy variable since it will be destroyed in ff_destroy_format */

		cp = find_EOL(text_line);
		if (cp)
		{
			EOL_char = *cp;
			*cp = STR_END;
		}

		error = err_push(ERR_VARIABLE_DESC + (error > ERR_WARNING_ONLY ? ERR_WARNING_ONLY : 0),text_line);

		if (cp)
			*cp = EOL_char;

	}

	RESTORE_CHAR(token, save_char);

	return(error);
}