qdf_parse.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for
  5. * any purpose with or without fee is hereby granted, provided that the
  6. * above copyright notice and this permission notice appear in all
  7. * copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  10. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  11. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  12. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  13. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  14. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  16. * PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. #include "qdf_file.h"
  19. #include "qdf_module.h"
  20. #include "qdf_parse.h"
  21. #include "qdf_status.h"
  22. #include "qdf_str.h"
  23. #include "qdf_trace.h"
  24. #include "qdf_types.h"
  25. QDF_STATUS qdf_ini_parse(const char *ini_path, void *context,
  26. qdf_ini_item_cb item_cb, qdf_ini_section_cb section_cb)
  27. {
  28. QDF_STATUS status;
  29. char *fbuf;
  30. char *cursor;
  31. int ini_read_count = 0;
  32. if (qdf_str_eq(QDF_WIFI_MODULE_PARAMS_FILE, ini_path))
  33. status = qdf_module_param_file_read(ini_path, &fbuf);
  34. else
  35. status = qdf_file_read(ini_path, &fbuf);
  36. if (QDF_IS_STATUS_ERROR(status)) {
  37. qdf_err("Failed to read *.ini file @ %s", ini_path);
  38. return status;
  39. }
  40. /* foreach line */
  41. cursor = fbuf;
  42. while (*cursor != '\0') {
  43. char *key = cursor;
  44. char *value = NULL;
  45. bool comment = false;
  46. bool eol = false;
  47. /*
  48. * Look for the end of the line, while noting any
  49. * value ('=') or comment ('#') indicators
  50. */
  51. while (!eol) {
  52. switch (*cursor) {
  53. case '\r':
  54. case '\n':
  55. *cursor = '\0';
  56. cursor++;
  57. /* fall through */
  58. case '\0':
  59. eol = true;
  60. break;
  61. case '=':
  62. /*
  63. * The first '=' is the value indicator.
  64. * Subsequent '=' are valid value characters.
  65. */
  66. if (!value && !comment) {
  67. value = cursor + 1;
  68. *cursor = '\0';
  69. }
  70. cursor++;
  71. break;
  72. case '#':
  73. /*
  74. * We don't process comments, so we can null-
  75. * terminate unconditionally here (unlike '=').
  76. */
  77. comment = true;
  78. *cursor = '\0';
  79. /* fall through */
  80. default:
  81. cursor++;
  82. break;
  83. }
  84. }
  85. key = qdf_str_trim(key);
  86. /*
  87. * Ignoring comments, a valid ini line contains one of:
  88. * 1) some 'key=value' config item
  89. * 2) section header
  90. * 3) a line containing whitespace
  91. */
  92. if (value) {
  93. status = item_cb(context, key, value);
  94. if (QDF_IS_STATUS_ERROR(status))
  95. goto free_fbuf;
  96. else
  97. ini_read_count++;
  98. } else if (key[0] == '[') {
  99. qdf_size_t len = qdf_str_len(key);
  100. if (key[len - 1] != ']') {
  101. qdf_err("Invalid *.ini syntax '%s'", key);
  102. } else {
  103. key[len - 1] = '\0';
  104. if (section_cb)
  105. status = section_cb(context, key + 1);
  106. else
  107. status = QDF_STATUS_E_NULL_VALUE;
  108. if (QDF_IS_STATUS_ERROR(status))
  109. goto free_fbuf;
  110. }
  111. } else if (key[0] != '\0') {
  112. qdf_err("Invalid *.ini syntax '%s'", key);
  113. }
  114. /* skip remaining EoL characters */
  115. while (*cursor == '\n' || *cursor == '\r')
  116. cursor++;
  117. }
  118. qdf_info("INI values read: %d", ini_read_count);
  119. if (ini_read_count != 0) {
  120. qdf_info("INI file parse successful");
  121. status = QDF_STATUS_SUCCESS;
  122. } else {
  123. qdf_info("INI file parse fail: invalid file format");
  124. status = QDF_STATUS_E_INVAL;
  125. }
  126. free_fbuf:
  127. if (qdf_str_eq(QDF_WIFI_MODULE_PARAMS_FILE, ini_path))
  128. qdf_module_param_file_free(fbuf);
  129. else
  130. qdf_file_buf_free(fbuf);
  131. return status;
  132. }
  133. qdf_export_symbol(qdf_ini_parse);