config.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /*====================================================================*
  2. *
  3. * Copyright (c) 2013 Qualcomm Atheros, Inc.
  4. *
  5. * All rights reserved.
  6. *
  7. *====================================================================*/
  8. /*====================================================================*
  9. *
  10. * config.c - configuration file reader;
  11. *
  12. * configuration files contain named parts where each part may
  13. * contain one of more named items that have text definitions;
  14. *
  15. * the named file can be searched for the first occurance of a
  16. * named part then the first occurance of a named item;
  17. *
  18. * [part1]
  19. * item1=string
  20. * item2=string
  21. *
  22. * [part2]
  23. * item1=string
  24. * item2=string
  25. *
  26. *--------------------------------------------------------------------*/
  27. #ifndef CONFIG_SOURCE
  28. #define CONFIG_SOURCE
  29. /*====================================================================*
  30. * system header files;
  31. *--------------------------------------------------------------------*/
  32. #include <stdio.h>
  33. #include <ctype.h>
  34. #include <unistd.h>
  35. #include <string.h>
  36. /*====================================================================*
  37. * custom header files;
  38. *--------------------------------------------------------------------*/
  39. #include "../tools/config.h"
  40. #include "../tools/types.h"
  41. #include "../tools/chars.h"
  42. /*====================================================================*
  43. * program variables;
  44. *--------------------------------------------------------------------*/
  45. static signed c;
  46. /*====================================================================*
  47. *
  48. * bool _compare (FILE * fp, char const *sp);
  49. *
  50. * compare file and text characters until they differ or until end
  51. * of text, line or file occurs; a match is declared when the text
  52. * ends before the line or file;
  53. *
  54. * spaces and tabs within the argument string or file string are
  55. * ignored such that "item1", " item1 " and "item 1" all match;
  56. *
  57. *--------------------------------------------------------------------*/
  58. static bool _compare (FILE * fp, char const * sp)
  59. {
  60. while (isblank ((unsigned char)* sp))
  61. {
  62. sp++;
  63. }
  64. while ((* sp) && nobreak (c))
  65. {
  66. if (toupper (c) != toupper ((unsigned char)* sp))
  67. {
  68. return (0);
  69. }
  70. do
  71. {
  72. sp++;
  73. }
  74. while (isblank ((unsigned char)* sp));
  75. do
  76. {
  77. c = getc (fp);
  78. }
  79. while (isblank (c));
  80. }
  81. return (! * sp);
  82. }
  83. /*====================================================================*
  84. *
  85. * void _collect (FILE * fp, char buffer [], size_t length);
  86. *
  87. * collect text to end of line; remove leading and trailing space
  88. * but preserve embedded space; replace selected escape sequences;
  89. *
  90. *--------------------------------------------------------------------*/
  91. static void _collect (FILE * fp, char buffer [], size_t length)
  92. {
  93. char * string = buffer;
  94. while ((c != ';') && nobreak (c))
  95. {
  96. if (c == '\\')
  97. {
  98. c = getc (fp);
  99. if (c == 'n')
  100. {
  101. c = '\n';
  102. }
  103. if (c == 'r')
  104. {
  105. c = '\r';
  106. }
  107. if (c == 't')
  108. {
  109. c = '\t';
  110. }
  111. }
  112. if (length > 1)
  113. {
  114. * buffer++ = c;
  115. length--;
  116. }
  117. if (! isblank (c))
  118. {
  119. string = buffer;
  120. }
  121. c = getc (fp);
  122. }
  123. * string = '\0';
  124. return;
  125. }
  126. /*====================================================================*
  127. *
  128. * void _discard (FILE * fp);
  129. *
  130. * read and discard characters until end-of-line or end-of-file
  131. * is detected; read the first character of next line if end of
  132. * file has not been detected;
  133. *
  134. *--------------------------------------------------------------------*/
  135. static void _discard (FILE * fp)
  136. {
  137. while (nobreak (c))
  138. {
  139. c = getc (fp);
  140. }
  141. if (c != EOF)
  142. {
  143. c = getc (fp);
  144. }
  145. return;
  146. }
  147. /*====================================================================*
  148. *
  149. * const char * configstring (char const * file, char const * part, char const * item, char const * string)
  150. *
  151. * open the named file, locate the named part and return the named
  152. * item as a text string, if present; return an alternative string
  153. * if the file, part or item is missing; the calling function must
  154. * preserve the returned strings because they are overwritten with
  155. * each call;
  156. *
  157. *--------------------------------------------------------------------*/
  158. char const * configstring (char const * file, char const * part, char const * item, char const * string)
  159. {
  160. FILE * fp;
  161. static char buffer [1024];
  162. if ((! file) || (! part) || (! item))
  163. {
  164. return (string);
  165. }
  166. if ((fp = fopen (file, "rb")))
  167. {
  168. for (c = getc (fp); c != EOF; _discard (fp))
  169. {
  170. while (isblank (c))
  171. {
  172. c = getc (fp);
  173. }
  174. if (c != '[')
  175. {
  176. continue;
  177. }
  178. do
  179. {
  180. c = getc (fp);
  181. }
  182. while (isblank (c));
  183. if (! _compare (fp, part))
  184. {
  185. continue;
  186. }
  187. if (c != ']')
  188. {
  189. continue;
  190. }
  191. for (_discard (fp); (c != '[') && (c != EOF); _discard (fp))
  192. {
  193. while (isblank (c))
  194. {
  195. c = getc (fp);
  196. }
  197. if (c == ';')
  198. {
  199. continue;
  200. }
  201. if (! _compare (fp, item))
  202. {
  203. continue;
  204. }
  205. if (c != '=')
  206. {
  207. continue;
  208. }
  209. do
  210. {
  211. c = getc (fp);
  212. }
  213. while (isblank (c));
  214. _collect (fp, buffer, sizeof (buffer));
  215. string = buffer;
  216. break;
  217. }
  218. break;
  219. }
  220. fclose (fp);
  221. }
  222. #if 0
  223. fprintf (stderr, "[%s][%s][%s]='%s'\n", file, part, item, string);
  224. #endif
  225. return (string);
  226. }
  227. /*====================================================================*
  228. *
  229. * unsigned confignumber (char const * file, char const * part, char const * item, unsigned number)
  230. *
  231. * open the named file, locate the named part and return the named
  232. * item as an unsigned integer, if present; return a default number
  233. * if the file, part or item is missing;
  234. *
  235. *--------------------------------------------------------------------*/
  236. unsigned confignumber (char const * file, char const * part, char const * item, unsigned number)
  237. {
  238. unsigned value = 0;
  239. char const * string = configstring (file, part, item, "");
  240. if ((string) && (* string))
  241. {
  242. while (isdigit ((unsigned char)* string))
  243. {
  244. value *= 10;
  245. value += * string++ - '0';
  246. }
  247. if (! (* string))
  248. {
  249. number = value;
  250. }
  251. }
  252. return (number);
  253. }
  254. /*====================================================================*
  255. *
  256. * int main (int argc, char const * argv []);
  257. *
  258. * demo/test program; arguments are file, part, item and text in
  259. * that order; you can construct your own configuration file and
  260. * observe behaviour;
  261. *
  262. *--------------------------------------------------------------------*/
  263. #if 0
  264. #include <stdio.h>
  265. int main (int argc, char const * argv [])
  266. {
  267. char const * string = configstring (argv [1], argv [2], argv [3], argv [4]);
  268. printf ("file=[%s] part=[%s] item=[%s] text=[%s]\n", argv [1], argv [2], argv [3], string);
  269. return (0);
  270. }
  271. #endif
  272. /*====================================================================*
  273. *
  274. *--------------------------------------------------------------------*/
  275. #endif