profile.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. #pragma warn -aus
  2. //----------------------------------------------------------------------------
  3. // MS Windows Style .ini File Interface for C++
  4. // This is the first version.
  5. // Programed by xuyifeng, 1995.10, china
  6. //----------------------------------------------------------------------------
  7. // Test history:
  8. // Compiler OS TEST
  9. // ---------------------------------------------------------------
  10. // Watcom C++ 10.0a Rational System DOS4GW 100% tested
  11. // Borland C++ 3.1 DOS 100% tested
  12. // 10/4/97 - Bugfix: added fclose(is); at the end of getProfileString -lonerunnr/ags
  13. //----------------------------------------------------------------------------
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <sys/io.h>
  17. #include <string.h>
  18. #include <ctype.h>
  19. #ifdef LINUX
  20. #include <X11/Xos.h>
  21. #define _strnicmp strncasecmp
  22. #endif
  23. #include "profile.h"
  24. #define False 0
  25. #define True 1
  26. //------------------------------------------------------------------------------
  27. // titlePos: get a section title position & length in a string.
  28. //------------------------------------------------------------------------------
  29. static char *titlePos( char *buf, int *len )
  30. {
  31. char *p = buf, *q;
  32. while( *p && isspace(*p) ) p++;
  33. if( *p != '[' )
  34. return 0;
  35. q = p+1;
  36. while( *q && *q != ']' ) q++;
  37. if( *q != ']' )
  38. return 0;
  39. if( len )
  40. *len = (int)(q - p - 1);
  41. return p+1;
  42. }
  43. //------------------------------------------------------------------------------
  44. // isTitleLine: check if a string is a section title line
  45. //------------------------------------------------------------------------------
  46. static int isTitleLine( char *bufPtr )
  47. {
  48. return titlePos( bufPtr, 0 ) != 0;
  49. }
  50. //------------------------------------------------------------------------------
  51. // containTitle: check if a string contain a section a title
  52. //------------------------------------------------------------------------------
  53. static int containTitle( char *buf, const char *section )
  54. {
  55. int len = 0;
  56. char *p = titlePos(buf, &len);
  57. if (p)
  58. {
  59. if( strlen( section ) == len && _strnicmp( section, p, len ) == 0 )
  60. return True;
  61. }
  62. return False;
  63. }
  64. //------------------------------------------------------------------------------
  65. // gotoSection: move file position to start line of a section
  66. //------------------------------------------------------------------------------
  67. static int gotoSection( FILE *is, const char *section )
  68. {
  69. char line[256] = {0};
  70. while( fgets(line, 256, is) != NULL)
  71. if( containTitle( line, section ) )
  72. return True;
  73. return False;
  74. }
  75. //------------------------------------------------------------------------------
  76. // textPos: get content's position of a entry
  77. //------------------------------------------------------------------------------
  78. static char *textPos( char *buf, const char *entry )
  79. {
  80. if( buf[0] == ';' ) // it is comment line
  81. return 0;
  82. char *p = strchr( buf, '=' );
  83. if (!p)
  84. return 0;
  85. int len = (int)(p - buf);
  86. if( strlen(entry) == len && _strnicmp( buf, entry, len ) == 0 )
  87. return p+1;
  88. return 0;
  89. }
  90. //------------------------------------------------------------------------------
  91. // stripQuotationChar: strip a pair of quotation chars in a string
  92. //------------------------------------------------------------------------------
  93. static void stripQuotationChar( char *buf )
  94. {
  95. char *p = buf;
  96. while( *p && isspace(*p) ) p++;
  97. if( !(*p == '\"' || *p == '\'') )
  98. return;
  99. char *q = p+strlen(p);
  100. while( *q != *p && q > p ) q--;
  101. if( q == p )
  102. return;
  103. int len = (int)(q - p - 1);
  104. memmove( buf, p+1, len );
  105. buf[len] = 0;
  106. }
  107. //------------------------------------------------------------------------------
  108. // readEntry: read content of entry
  109. //------------------------------------------------------------------------------
  110. static int readEntry( FILE *is, const char *entry, char *buf, int bufSize,
  111. int strip )
  112. {
  113. char lineBuf[256] = {0};
  114. char *cur = buf;
  115. *cur = '\0';
  116. int len = -1;
  117. while( fgets(lineBuf, 256, is) != NULL)
  118. {
  119. if (lineBuf[strlen(lineBuf)-1] == '\n')
  120. lineBuf[strlen(lineBuf)-1] = 0;
  121. if( isTitleLine( lineBuf ) ) // section is ended
  122. break;
  123. char *p = textPos( lineBuf, entry ); // not equal this entry
  124. if( p == 0 )
  125. continue;
  126. if( strip )
  127. stripQuotationChar( p );
  128. len = strlen(p);
  129. if( bufSize-1 < len )
  130. len = bufSize-1;
  131. strncpy( cur, p, len );
  132. cur[len] = 0;
  133. break;
  134. }
  135. return len;
  136. }
  137. //------------------------------------------------------------------------------
  138. // getProfileString:
  139. //------------------------------------------------------------------------------
  140. int GetPrivateProfileString( const char *section,
  141. const char *entry,
  142. const char *defaultString,
  143. char *buffer,
  144. int bufLen,
  145. const char *fileName )
  146. {
  147. FILE *is;
  148. int len = -1;
  149. is = fopen(fileName, "rt");
  150. if( is && gotoSection( is, section ) )
  151. len = readEntry(is, entry, buffer, bufLen, True);
  152. if (len < 0) //can not read entry, use default string
  153. {
  154. strncpy( buffer, defaultString, bufLen-1 );
  155. buffer[bufLen-1] = 0;
  156. len = strlen(buffer);
  157. }
  158. if (is) fclose(is);
  159. return len;
  160. }
  161. //----------------------------------------------------------------------------
  162. // getProfileInt:
  163. //----------------------------------------------------------------------------
  164. long GetPrivateProfileInt( const char *section,
  165. const char *entry,
  166. long defaultInt,
  167. const char *fileName )
  168. {
  169. char buf[256];
  170. char iBuf[34]; //"34" is max space "_itoa" required under 32 bit C++
  171. sprintf(iBuf, "%d", defaultInt);
  172. GetPrivateProfileString( section, entry, iBuf, buf, 256, fileName );
  173. return atol( buf );
  174. }
  175. static void writeEntry( FILE *os, const char *entry, const char *string )
  176. {
  177. fprintf(os, "%s=%s\n", entry, string);
  178. }
  179. //------------------------------------------------------------------------------
  180. // writeProfileString:
  181. //------------------------------------------------------------------------------
  182. int WritePrivateProfileString( const char *section,
  183. const char *entry,
  184. const char *string,
  185. const char *fileName )
  186. {
  187. char path [8192] = {0};
  188. char drive[256] = {0};
  189. char dir [256] = {0};
  190. char file [256] = {0};
  191. char ext [256] = {0};
  192. char buf [256] = {0};
  193. int titleFound;
  194. // work better on network!
  195. _splitpath( path, drive, dir, file, ext );
  196. _makepath( path, drive, dir, mkstemp("iniXXXXXX"), "" );
  197. FILE *is = fopen(fileName, "rt");
  198. FILE *os = fopen(path, "wt");
  199. if(!is || !os || entry == 0) // maybe can not create file or invalid entry
  200. {
  201. if (is) fclose(is);
  202. if (os) fclose(os);
  203. return 0;
  204. }
  205. titleFound = False;
  206. if (is)
  207. {
  208. while (fgets(buf, 256, is) != NULL)
  209. {
  210. fputs(buf, os);
  211. if( containTitle(buf, section) )
  212. {
  213. titleFound = True;
  214. break;
  215. }
  216. }
  217. }
  218. if (!titleFound) // add section
  219. {
  220. fprintf(os, "[%s]\n", section);
  221. writeEntry( os, entry, string );
  222. }
  223. else
  224. {
  225. while (fgets(buf, 256, is) != NULL)
  226. {
  227. if (isTitleLine(buf)) // section ended, but still not found the entry
  228. break;
  229. if (textPos(buf, entry)) // entry found, so rewrite it
  230. {
  231. break;
  232. }
  233. fputs(buf, os);
  234. }
  235. writeEntry(os, entry, string);
  236. if (is)
  237. {
  238. while(fgets(buf, 256, is) != NULL) // copy left lines
  239. fputs(buf, os);
  240. }
  241. }
  242. if (is) fclose(is);
  243. if (os) fclose(os);
  244. unlink(fileName);
  245. rename(path, fileName);
  246. return strlen(string);
  247. }
  248. #pragma warn .aus