/** Read one single option from file into the given buffer. When the first separator is encountered it returns. Actions: - read chars while not eof - skip comments (parts beginning with '#' and ending with '\n') - switch to DATA STATE if non space char is encountered - assume first name in lines to be a long option name by adding '--' if necesssary - add data to buffer - do not forget a 0 at the end * States: * NEW_LINE - wait here until some option. Add '--' if not already there * SPACE - between options. Like NEW_LINE but no additions * DATA - real data. Stop on space. * COMMENT - everything beginning with # until EOLine * ESCAPE - everything that is otherwise (incl. spaces). Next char is raw copied. */ static RC_TYPE parser_read_option(OPTION_FILE_PARSER *p_cfg, char *p_buffer, int maxlen) { RC_TYPE rc = RC_OK; BOOL parse_end = FALSE; int count = 0; *p_buffer = 0; while (!parse_end) { char ch; { int n; if ((n = fscanf(p_cfg->p_file, "%c", &ch)) < 0) { if (feof(p_cfg->p_file)) { break; } rc = RC_FILE_IO_READ_ERROR; break; } } switch (p_cfg->state) { case NEW_LINE: if (ch == '\\') { p_cfg->state = ESCAPE; break; } if (ch == '#') /*comment*/ { p_cfg->state = COMMENT; break; } if (!isspace(ch)) { if (ch != '-')/*add '--' to first word in line*/ { if ((rc = push_in_buffer("--", 2, p_buffer, &count, maxlen)) != RC_OK) { break; } } if ((rc = push_in_buffer(&ch, 1, p_buffer, &count, maxlen)) != RC_OK) { break; } p_cfg->state = DATA; break; } /*skip actual leading spaces*/ break; case SPACE: if (ch == '\\') { p_cfg->state = ESCAPE; break; } if (ch == '#') /*comment*/ { p_cfg->state = COMMENT; break; } if (ch == '\n' || ch == '\r') { p_cfg->state = NEW_LINE; break; } if (!isspace(ch)) { if ((rc = push_in_buffer(&ch, 1, p_buffer, &count, maxlen)) != RC_OK) { break; } p_cfg->state = DATA; break; } break; case COMMENT: if (ch == '\n' || ch == '\r') { p_cfg->state = NEW_LINE; } /*skip comments*/ break; case DATA: if (ch == '\\') { p_cfg->state = ESCAPE; break; } if (ch == '#') { p_cfg->state = COMMENT; break; } if (ch == '\n' || ch == '\r') { p_cfg->state = NEW_LINE; parse_end = TRUE; break; } if (isspace(ch)) { p_cfg->state = SPACE; parse_end = TRUE; break; } /*actual data*/ if ((rc = push_in_buffer(&ch, 1, p_buffer, &count, maxlen)) != RC_OK) { break; } break; case ESCAPE: if ((rc = push_in_buffer(&ch, 1, p_buffer, &count, maxlen)) != RC_OK) { break; } p_cfg->state = DATA; break; default: rc = RC_CMD_PARSER_INVALID_OPTION; } if (rc != RC_OK) { break; } } if (rc == RC_OK) { char ch = 0; rc = push_in_buffer(&ch, 1, p_buffer, &count, maxlen); } return rc; }
/** Read one single option from file into the given buffer. When the first separator is encountered it returns. Actions: - read chars while not eof - skip comments (parts beginning with '#' and ending with '\n') - switch to DATA STATE if non space char is encountered - assume first name in lines to be a long option name by adding '--' if necesssary - add data to buffer - do not forget a 0 at the end * States: * NEW_LINE - wait here until some option. Add '--' if not already there * SPACE - between options. Like NEW_LINE but no additions * DATA - real data. Stop on space. * COMMENT - everything beginning with # until EOLine * ESCAPE - everything that is otherwise (incl. spaces). Next char is raw copied. */ static int parser_read_option(cfg_parser_t *cfg, char *p_buffer, int maxlen) { int rc = 0; int parse_end = 0; int count = 0; *p_buffer = 0; while (!parse_end) { char ch; { int n; if ((n = fscanf(cfg->fp, "%c", &ch)) < 0) { if (feof(cfg->fp)) break; rc = RC_FILE_IO_READ_ERROR; break; } } switch (cfg->state) { case NEW_LINE: if (ch == '\\') { cfg->state = ESCAPE; break; } if (ch == '#') { /*comment */ cfg->state = COMMENT; break; } if (!isspace(ch)) { if (ch != '-') { /*add '--' to first word in line */ if ((rc = push_in_buffer("--", 2, p_buffer, &count, maxlen)) != 0) break; } if ((rc = push_in_buffer(&ch, 1, p_buffer, &count, maxlen)) != 0) break; cfg->state = DATA; break; } /*skip actual leading spaces */ break; case SPACE: if (ch == '\\') { cfg->state = ESCAPE; break; } if (ch == '#') { /*comment */ cfg->state = COMMENT; break; } if (ch == '\n' || ch == '\r') { cfg->state = NEW_LINE; break; } if (!isspace(ch)) { if ((rc = push_in_buffer(&ch, 1, p_buffer, &count, maxlen)) != 0) break; cfg->state = DATA; break; } break; case COMMENT: /*skip comments */ if (ch == '\n' || ch == '\r') cfg->state = NEW_LINE; break; case DATA: if (ch == '\\') { cfg->state = ESCAPE; break; } if (ch == '#') { cfg->state = COMMENT; break; } if (ch == '\n' || ch == '\r') { cfg->state = NEW_LINE; parse_end = 1; break; } if (isspace(ch)) { cfg->state = SPACE; parse_end = 1; break; } /*actual data */ if ((rc = push_in_buffer(&ch, 1, p_buffer, &count, maxlen)) != 0) break; break; case ESCAPE: if ((rc = push_in_buffer(&ch, 1, p_buffer, &count, maxlen)) != 0) break; cfg->state = DATA; break; default: rc = RC_CMD_PARSER_INVALID_OPTION; break; } if (rc != 0) break; } if (rc == 0) { char ch = 0; rc = push_in_buffer(&ch, 1, p_buffer, &count, maxlen); } return rc; }