| 30 | |
| 31 | static std::string delimiter= ";"; |
| 32 | extern "C" int read_bootstrap_query(char *query, int *query_length, |
| 33 | fgets_input_t input, fgets_fn_t fgets_fn, |
| 34 | int preserve_delimiter, int *error) |
| 35 | { |
| 36 | char *line_buffer; |
| 37 | const char *line; |
| 38 | size_t len; |
| 39 | size_t query_len= 0; |
| 40 | int fgets_error= 0; |
| 41 | int exit_code= 0; |
| 42 | *error= 0; |
| 43 | |
| 44 | line_buffer= (char*) malloc(MAX_BOOTSTRAP_LINE_SIZE); |
| 45 | |
| 46 | *query_length= 0; |
| 47 | for ( ; ; ) |
| 48 | { |
| 49 | line= (*fgets_fn)(line_buffer, MAX_BOOTSTRAP_LINE_SIZE, input, &fgets_error); |
| 50 | |
| 51 | if (error) |
| 52 | *error= fgets_error; |
| 53 | |
| 54 | if (fgets_error != 0) |
| 55 | { |
| 56 | exit_code= READ_BOOTSTRAP_ERROR; |
| 57 | break; |
| 58 | } |
| 59 | |
| 60 | if (line == NULL) |
| 61 | { |
| 62 | exit_code= (query_len == 0) ? READ_BOOTSTRAP_EOF : READ_BOOTSTRAP_ERROR; |
| 63 | break; |
| 64 | } |
| 65 | |
| 66 | len= strlen(line); |
| 67 | |
| 68 | /* |
| 69 | Remove trailing whitespace characters. |
| 70 | This assumes: |
| 71 | - no multibyte encoded character can be found at the very end of a line, |
| 72 | - whitespace characters from the "C" locale only. |
| 73 | which is sufficient for the kind of queries found |
| 74 | in the bootstrap scripts. |
| 75 | */ |
| 76 | while (len && (isspace(line[len - 1]))) |
| 77 | len--; |
| 78 | /* |
| 79 | Cleanly end the string, so we don't have to test len > x |
| 80 | all the time before reading line[x], in the code below. |
| 81 | */ |
| 82 | line_buffer[len]= '\0'; |
| 83 | |
| 84 | /* Skip blank lines */ |
| 85 | if (len == 0) |
| 86 | continue; |
| 87 | |
| 88 | /* Skip # comments */ |
| 89 | if (line[0] == '#') |