Parse the file and return line by line.
| 20 | |
| 21 | // Parse the file and return line by line. |
| 22 | int parse_ini_file(const char* f_path, ini_line_cb handler, void* data) |
| 23 | { |
| 24 | // Open the file stream. |
| 25 | FILE* h_file; |
| 26 | if (fopen_s(&h_file, f_path, "r") || !h_file) return 0; |
| 27 | |
| 28 | // Current line. |
| 29 | char* c_str_ptr = 0, * c_str_ptr_end = 0; |
| 30 | char c_line[MAX_INI_LINE]; |
| 31 | |
| 32 | // Read it in a loop for each line. |
| 33 | unsigned int line_number = 1; |
| 34 | while (fgets(c_line, sizeof(c_line), h_file)) |
| 35 | { |
| 36 | // Comment. |
| 37 | if (*c_line == ';') { |
| 38 | line_number++; |
| 39 | continue; |
| 40 | }; |
| 41 | |
| 42 | // It may be a section. |
| 43 | if (*c_line == '[' && (c_str_ptr = strchr(c_line, ']'))) |
| 44 | { |
| 45 | // New section. |
| 46 | *c_str_ptr = '\0'; |
| 47 | handler(data, line_number, c_line + 1, 0, 0); |
| 48 | } |
| 49 | else if ((c_str_ptr = strchr(c_line, '='))) |
| 50 | { |
| 51 | // It may be a name[=]value. |
| 52 | if ((c_str_ptr_end = strchr(c_str_ptr, '\n'))) { |
| 53 | *c_str_ptr_end = '\0'; |
| 54 | }; |
| 55 | |
| 56 | // Call the handler with name-value pair. |
| 57 | *c_str_ptr = '\0'; |
| 58 | handler(data, line_number, 0, c_line, c_str_ptr + 1); |
| 59 | } |
| 60 | else |
| 61 | { |
| 62 | // Close the file and return FALSE. |
| 63 | fclose(h_file); |
| 64 | return 0; |
| 65 | }; |
| 66 | |
| 67 | // Next. |
| 68 | line_number++; |
| 69 | }; |
| 70 | |
| 71 | // Close the file. |
| 72 | fclose(h_file); |
| 73 | return 1; |
| 74 | }; |
| 75 | |
| 76 | #ifdef __cplusplus |
| 77 | }; |