confreader.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /* vim: tabstop=4 shiftwidth=4 noexpandtab
  2. * This file is part of ToaruOS and is released under the terms
  3. * of the NCSA / University of Illinois License - see LICENSE.md
  4. * Copyright (C) 2018 K. Lange
  5. *
  6. * Configuration File Reader
  7. *
  8. * Reads an implementation of the INI "standard". Note that INI
  9. * isn't actually a standard. We support the following:
  10. * - ; comments
  11. * - foo=bar keyword assignment
  12. * - [sections]
  13. */
  14. #include <stdio.h>
  15. #include <toaru/hashmap.h>
  16. #include <toaru/confreader.h>
  17. #define TRACE_APP_NAME "confreader"
  18. #define TRACE(...)
  19. //#include <toaru/trace.h>
  20. static void free_hashmap(void * h) {
  21. hashmap_free(h);
  22. free(h);
  23. }
  24. confreader_t * confreader_load(const char * file) {
  25. confreader_t * out = malloc(sizeof(confreader_t));
  26. out->sections = hashmap_create(10);
  27. FILE * f = fopen(file, "r");
  28. hashmap_t * current_section = hashmap_create(10);
  29. current_section->hash_val_free = free_hashmap;
  30. hashmap_set(out->sections, "", current_section);
  31. if (!f) {
  32. /* File does not exist, no configuration values, but continue normally. */
  33. return out;
  34. }
  35. char tmp[1024];
  36. char tmp2[1024];
  37. while (!feof(f)) {
  38. char c = fgetc(f);
  39. tmp[0] = '\0';
  40. tmp2[0] = '\0';
  41. if (c == ';') {
  42. TRACE("Comment");
  43. while (!feof(f) && fgetc(f) != '\n');
  44. TRACE("Done");
  45. } else if (c == '\n' || c == EOF) {
  46. TRACE("blank line or EOF: %d", c);
  47. continue;
  48. } else if (c == '[') {
  49. TRACE("section");
  50. char * foo = tmp;
  51. int i;
  52. while ((i = fgetc(f)) >= 0) {
  53. if (i == ']') break;
  54. *foo = i;
  55. foo++;
  56. *foo = '\0';
  57. }
  58. while (!feof(f) && fgetc(f) != '\n');
  59. current_section = hashmap_create(10);
  60. TRACE("adding section %s", tmp);
  61. hashmap_set(out->sections, tmp, current_section);
  62. TRACE("section is over");
  63. } else {
  64. TRACE("value");
  65. char * foo = tmp;
  66. *foo = c;
  67. foo++;
  68. int i;
  69. while ((i = fgetc(f)) >= 0) {
  70. if (i == '=') break;
  71. *foo = i;
  72. foo++;
  73. *foo = '\0';
  74. }
  75. if (i != '=') {
  76. TRACE("no equals sign");
  77. while (!feof(f) && fgetc(f) != '\n');
  78. continue;
  79. }
  80. TRACE("=");
  81. foo = tmp2;
  82. while ((i = fgetc(f)) >= 0) {
  83. if (i == '\n') break;
  84. *foo = i;
  85. foo++;
  86. *foo = '\0';
  87. }
  88. TRACE("setting value %s to %s", tmp, tmp2);
  89. hashmap_set(current_section, tmp, strdup(tmp2));
  90. }
  91. }
  92. fclose(f);
  93. TRACE("done reading");
  94. return out;
  95. }
  96. void confreader_free(confreader_t * conf) {
  97. free_hashmap(conf->sections);
  98. free(conf);
  99. }
  100. char * confreader_get(confreader_t * ctx, char * section, char * value) {
  101. if (!ctx) return NULL;
  102. hashmap_t * s = hashmap_get(ctx->sections, section);
  103. if (!s) {
  104. TRACE("section doesn't exist: %s", section);
  105. return NULL;
  106. }
  107. return hashmap_get(s, value);
  108. }
  109. char * confreader_getd(confreader_t * ctx, char * section, char * value, char * def) {
  110. char * result = confreader_get(ctx, section, value);
  111. return result ? result : def;
  112. }
  113. int confreader_int(confreader_t * ctx, char * section, char * value) {
  114. char * result = confreader_get(ctx, section, value);
  115. if (!result) return 0;
  116. return atoi(result);
  117. }
  118. int confreader_intd(confreader_t * ctx, char * section, char * value, int def) {
  119. char * result = confreader_get(ctx, section, value);
  120. if (!result) return def;
  121. return atoi(result);
  122. }