home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_11_08 / hellquis / profiles.cpp next >
C/C++ Source or Header  |  1993-03-01  |  10KB  |  417 lines

  1. //-- profiles.cpp  -- implements the private profile string
  2. //                    routines from windows 3.0
  3. //      930301   (c) 1993, Gunnar Hellquist, Stockholm
  4.  
  5. #include "profiles.h"
  6. #include <ctype.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <stdio.h>
  10.  
  11. #ifdef SEARCHPATH
  12. #include <dir.h>
  13. #endif
  14.  
  15. // forward declarations of local routines
  16. int GetKey(FILE *inf,char * Line,LPSTR lpKeyName,
  17.        LPSTR lpReturnedString, int nSize);
  18. int GetAllKeys(FILE *inf,char *Line,
  19.        LPSTR lpReturnedString, int nSize);
  20. int    CmpApp(char * Line, LPSTR lpAppName);
  21. char * CmpKey(char * Line, LPSTR lpKeyName);
  22. void   PutApp(LPSTR lpApplicationName, FILE *outf);
  23. void   PutKey(LPSTR lpKeyName,LPSTR lpString, FILE *outf);
  24. //------------------------------------------------------------
  25. //  GetPrivateProfileString
  26. //
  27. //  Implements a version of the Windows 3.0 routine to fetch
  28. //  profile strings from a file. In windows they are normally
  29. //  named .ini.
  30. //
  31. //  The function searches the file for a key found under the
  32. //  matching application heading. If found, the string is copied
  33. //  else the default is returned.
  34. //
  35. //  If lpKeyName is NULL, the routine instead returns all the
  36. //  keynames found under the application heading. The keynames
  37. //  are separated by a NUL character. List is terminated by
  38. //  double NUL character
  39. //
  40. //  Returns number of characters copied to lpReturnedString, not
  41. //  including terminating NUL character.
  42. //
  43. //  Text in file has to be left aligned:
  44. //
  45. //          [Application]
  46. //          ;   comment
  47. //          key=value
  48. //          key=value
  49. //             ....     (aso)
  50. //
  51.  
  52. int GetPrivateProfileString( LPSTR lpApplicationName,
  53.         LPSTR lpKeyName, LPSTR lpDefault,
  54.         LPSTR lpReturnedString, int nSize,
  55.         LPSTR lpFileName)
  56. {
  57.     int nChars = 0 ;
  58.     char Line[MAXLINELEN] ;
  59.     FILE *inf ;
  60.     int toCopy ;
  61. #ifdef SEARCHPATH
  62.     lpFileName = searchpath(lpFileName);
  63. #endif
  64.     inf = fopen (lpFileName,"r");      // open the file
  65.  
  66.     if (inf)
  67.     {
  68.         while (fgets(Line,MAXLINELEN,inf))
  69.         {
  70.             if (CmpApp(Line,lpApplicationName))
  71.             {
  72.                if (lpKeyName)
  73.                 nChars = GetKey(inf, Line, lpKeyName,
  74.                 lpReturnedString, nSize);
  75.                else
  76.                 nChars = GetAllKeys(inf,Line,
  77.                     lpReturnedString, nSize);
  78.                break ;
  79.             }
  80.         }
  81.     }
  82.  
  83.     //-- if key string not found, return default
  84.     if (!nChars)
  85.     {
  86.         if  ( (lpDefault) && (lpKeyName))
  87.         {
  88.             toCopy = nChars = strlen(lpDefault);
  89.             if (nChars >= nSize)
  90.             {
  91.                 toCopy = nSize-1 ;
  92.                 nChars = nSize;
  93.             }
  94.             memcpy (lpReturnedString,lpDefault,toCopy);
  95.             lpReturnedString[toCopy] = '\0';
  96.         }
  97.         else
  98.         {
  99.             lpReturnedString[0] ='\0';
  100.             lpReturnedString[1] ='\0';
  101.         }
  102.     }
  103.     fclose (inf) ;
  104.     return nChars ;
  105. }
  106. //----------------------------------------------------------------
  107. //  CmpApp
  108. //         Local routine to check if line contains application
  109. //         name. Returns TRUE (=1) if found.
  110. int CmpApp(char * Line, LPSTR lpAppName)
  111. {
  112.     char  *i = Line;
  113.     LPSTR n = lpAppName;
  114.     int   OK = 0 ;
  115.  
  116.     if (*i++ == '[')
  117.     for (;;)
  118.     {
  119.         if ((!*n) && (*i==']'))
  120.         {
  121.             OK = 1 ;
  122.             break ;
  123.         }
  124.         if (!*n) break ;
  125.         if (!*i) break ;
  126.         if (toupper(*i) != toupper(*n) ) break ;
  127.         i++, n++;
  128.     }
  129.     return OK ;
  130. }
  131. //----------------------------------------------------------------
  132. //  CmpKey
  133. //       Local routine to find key name on line. If found, position
  134. //       in string of the string value is returned.
  135. char *CmpKey(char * Line, LPSTR lpKeyName)
  136. {
  137.     char  *i = Line ;
  138.     LPSTR n = lpKeyName;
  139.     char  * outpos = 0 ;
  140.  
  141.     for (;;)
  142.     {
  143.         if ((!*n) && (*i == '='))
  144.         {
  145.             outpos = i ;
  146.             outpos++;
  147.             break ;
  148.         }
  149.         if (!*i) break ;
  150.         if (!*n) break ;
  151.         if (toupper(*i) != toupper(*n)) break ;
  152.         *n++, *i++ ;
  153.     }
  154.  
  155.     return outpos ;
  156. }
  157. //----------------------------------------------------------------
  158. // GetKey
  159. //     Local routine to get key value from profile file.
  160. //     Returns number of characters copied to
  161. int GetKey(FILE *inf,char * Line,LPSTR lpKeyName,
  162.        LPSTR lpReturnedString, int nSize)
  163. {
  164.     char * c;
  165.     int nChars = 0 ;
  166.     while (fgets(Line,MAXLINELEN,inf))
  167.     {
  168.         if (Line[0] == '[' )       // next app
  169.             break ;
  170.         c=CmpKey(Line,lpKeyName);
  171.         if (c)
  172.         {
  173.             while ((nChars < (nSize-1))
  174.                     && *c && (*c != '\n'))
  175.             {
  176.                 *lpReturnedString = *c ;
  177.                 lpReturnedString++,c++;
  178.                 nChars++;
  179.             }
  180.             *lpReturnedString = '\0';
  181.             if (*c)
  182.                 nChars = nSize ;   // mark overflow
  183.             break ;
  184.         }
  185.     }
  186.     return nChars ;
  187. }
  188. //----------------------------------------------------------------
  189. // GetAllKeys
  190. //     Local routine to get all the key names from profile file
  191. //     Returns number of characters copied to lpReturnedString
  192. //     On overflow, the value returned is nSize - 2;
  193. int GetAllKeys(FILE *inf,char *Line,
  194.        LPSTR lpReturnedString, int nSize)
  195. {
  196.     int nChars = 0 ;
  197.     char *c;
  198.     char *i;
  199.     while (fgets(Line,MAXLINELEN,inf))
  200.     {
  201.         if (nChars >= (nSize-2))
  202.         {
  203.             nChars = nSize -2 ;
  204.             *lpReturnedString = '\0';
  205.             lpReturnedString++;
  206.             break;
  207.         }
  208.  
  209.         c = strchr (Line,'=');
  210.         i = Line ;
  211.         if (c)
  212.         {
  213.             while(i < c)
  214.             {
  215.                 if (nChars<(nSize-2))
  216.                 {
  217.                     nChars++ ;
  218.                     *lpReturnedString = *i ;
  219.                     *lpReturnedString++;
  220.                 }
  221.                 i++;
  222.             }
  223.             *lpReturnedString = '\0';
  224.             nChars++;
  225.         }
  226.         *lpReturnedString = '\0';
  227.         lpReturnedString++;
  228.         nChars ++ ;
  229.     }
  230.     *lpReturnedString = '\0';
  231.     return nChars ;
  232. }
  233. //---------------------------------------------------------------
  234. //  PutApp
  235. //        local routine to write out application line
  236. void   PutApp(LPSTR lpApplicationName, FILE *outf)
  237. {
  238.     fputc('[',outf);
  239.     fputs(lpApplicationName,outf);
  240.     fputs("]\n",outf);
  241. }
  242. //---------------------------------------------------------------
  243. //  PutKey
  244. //        local routine to write out key line
  245.  
  246. void   PutKey(LPSTR lpKeyName,LPSTR lpString, FILE *outf)
  247. {
  248.     fputs(lpKeyName,outf);
  249.     fputc('=',outf);
  250.     fputs(lpString,outf);
  251.     fputc('\n',outf);
  252. }
  253. //--------------------------------------------------------------
  254. //  GetPrivateProfileInt
  255. //
  256. //  A routine from Windows 3.0 API which reads an integer from
  257. //  the application init file, often .ini extension.
  258. //
  259. //  The file is searched for the application heading and the
  260. //  integer value of the key is returned. The file has the
  261. //  following layout:
  262. //
  263. //    [Application]
  264. //      key name=key value
  265. //        ... aso
  266. //
  267. //  Returns:
  268. //         zero if key value is not an intger or, negative
  269. //         actual value if possible to interpret as integer.
  270. //                Note that only the beginning of key value
  271. //                is interpreted, ie key=345abc returns 345
  272. //         nDefault if key or application is not found
  273. //
  274. WORD GetPrivateProfileInt  (LPSTR lpApplicationName,
  275.         LPSTR lpKeyName, int nDefault,
  276.         LPSTR lpFileName)
  277. {
  278.     char txt[MAXINTLEN] ;
  279.     WORD nValue = nDefault ;
  280.     long val ;
  281.     int nChars ;
  282.  
  283.     nChars = GetPrivateProfileString(lpApplicationName,
  284.            lpKeyName,NULL,txt,sizeof(txt),lpFileName);
  285.     if (nChars)
  286.     {
  287.         val = atol(txt);
  288.         if ((val<0) || (val > MAXWORD ))
  289.             nValue = 0 ;
  290.         else
  291.             nValue = (WORD) val ;
  292.     }
  293.     return nValue ;
  294. }
  295. //------------------------------------------------------------
  296. //  WritePrivateProfileString
  297. //
  298. //  Implements a version of the Windows 3.0 routine to write
  299. //  profile strings to a file. In windows they are normally
  300. //  named with the extension .ini.
  301. //
  302. //  The routine searches the file named by lpFileName for an
  303. //  application heading given by lpApplicationName and a key
  304. //  name given by lpKeyName. If found the value is changed to
  305. //  lpString, otherwise it will be added.
  306. //
  307. //  First special case is when lpString is NULL. Then the
  308. //  corresponding line identified by lpKeyName is deleted.
  309. //  Second special case is when both lpString and lpKeyName
  310. //  are NULL. In that case the whole section under
  311. //  lpApplicationName is deleted. Lines beginning with ';'
  312. //  are however kept since they are considered comments.
  313. //
  314. BOOL WritePrivateProfileString ( LPSTR lpApplicationName,
  315.         LPSTR lpKeyName, LPSTR lpString,
  316.         LPSTR lpFileName)
  317. {
  318.     BOOL ok = 0 ;
  319. #ifdef SEARCHPATH
  320.     char *fname = searchpath(lpFileName);
  321.     if (!fname)
  322.         fname = lpFileName ;
  323. #endif
  324.     FILE *inf= fopen(fname,"r");      // open the existing file
  325.     FILE *outf ;
  326.     char *tmp= tmpnam(NULL);
  327.     char line[MAXLINELEN] ;
  328.  
  329.     if (inf)
  330.     {
  331.         outf = fopen(tmp,"w");
  332.         if (outf)
  333.         {
  334.             while(fgets(line,MAXLINELEN,inf))
  335.             {
  336.                 if (CmpApp(line,lpApplicationName))
  337.                     break;
  338.                 fputs(line,outf);
  339.             }
  340.             if (feof(inf))
  341.             {     // write new lpApplication section
  342.                 if (lpKeyName)
  343.                 {
  344.                   PutApp(lpApplicationName,outf);
  345.                   PutKey(lpKeyName,lpString,outf);
  346.                   ok = 1 ;
  347.                 }
  348.             }
  349.             else  // have found section
  350.             {
  351.               if (!lpKeyName)
  352.               { // remove section but keep comments
  353.                 while(fgets(line,MAXLINELEN,inf))
  354.                 {  // exit if next section
  355.                   if (line[0] == '[')
  356.                      break;
  357.                   if (line[0] == ';')
  358.                      fputs(line,outf);
  359.                 }
  360.               }
  361.               else
  362.               { // change only key, or add new key
  363.                 fputs(line,outf);
  364.                   while (1)
  365.                   {
  366.                     if (! fgets(line,MAXLINELEN,inf))
  367.                       line[0] = '\0';
  368.                     if ( CmpKey(line,lpKeyName)
  369.                       || (line[0] == '[')
  370.                       || (line[0] == '\0') )
  371.  
  372.                     { // write new key line
  373.                       PutKey(lpKeyName,lpString,outf);
  374.                         if (line[0] == '[')
  375.                           fputs(line,outf);
  376.                             break ;
  377.                     }
  378.                     fputs(line,outf);
  379.                   }
  380.               }
  381.               // copy rest of file
  382.               while(fgets(line,MAXLINELEN,inf))
  383.                 fputs(line,outf);
  384.  
  385.               ok = 1 ;
  386.             }
  387.             // close files, copy tmpfile and delet
  388.             fclose(inf);
  389.             fclose(outf);
  390.             remove(fname);
  391.             inf = fopen(tmp,"r");
  392.             outf = fopen(fname,"w");
  393.             while (fgets(line, MAXLINELEN,inf))
  394.                 fputs(line,outf);
  395.             fclose(inf);
  396.             fclose(outf);
  397.             remove(tmp);
  398.         }
  399.         fclose (outf);
  400.     }
  401.     else if (lpApplicationName && lpKeyName)
  402.     {           // -- no file found, create a new
  403.         outf = fopen(fname,"w");
  404.         if (outf)
  405.         {
  406.             PutApp(lpApplicationName,outf);
  407.             PutKey(lpKeyName,lpString,outf);
  408.             ok = 1 ;
  409.         }
  410.         fclose(outf);
  411.     }
  412.     fclose (inf);
  413.     return ok;
  414. }
  415.  
  416. //-- end of profiles.cpp
  417.