/** * @brief get a line from a file pointed at by fp. The line can be extended * onto the next line if it ends in a backslash (\). If the string is * extended, the lines will be combined and the backslash will be * stripped. * * @param[in] fp pointer to file to read from * @param[in, out] pbuf_size - pointer to size of buffer * @param[in, out] pbuf - pointer to buffer * * @return char * * @retval string read from file * @retval NULL - EOF or error * @par MT-Safe: no */ char * pbs_fgets_extend(char **pbuf, int *pbuf_size, FILE *fp) { static char *locbuf = NULL; static int locbuf_size = 0; char *buf; char *p; int len; if (pbuf == NULL || pbuf_size == NULL || fp == NULL) return NULL; if (locbuf == NULL) { if ((locbuf = malloc(PBS_FGETS_LINE_LEN)) == NULL) return NULL; locbuf_size = PBS_FGETS_LINE_LEN; } if (*pbuf_size == 0 || *pbuf == NULL) { if ((*pbuf = malloc(PBS_FGETS_LINE_LEN)) == NULL) return NULL; *pbuf_size = PBS_FGETS_LINE_LEN; } buf = *pbuf; locbuf[0] = '\0'; buf[0] = '\0'; while ((p = pbs_fgets(&locbuf, &locbuf_size, fp)) != NULL) { if (pbs_strcat(pbuf, pbuf_size, locbuf) == NULL) return NULL; buf = *pbuf; len = strlen(buf); /* we have two options: * 1) We extend: string ends in a '\' and 0 or more whitespace * 2) we do not extend: Not #1 * In the case of #1, we want the string to end just before the '\' * In the case of #2 we want to leave the string alone. */ while (len > 0 && isspace(buf[len-1])) len--; if (len > 0) { if (buf[len - 1] != '\\') { break; } else { buf[len - 1] = '\0'; /* remove the backslash (\) */ } } } /* if we read just EOF */ if (p == NULL && buf[0] == '\0') return NULL; return buf; }
/** * @brief * parse_config_line - Read and parse one line of the pbs.conf file * * @param[in] fp File pointer to use for reading * @param[in/out] key Pointer to variable name pointer * @param[in/out] val Pointer to variable value pointer * * @return int * @retval !NULL Input remains * @retval NULL End of input */ static char * parse_config_line(FILE *fp, char **key, char **val) { char *start; char *end; char *split; char *ret; *key = '\0'; *val = '\0'; /* Use a do-while rather than a goto. */ do { int len; ret = pbs_fgets(&pbs_loadconf_buf, &pbs_loadconf_len, fp); if (ret == NULL) break; len = strlen(pbs_loadconf_buf); if (len < 1) break; /* Advance the start pointer past any whitespace. */ for (start = pbs_loadconf_buf; (*start != '\0') && isspace((int)*start); start++); /* Is this a comment line. */ if (*start == '#') break; /* Remove whitespace from the end. */ for (end = pbs_loadconf_buf + len - 1; (end >= start) && isspace((int)*end); end--) *end = '\0'; /* Was there nothing but white space? */ if (start >= end) break; split = strchr(start, '='); if (split == NULL) break; *key = start; *split++ = '\0'; *val = split; } while (0); return ret; }