home *** CD-ROM | disk | FTP | other *** search
- //-- profiles.cpp -- implements the private profile string
- // routines from windows 3.0
- // 930301 (c) 1993, Gunnar Hellquist, Stockholm
-
- #include "profiles.h"
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
-
- #ifdef SEARCHPATH
- #include <dir.h>
- #endif
-
- // forward declarations of local routines
- int GetKey(FILE *inf,char * Line,LPSTR lpKeyName,
- LPSTR lpReturnedString, int nSize);
- int GetAllKeys(FILE *inf,char *Line,
- LPSTR lpReturnedString, int nSize);
- int CmpApp(char * Line, LPSTR lpAppName);
- char * CmpKey(char * Line, LPSTR lpKeyName);
- void PutApp(LPSTR lpApplicationName, FILE *outf);
- void PutKey(LPSTR lpKeyName,LPSTR lpString, FILE *outf);
- //------------------------------------------------------------
- // GetPrivateProfileString
- //
- // Implements a version of the Windows 3.0 routine to fetch
- // profile strings from a file. In windows they are normally
- // named .ini.
- //
- // The function searches the file for a key found under the
- // matching application heading. If found, the string is copied
- // else the default is returned.
- //
- // If lpKeyName is NULL, the routine instead returns all the
- // keynames found under the application heading. The keynames
- // are separated by a NUL character. List is terminated by
- // double NUL character
- //
- // Returns number of characters copied to lpReturnedString, not
- // including terminating NUL character.
- //
- // Text in file has to be left aligned:
- //
- // [Application]
- // ; comment
- // key=value
- // key=value
- // .... (aso)
- //
-
- int GetPrivateProfileString( LPSTR lpApplicationName,
- LPSTR lpKeyName, LPSTR lpDefault,
- LPSTR lpReturnedString, int nSize,
- LPSTR lpFileName)
- {
- int nChars = 0 ;
- char Line[MAXLINELEN] ;
- FILE *inf ;
- int toCopy ;
- #ifdef SEARCHPATH
- lpFileName = searchpath(lpFileName);
- #endif
- inf = fopen (lpFileName,"r"); // open the file
-
- if (inf)
- {
- while (fgets(Line,MAXLINELEN,inf))
- {
- if (CmpApp(Line,lpApplicationName))
- {
- if (lpKeyName)
- nChars = GetKey(inf, Line, lpKeyName,
- lpReturnedString, nSize);
- else
- nChars = GetAllKeys(inf,Line,
- lpReturnedString, nSize);
- break ;
- }
- }
- }
-
- //-- if key string not found, return default
- if (!nChars)
- {
- if ( (lpDefault) && (lpKeyName))
- {
- toCopy = nChars = strlen(lpDefault);
- if (nChars >= nSize)
- {
- toCopy = nSize-1 ;
- nChars = nSize;
- }
- memcpy (lpReturnedString,lpDefault,toCopy);
- lpReturnedString[toCopy] = '\0';
- }
- else
- {
- lpReturnedString[0] ='\0';
- lpReturnedString[1] ='\0';
- }
- }
- fclose (inf) ;
- return nChars ;
- }
- //----------------------------------------------------------------
- // CmpApp
- // Local routine to check if line contains application
- // name. Returns TRUE (=1) if found.
- int CmpApp(char * Line, LPSTR lpAppName)
- {
- char *i = Line;
- LPSTR n = lpAppName;
- int OK = 0 ;
-
- if (*i++ == '[')
- for (;;)
- {
- if ((!*n) && (*i==']'))
- {
- OK = 1 ;
- break ;
- }
- if (!*n) break ;
- if (!*i) break ;
- if (toupper(*i) != toupper(*n) ) break ;
- i++, n++;
- }
- return OK ;
- }
- //----------------------------------------------------------------
- // CmpKey
- // Local routine to find key name on line. If found, position
- // in string of the string value is returned.
- char *CmpKey(char * Line, LPSTR lpKeyName)
- {
- char *i = Line ;
- LPSTR n = lpKeyName;
- char * outpos = 0 ;
-
- for (;;)
- {
- if ((!*n) && (*i == '='))
- {
- outpos = i ;
- outpos++;
- break ;
- }
- if (!*i) break ;
- if (!*n) break ;
- if (toupper(*i) != toupper(*n)) break ;
- *n++, *i++ ;
- }
-
- return outpos ;
- }
- //----------------------------------------------------------------
- // GetKey
- // Local routine to get key value from profile file.
- // Returns number of characters copied to
- int GetKey(FILE *inf,char * Line,LPSTR lpKeyName,
- LPSTR lpReturnedString, int nSize)
- {
- char * c;
- int nChars = 0 ;
- while (fgets(Line,MAXLINELEN,inf))
- {
- if (Line[0] == '[' ) // next app
- break ;
- c=CmpKey(Line,lpKeyName);
- if (c)
- {
- while ((nChars < (nSize-1))
- && *c && (*c != '\n'))
- {
- *lpReturnedString = *c ;
- lpReturnedString++,c++;
- nChars++;
- }
- *lpReturnedString = '\0';
- if (*c)
- nChars = nSize ; // mark overflow
- break ;
- }
- }
- return nChars ;
- }
- //----------------------------------------------------------------
- // GetAllKeys
- // Local routine to get all the key names from profile file
- // Returns number of characters copied to lpReturnedString
- // On overflow, the value returned is nSize - 2;
- int GetAllKeys(FILE *inf,char *Line,
- LPSTR lpReturnedString, int nSize)
- {
- int nChars = 0 ;
- char *c;
- char *i;
- while (fgets(Line,MAXLINELEN,inf))
- {
- if (nChars >= (nSize-2))
- {
- nChars = nSize -2 ;
- *lpReturnedString = '\0';
- lpReturnedString++;
- break;
- }
-
- c = strchr (Line,'=');
- i = Line ;
- if (c)
- {
- while(i < c)
- {
- if (nChars<(nSize-2))
- {
- nChars++ ;
- *lpReturnedString = *i ;
- *lpReturnedString++;
- }
- i++;
- }
- *lpReturnedString = '\0';
- nChars++;
- }
- *lpReturnedString = '\0';
- lpReturnedString++;
- nChars ++ ;
- }
- *lpReturnedString = '\0';
- return nChars ;
- }
- //---------------------------------------------------------------
- // PutApp
- // local routine to write out application line
- void PutApp(LPSTR lpApplicationName, FILE *outf)
- {
- fputc('[',outf);
- fputs(lpApplicationName,outf);
- fputs("]\n",outf);
- }
- //---------------------------------------------------------------
- // PutKey
- // local routine to write out key line
-
- void PutKey(LPSTR lpKeyName,LPSTR lpString, FILE *outf)
- {
- fputs(lpKeyName,outf);
- fputc('=',outf);
- fputs(lpString,outf);
- fputc('\n',outf);
- }
- //--------------------------------------------------------------
- // GetPrivateProfileInt
- //
- // A routine from Windows 3.0 API which reads an integer from
- // the application init file, often .ini extension.
- //
- // The file is searched for the application heading and the
- // integer value of the key is returned. The file has the
- // following layout:
- //
- // [Application]
- // key name=key value
- // ... aso
- //
- // Returns:
- // zero if key value is not an intger or, negative
- // actual value if possible to interpret as integer.
- // Note that only the beginning of key value
- // is interpreted, ie key=345abc returns 345
- // nDefault if key or application is not found
- //
- WORD GetPrivateProfileInt (LPSTR lpApplicationName,
- LPSTR lpKeyName, int nDefault,
- LPSTR lpFileName)
- {
- char txt[MAXINTLEN] ;
- WORD nValue = nDefault ;
- long val ;
- int nChars ;
-
- nChars = GetPrivateProfileString(lpApplicationName,
- lpKeyName,NULL,txt,sizeof(txt),lpFileName);
- if (nChars)
- {
- val = atol(txt);
- if ((val<0) || (val > MAXWORD ))
- nValue = 0 ;
- else
- nValue = (WORD) val ;
- }
- return nValue ;
- }
- //------------------------------------------------------------
- // WritePrivateProfileString
- //
- // Implements a version of the Windows 3.0 routine to write
- // profile strings to a file. In windows they are normally
- // named with the extension .ini.
- //
- // The routine searches the file named by lpFileName for an
- // application heading given by lpApplicationName and a key
- // name given by lpKeyName. If found the value is changed to
- // lpString, otherwise it will be added.
- //
- // First special case is when lpString is NULL. Then the
- // corresponding line identified by lpKeyName is deleted.
- // Second special case is when both lpString and lpKeyName
- // are NULL. In that case the whole section under
- // lpApplicationName is deleted. Lines beginning with ';'
- // are however kept since they are considered comments.
- //
- BOOL WritePrivateProfileString ( LPSTR lpApplicationName,
- LPSTR lpKeyName, LPSTR lpString,
- LPSTR lpFileName)
- {
- BOOL ok = 0 ;
- #ifdef SEARCHPATH
- char *fname = searchpath(lpFileName);
- if (!fname)
- fname = lpFileName ;
- #endif
- FILE *inf= fopen(fname,"r"); // open the existing file
- FILE *outf ;
- char *tmp= tmpnam(NULL);
- char line[MAXLINELEN] ;
-
- if (inf)
- {
- outf = fopen(tmp,"w");
- if (outf)
- {
- while(fgets(line,MAXLINELEN,inf))
- {
- if (CmpApp(line,lpApplicationName))
- break;
- fputs(line,outf);
- }
- if (feof(inf))
- { // write new lpApplication section
- if (lpKeyName)
- {
- PutApp(lpApplicationName,outf);
- PutKey(lpKeyName,lpString,outf);
- ok = 1 ;
- }
- }
- else // have found section
- {
- if (!lpKeyName)
- { // remove section but keep comments
- while(fgets(line,MAXLINELEN,inf))
- { // exit if next section
- if (line[0] == '[')
- break;
- if (line[0] == ';')
- fputs(line,outf);
- }
- }
- else
- { // change only key, or add new key
- fputs(line,outf);
- while (1)
- {
- if (! fgets(line,MAXLINELEN,inf))
- line[0] = '\0';
- if ( CmpKey(line,lpKeyName)
- || (line[0] == '[')
- || (line[0] == '\0') )
-
- { // write new key line
- PutKey(lpKeyName,lpString,outf);
- if (line[0] == '[')
- fputs(line,outf);
- break ;
- }
- fputs(line,outf);
- }
- }
- // copy rest of file
- while(fgets(line,MAXLINELEN,inf))
- fputs(line,outf);
-
- ok = 1 ;
- }
- // close files, copy tmpfile and delet
- fclose(inf);
- fclose(outf);
- remove(fname);
- inf = fopen(tmp,"r");
- outf = fopen(fname,"w");
- while (fgets(line, MAXLINELEN,inf))
- fputs(line,outf);
- fclose(inf);
- fclose(outf);
- remove(tmp);
- }
- fclose (outf);
- }
- else if (lpApplicationName && lpKeyName)
- { // -- no file found, create a new
- outf = fopen(fname,"w");
- if (outf)
- {
- PutApp(lpApplicationName,outf);
- PutKey(lpKeyName,lpString,outf);
- ok = 1 ;
- }
- fclose(outf);
- }
- fclose (inf);
- return ok;
- }
-
- //-- end of profiles.cpp
-