/xmlfy-1.5.5/xmlfy/validate_args/process_arg_expel.c
# · C · 478 lines · 380 code · 38 blank · 60 comment · 130 complexity · cbdfbef0b45823abdc938f365fdae4f6 MD5 · raw file
- /*
- * BSD License for xmlfy
- * Copyright (c) 2008-2011, Arthur Gouros
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * - Neither the name of Arthur Gouros nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
- /**************************************************************************
- * xmlfy - Convert to XML on the fly. *
- * Original Author: Arthur Gouros. *
- * *
- * Please consult the documentation for further information. *
- **************************************************************************
- */
- #include "validate_args.h"
- /* function templates */
- int process_arg_expel(unsigned char *s);
- int set_flag_string(int status, int pos, unsigned char *s, int s_length);
- int process_arg_expel(s)
- unsigned char *s;
- {
- /* translate expel arg to expel structure */
- unsigned char *records, *fields, string_delimiter;
- int s_length, r_length, f_length;
- int i, j, ret;
- char value[10];
- int i_value;
- int flag_string;
- /* initialise */
- ret = TRUE;
- s_length = xstrlen(s);
- flag_string = FALSE;
- string_delimiter = '/';
- if (s_length == 0)
- ret = FALSE;
- /* ensure legal characters */
- j = 0;
- for (i = 0 ; i < s_length ; i++)
- {
- switch (s[i])
- {
- case '0' :
- case '1' :
- case '2' :
- case '3' :
- case '4' :
- case '5' :
- case '6' :
- case '7' :
- case '8' :
- case '9' :
- case '$' :
- case '-' :
- case ',' :
- case 'n' :
- case 'f' :
- case 'c' :
- case '\'' :
- case '\"' :
- break;
- case '/' :
- case '%' : if (!flag_string)
- string_delimiter = s[i];
- if (string_delimiter == s[i])
- flag_string = set_flag_string(flag_string, i, s, s_length);
- break;
- case ':' : if (!flag_string)
- j++;
- break;
- default : if (!flag_string)
- ret = FALSE;
- }
- }
- if (j > 1)
- ret = FALSE;
- if (ret)
- {
- /* split arg into records/fields components */
- i = 0;
- flag_string = FALSE;
- while (i < s_length && (flag_string || s[i] != ':'))
- {
- if (!flag_string && (s[i] == '/' || s[i] == '%'))
- string_delimiter = s[i];
- if (s[i] == string_delimiter)
- flag_string = set_flag_string(flag_string, i, s, s_length);
- i++;
- }
- if (i == s_length)
- {
- records = s;
- r_length = s_length;
- fields = NULL;
- f_length = 0;
- }
- else
- {
- records = s;
- r_length = i;
- fields = &s[i + 1];
- f_length = s_length - i - 1;
- /* ensure legal field chars */
- for (i = 0 ; i < f_length ; i++)
- {
- switch (fields[i])
- {
- case '0' :
- case '1' :
- case '2' :
- case '3' :
- case '4' :
- case '5' :
- case '6' :
- case '7' :
- case '8' :
- case '9' :
- case '$' :
- case '-' :
- case ',' :
- case '\'' :
- case '\"' :
- break;
- default :
- ret = FALSE;
- }
- }
- }
- }
- if (ret)
- {
- /* allocate memory for expel structure */
- if (nexpel)
- expel = (struct_expel *) realloc(expel, ((nexpel + 1) * sizeof(struct_expel)));
- else
- expel = (struct_expel *) malloc(sizeof(struct_expel));
- if (expel == NULL) out_of_mem();
- /* calc number of records/fields */
- expel[nexpel].n_erecords = 1;
- flag_string = FALSE;
- for (i = 0 ; i < r_length ; i++)
- {
- if (!flag_string && (records[i] == '/' || records[i] == '%'))
- string_delimiter = records[i];
- if (records[i] == string_delimiter)
- flag_string = set_flag_string(flag_string, i, records, r_length);
- if (!flag_string && records[i] == ',')
- expel[nexpel].n_erecords++;
- }
- if (f_length > 0)
- {
- expel[nexpel].n_efields = 1;
- for (i = 0 ; i < f_length ; i++)
- if (fields[i] == ',')
- expel[nexpel].n_efields++;
- }
- else
- expel[nexpel].n_efields = 0;
- /* allocate ranges */
- expel[nexpel].erecords = (struct_erecords *) malloc(expel[nexpel].n_erecords * sizeof(struct_erecords));
- if (expel[nexpel].erecords == NULL) out_of_mem();
- if (expel[nexpel].n_efields)
- {
- expel[nexpel].efields = (struct_efields *) malloc(expel[nexpel].n_efields * sizeof(struct_efields));
- if (expel[nexpel].efields == NULL) out_of_mem();
- }
- for (i = 0 ; i < expel[nexpel].n_erecords ; i++)
- {
- expel[nexpel].erecords[i].type = RANGE_UNSET;
- expel[nexpel].erecords[i].min = RANGE_UNSET;
- expel[nexpel].erecords[i].max = RANGE_UNSET;
- expel[nexpel].erecords[i].s = NULL;
- expel[nexpel].erecords[i].s_length = 0;
- }
- for (i = 0 ; i < expel[nexpel].n_efields ; i++)
- {
- expel[nexpel].efields[i].min = RANGE_UNSET;
- expel[nexpel].efields[i].max = RANGE_UNSET;
- }
- /* populate expel structure */
- j = 0;
- i_value = 0;
- value[0] = '\0';
- flag_string = FALSE;
- for (i = 0 ; i < r_length ; i++)
- {
- if (!flag_string && (records[i] == '/' || records[i] == '%'))
- string_delimiter = records[i];
- switch (records[i])
- {
- case '/' :
- case '%' : if (!flag_string)
- {
- if (i + 1 < r_length)
- {
- flag_string = TRUE;
- expel[nexpel].erecords[j].s = &records[i + 1];
- /* read up to next matching forward slash */
- while (i + expel[nexpel].erecords[j].s_length + 1 < r_length && flag_string)
- {
- if (records[i + expel[nexpel].erecords[j].s_length + 1] == string_delimiter)
- flag_string = set_flag_string(flag_string, i + expel[nexpel].erecords[j].s_length + 1, records, r_length);
- if (flag_string)
- expel[nexpel].erecords[j].s_length++;
- }
- if (flag_string)
- ret = FALSE;
- i += expel[nexpel].erecords[j].s_length + 1;
- }
- }
- else
- ret = FALSE;
- break;
- case '\'' :
- case '\"' : i_value = 0;
- break;
- case 'n' : if (expel[nexpel].erecords[j].type == RANGE_UNSET)
- expel[nexpel].erecords[j].type = EXPEL_TYPE_N;
- else
- ret = FALSE;
- i_value = 0;
- break;
- case 'f' : if (expel[nexpel].erecords[j].type == RANGE_UNSET)
- expel[nexpel].erecords[j].type = EXPEL_TYPE_F;
- else
- ret = FALSE;
- i_value = 0;
- break;
- case 'c' : if (expel[nexpel].erecords[j].type == RANGE_UNSET)
- expel[nexpel].erecords[j].type = EXPEL_TYPE_C;
- else
- ret = FALSE;
- i_value = 0;
- break;
- case '$' : if (expel[nexpel].erecords[j].min == RANGE_UNSET)
- ret = FALSE; /* in this release the last record must be in a range */
- else
- expel[nexpel].erecords[j].max = -1;
- i_value = 0;
- break;
- case '-' : if (i_value)
- {
- if (expel[nexpel].erecords[j].min == RANGE_UNSET)
- {
- expel[nexpel].erecords[j].min = atol(value) - 1;
- if (expel[nexpel].erecords[j].min < 0)
- ret = FALSE;
- }
- }
- else
- expel[nexpel].erecords[j].min = 0;
- i_value = 0;
- /* pre-populate max field in case not supplied */
- expel[nexpel].erecords[j].max = -1;
- break;
- case ',' : if (i_value)
- {
- if (expel[nexpel].erecords[j].min == RANGE_UNSET)
- {
- expel[nexpel].erecords[j].min = atol(value) - 1;
- if (expel[nexpel].erecords[j].min < 0)
- ret = FALSE;
- /* pre-populate max field in case not supplied */
- expel[nexpel].erecords[j].max = expel[nexpel].erecords[j].min;
- }
- else
- {
- expel[nexpel].erecords[j].max = atol(value) - 1;
- if (expel[nexpel].erecords[j].max < 0)
- ret = FALSE;
- }
- }
- i_value = 0;
- /* quick sanity check */
- if (expel[nexpel].erecords[j].type == RANGE_UNSET || (expel[nexpel].erecords[j].max > 0 && expel[nexpel].erecords[j].min > expel[nexpel].erecords[j].max))
- ret = FALSE;
- j++;
- break;
- default : value[i_value++] = records[i];
- value[i_value] = '\0';
- }
- }
- if (i_value)
- {
- if (expel[nexpel].erecords[j].min == RANGE_UNSET)
- {
- expel[nexpel].erecords[j].min = atol(value) - 1;
- if (expel[nexpel].erecords[j].min < 0)
- ret = FALSE;
- /* pre-populate max field in case not supplied */
- expel[nexpel].erecords[j].max = expel[nexpel].erecords[j].min;
- }
- else
- {
- expel[nexpel].erecords[j].max = atol(value) - 1;
- if (expel[nexpel].erecords[j].max < 0)
- ret = FALSE;
- }
- }
- /* quick sanity check */
- if (j < expel[nexpel].n_erecords && (expel[nexpel].erecords[j].type == RANGE_UNSET || (expel[nexpel].erecords[j].max > 0 && expel[nexpel].erecords[j].min > expel[nexpel].erecords[j].max)))
- ret = FALSE;
- if (expel[nexpel].n_efields)
- {
- j = 0;
- i_value = 0;
- value[0] = '\0';
- for (i = 0 ; i < f_length ; i++)
- {
- switch (fields[i])
- {
- case '\'' :
- case '\"' : i_value = 0;
- break;
- case '$' : if (expel[nexpel].efields[j].min == RANGE_UNSET)
- {
- expel[nexpel].efields[j].min = -1;
- /* pre-populate max field in case not supplied */
- expel[nexpel].efields[j].max = -1;
- }
- else
- expel[nexpel].efields[j].max = -1;
- i_value = 0;
- break;
- case '-' : if (i_value)
- {
- if (expel[nexpel].efields[j].min == RANGE_UNSET)
- {
- expel[nexpel].efields[j].min = atol(value) - 1;
- if (expel[nexpel].efields[j].min < 0)
- ret = FALSE;
- }
- }
- else
- expel[nexpel].efields[j].min = 0;
- i_value = 0;
- /* pre-populate max field in case not supplied */
- expel[nexpel].efields[j].max = -1;
- break;
- case ',' : if (i_value)
- {
- if (expel[nexpel].efields[j].min == RANGE_UNSET)
- {
- expel[nexpel].efields[j].min = atol(value) - 1;
- if (expel[nexpel].efields[j].min < 0)
- ret = FALSE;
- /* pre-populate max field in case not supplied */
- expel[nexpel].efields[j].max = expel[nexpel].efields[j].min;
- }
- else
- {
- expel[nexpel].efields[j].max = atol(value) - 1;
- if (expel[nexpel].efields[j].max < 0)
- ret = FALSE;
- }
- }
- i_value = 0;
- /* quick sanity check */
- if (expel[nexpel].efields[j].max > 0 && expel[nexpel].efields[j].min > expel[nexpel].efields[j].max)
- ret = FALSE;
- j++;
- break;
-
- default : value[i_value++] = fields[i];
- value[i_value] = '\0';
- }
- }
- if (i_value)
- {
- if (expel[nexpel].efields[j].min == RANGE_UNSET)
- {
- expel[nexpel].efields[j].min = atol(value) - 1;
- if (expel[nexpel].efields[j].min < 0)
- ret = FALSE;
- /* pre-populate max field in case not supplied */
- expel[nexpel].efields[j].max = expel[nexpel].efields[j].min;
- }
- else
- {
- expel[nexpel].efields[j].max = atol(value) - 1;
- if (expel[nexpel].efields[j].max < 0)
- ret = FALSE;
- }
- /* quick sanity check */
- if (expel[nexpel].efields[j].max > 0 && expel[nexpel].efields[j].min > expel[nexpel].efields[j].max)
- ret = FALSE;
- }
- /* quick sanity check */
- for (i = 0 ; i < expel[nexpel].n_efields ; i++)
- if (expel[nexpel].efields[i].min == RANGE_UNSET && expel[nexpel].efields[i].max == RANGE_UNSET)
- ret = FALSE;
- }
- nexpel++;
- }
- return(ret);
- }
- int set_flag_string(status, pos, s, s_length)
- int status;
- int pos;
- unsigned char *s;
- int s_length;
- {
- /* Toggle the flag_status and ensure the terminating string delimiter is correctly identified */
- if (!status)
- status = TRUE;
- else if (pos + 1 >= s_length)
- status = FALSE;
- else
- {
- switch (s[pos + 1])
- {
- case '\'' :
- case '\"' :
- case ',' :
- case ':' :
- status = FALSE;
- }
- }
- return(status);
- }