diff --git a/src/slurmctld/buffer.c b/src/slurmctld/buffer.c new file mode 100644 index 0000000000000000000000000000000000000000..bd91e6a307e4710a4b257ff607440b107432bf14 --- /dev/null +++ b/src/slurmctld/buffer.c @@ -0,0 +1,58 @@ +/* $Id$ */ + +/* seemingly unused buffer functions */ + +/* + * read_buffer - read a line from the specified buffer + * input: buffer - pointer to read buffer, must be allocated by alloc() + * buffer_offset - byte offset in buffer, read location + * buffer_size - byte size of buffer + * line - pointer to location to be loaded with pointer to the line + * output: buffer_offset - incremented by size of size plus the value size itself + * line - set to pointer to the line + * returns 0 if no error or EFAULT on end of buffer, EINVAL on bad tag + */ +int +read_buffer (char *buffer, int *buffer_offset, int buffer_size, char **line) +{ + if ((*buffer_offset) >= buffer_size) + return EFAULT; + line[0] = &buffer[*buffer_offset]; + (*buffer_offset) += (strlen (line[0]) + 1); + + if ((*buffer_offset) > buffer_size) + return EFAULT; + return 0; +} + +/* + * write_buffer - write the specified line to the specified buffer, + * enlarging the buffer as needed + * input: buffer - pointer to write buffer, must be allocated by alloc() + * buffer_offset - byte offset in buffer, write location + * buffer_size - byte size of buffer + * line - pointer to data to be writen + * output: buffer - value is written here, buffer may be relocated by xrealloc() + * buffer_offset - incremented by value_size + * returns 0 if no error or errno otherwise + */ +int +write_buffer (char **buffer, int *buffer_offset, int *buffer_size, char *line) +{ + int line_size; + + line_size = strlen (line) + 1; + if ((*buffer_offset + line_size) >= *buffer_size) { + (*buffer_size) += line_size + 8096; + if (buffer[0]) + xrealloc (buffer[0], *buffer_size); + else + buffer[0] = xmalloc(*buffer_size); + } + + memcpy (buffer[0] + (*buffer_offset), line, line_size); + (*buffer_offset) += line_size; + return 0; +} + + diff --git a/src/slurmctld/parse_spec.c b/src/slurmctld/parse_spec.c new file mode 100644 index 0000000000000000000000000000000000000000..7fe6329e2ed61204c6702a268d1aaa00aeb26678 --- /dev/null +++ b/src/slurmctld/parse_spec.c @@ -0,0 +1,204 @@ +/* $Id$ */ + +/* slurm_parser() functionality - split out from bits_bytes.c and + * moved into slurmctld/ srcdir + */ + +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> + +#include "log.h" +#include "xmalloc.h" + +#define BUF_SIZE 1024 +#define SEPCHARS " \n\t" + +/* + * slurm_parser - parse the supplied specification into keyword/value pairs + * only the keywords supplied will be searched for. the supplied specification + * is altered, overwriting the keyword and value pairs with spaces. + * input: spec - pointer to the string of specifications + * sets of three values (as many sets as required): keyword, type, value + * keyword - string with the keyword to search for including equal sign + * (e.g. "name=") + * type - char with value 'd' for int, 'f' for float, 's' for string + * value - pointer to storage location for value (char **) for type 's' + * output: spec - everything read is overwritten by speces + * value - set to read value (unchanged if keyword not found) + * return - 0 if no error, otherwise errno code + * NOTE: terminate with a keyword value of "END" + * NOTE: values of type (char *) are xfreed if non-NULL. caller must xfree any + * returned value + */ +int +slurm_parser (char *spec, ...) +{ + va_list ap; + char *keyword, **str_ptr; + int error_code, *int_ptr, type; + float *float_ptr; + + error_code = 0; + va_start(ap, spec); + while (error_code == 0) { + keyword = va_arg(ap, char *); + if (strcmp (keyword, "END") == 0) + break; + type = va_arg(ap, int); + switch (type) { + case 'd': + int_ptr = va_arg(ap, int *); + error_code = load_integer(int_ptr, keyword, spec); + break; + case 'f': + float_ptr = va_arg(ap, float *); + error_code = load_float(float_ptr, keyword, spec); + break; + case 's': + str_ptr = va_arg(ap, char **); + error_code = load_string(str_ptr, keyword, spec); + break; + default: + fatal ("parse_spec: invalid type %c", type); + } + } + va_end(ap); + return error_code; +} + + +/* + * load_float - location into which result is stored + * keyword - string to search for + * in_line - string to search for keyword + * output: *destination - set to value, no change if value not found + * in_line - the keyword and value (if present) are overwritten by spaces + * return value - 0 if no error, otherwise an error code + * NOTE: in_line is overwritten, do not use a constant + */ +int +load_float (float *destination, char *keyword, char *in_line) +{ + char scratch[BUF_SIZE]; /* scratch area for parsing the input line */ + char *str_ptr1, *str_ptr2, *str_ptr3; + int i, str_len1, str_len2; + + str_ptr1 = (char *) strstr (in_line, keyword); + if (str_ptr1 != NULL) { + str_len1 = strlen (keyword); + strcpy (scratch, str_ptr1 + str_len1); + if ((scratch[0] < '0') && (scratch[0] > '9')) { + error ("load_float: bad value for keyword %s\n", keyword); + return EINVAL; + } + str_ptr2 = (char *) strtok_r (scratch, SEPCHARS, &str_ptr3); + str_len2 = strlen (str_ptr2); + *destination = (float) strtod (scratch, (char **) NULL); + for (i = 0; i < (str_len1 + str_len2); i++) { + str_ptr1[i] = ' '; + } + } + return 0; +} + + +/* + * load_integer - parse a string for a keyword, value pair + * input: *destination - location into which result is stored + * keyword - string to search for + * in_line - string to search for keyword + * output: *destination - set to value, no change if value not found, + * set to 1 if keyword found without value, + * set to -1 if keyword followed by "unlimited" + * in_line - the keyword and value (if present) are overwritten by spaces + * return value - 0 if no error, otherwise an error code + * NOTE: in_line is overwritten, do not use a constant + */ +int +load_integer (int *destination, char *keyword, char *in_line) +{ + char scratch[BUF_SIZE]; /* scratch area for parsing the input line */ + char *str_ptr1, *str_ptr2, *str_ptr3; + int i, str_len1, str_len2; + + str_ptr1 = (char *) strstr (in_line, keyword); + if (str_ptr1 != NULL) { + str_len1 = strlen (keyword); + strcpy (scratch, str_ptr1 + str_len1); + if ((scratch[0] == (char) NULL) || + (isspace ((int) scratch[0]))) { /* keyword with no value set */ + *destination = 1; + str_len2 = 0; + } + else { + str_ptr2 = + (char *) strtok_r (scratch, SEPCHARS, &str_ptr3); + str_len2 = strlen (str_ptr2); + if (strcmp (str_ptr2, "UNLIMITED") == 0) + *destination = -1; + else if ((str_ptr2[0] >= '0') && (str_ptr2[0] <= '9')) { + *destination = + (int) strtol (scratch, (char **) NULL, 10); + } + else { + error ("load_integer: bad value for keyword %s\n", + keyword); + return EINVAL; + } + } + + for (i = 0; i < (str_len1 + str_len2); i++) { + str_ptr1[i] = ' '; + } + } + return 0; +} + + +/* + * load_string - parse a string for a keyword, value pair + * input: *destination - location into which result is stored + * keyword - string to search for + * in_line - string to search for keyword + * output: *destination - set to value, no change if value not found, + * if *destination had previous value, that memory location is automatically freed + * in_line - the keyword and value (if present) are overwritten by spaces + * return value - 0 if no error, otherwise an error code + * NOTE: destination must be free when no longer required + * NOTE: if destination is non-NULL at function call time, it will be freed + * NOTE: in_line is overwritten, do not use a constant + */ +int +load_string (char **destination, char *keyword, char *in_line) +{ + char scratch[BUF_SIZE]; /* scratch area for parsing the input line */ + char *str_ptr1, *str_ptr2, *str_ptr3; + int i, str_len1, str_len2; + + str_ptr1 = (char *) strstr (in_line, keyword); + if (str_ptr1 != NULL) { + str_len1 = strlen (keyword); + strcpy (scratch, str_ptr1 + str_len1); + if ((scratch[0] == (char) NULL) || + (isspace ((int) scratch[0]))) { /* keyword with no value set */ + error ("load_string: keyword %s lacks value\n", + keyword); + return EINVAL; + } + str_ptr2 = (char *) strtok_r (scratch, SEPCHARS, &str_ptr3); + str_len2 = strlen (str_ptr2); + if (destination[0] != NULL) + xfree (destination[0]); + destination[0] = (char *) xmalloc (str_len2 + 1); + strcpy (destination[0], str_ptr2); + for (i = 0; i < (str_len1 + str_len2); i++) { + str_ptr1[i] = ' '; + } + } + return 0; +} + + diff --git a/src/slurmctld/util.c b/src/slurmctld/util.c new file mode 100644 index 0000000000000000000000000000000000000000..38aa4513627546f527e52677a3f8280f66e7a1b1 --- /dev/null +++ b/src/slurmctld/util.c @@ -0,0 +1,38 @@ +/* $Id$ */ + +/* generic utility functions used by slurmctld: + * + */ + +#include <string.h> + +#include <src/slurmctld/util.h> + +/* + * block_or_cycle - map string into integer + * input: in_string: pointer to string containing "BLOCK" or "CYCLE" + * output: returns DIST_BLOCK for "BLOCK", DIST_CYCLE for "CYCLE", -1 otherwise + */ +enum task_dist +block_or_cycle (char *in_string) +{ + if (strcmp (in_string, "BLOCK") == 0) return DIST_BLOCK; + if (strcmp (in_string, "CYCLE") == 0) return DIST_CYCLE; + return -1; +} + +/* + * yes_or_no - map string into integer + * input: in_string: pointer to string containing "YES" or "NO" + * output: returns 1 for "YES", 0 for "NO", -1 otherwise + */ +int +yes_or_no (char *in_string) +{ + if (strcmp (in_string, "YES") == 0) return 1; + if (strcmp (in_string, "NO") == 0) return 0; + return -1; +} + + + diff --git a/src/slurmctld/util.h b/src/slurmctld/util.h new file mode 100644 index 0000000000000000000000000000000000000000..4edfc38542a0e416c15abd4b805d0e9cabd3007e --- /dev/null +++ b/src/slurmctld/util.h @@ -0,0 +1,12 @@ +/* $Id$ */ + +#ifndef _UTIL_H +#define _UTIL_H + +#include "slurmctld.h" + +enum task_dist block_or_cycle (char *in_string); +int yes_or_no (char *in_string); + + +#endif /* !_UTIL_H */