#pragma warn -aus //---------------------------------------------------------------------------- // MS Windows Style .ini File Interface for C++ // This is the first version. // Programed by xuyifeng, 1995.10, china //---------------------------------------------------------------------------- // Test history: // Compiler OS TEST // --------------------------------------------------------------- // Watcom C++ 10.0a Rational System DOS4GW 100% tested // Borland C++ 3.1 DOS 100% tested // 10/4/97 - Bugfix: added fclose(is); at the end of getProfileString -lonerunnr/ags //---------------------------------------------------------------------------- #include #include #include #include #include #ifdef LINUX #include #define _strnicmp strncasecmp #endif #include "profile.h" #define False 0 #define True 1 //------------------------------------------------------------------------------ // titlePos: get a section title position & length in a string. //------------------------------------------------------------------------------ static char *titlePos( char *buf, int *len ) { char *p = buf, *q; while( *p && isspace(*p) ) p++; if( *p != '[' ) return 0; q = p+1; while( *q && *q != ']' ) q++; if( *q != ']' ) return 0; if( len ) *len = (int)(q - p - 1); return p+1; } //------------------------------------------------------------------------------ // isTitleLine: check if a string is a section title line //------------------------------------------------------------------------------ static int isTitleLine( char *bufPtr ) { return titlePos( bufPtr, 0 ) != 0; } //------------------------------------------------------------------------------ // containTitle: check if a string contain a section a title //------------------------------------------------------------------------------ static int containTitle( char *buf, const char *section ) { int len = 0; char *p = titlePos(buf, &len); if (p) { if( strlen( section ) == len && _strnicmp( section, p, len ) == 0 ) return True; } return False; } //------------------------------------------------------------------------------ // gotoSection: move file position to start line of a section //------------------------------------------------------------------------------ static int gotoSection( FILE *is, const char *section ) { char line[256] = {0}; while( fgets(line, 256, is) != NULL) if( containTitle( line, section ) ) return True; return False; } //------------------------------------------------------------------------------ // textPos: get content's position of a entry //------------------------------------------------------------------------------ static char *textPos( char *buf, const char *entry ) { if( buf[0] == ';' ) // it is comment line return 0; char *p = strchr( buf, '=' ); if (!p) return 0; int len = (int)(p - buf); if( strlen(entry) == len && _strnicmp( buf, entry, len ) == 0 ) return p+1; return 0; } //------------------------------------------------------------------------------ // stripQuotationChar: strip a pair of quotation chars in a string //------------------------------------------------------------------------------ static void stripQuotationChar( char *buf ) { char *p = buf; while( *p && isspace(*p) ) p++; if( !(*p == '\"' || *p == '\'') ) return; char *q = p+strlen(p); while( *q != *p && q > p ) q--; if( q == p ) return; int len = (int)(q - p - 1); memmove( buf, p+1, len ); buf[len] = 0; } //------------------------------------------------------------------------------ // readEntry: read content of entry //------------------------------------------------------------------------------ static int readEntry( FILE *is, const char *entry, char *buf, int bufSize, int strip ) { char lineBuf[256] = {0}; char *cur = buf; *cur = '\0'; int len = -1; while( fgets(lineBuf, 256, is) != NULL) { if (lineBuf[strlen(lineBuf)-1] == '\n') lineBuf[strlen(lineBuf)-1] = 0; if( isTitleLine( lineBuf ) ) // section is ended break; char *p = textPos( lineBuf, entry ); // not equal this entry if( p == 0 ) continue; if( strip ) stripQuotationChar( p ); len = strlen(p); if( bufSize-1 < len ) len = bufSize-1; strncpy( cur, p, len ); cur[len] = 0; break; } return len; } //------------------------------------------------------------------------------ // getProfileString: //------------------------------------------------------------------------------ int GetPrivateProfileString( const char *section, const char *entry, const char *defaultString, char *buffer, int bufLen, const char *fileName ) { FILE *is; int len = -1; is = fopen(fileName, "rt"); if( is && gotoSection( is, section ) ) len = readEntry(is, entry, buffer, bufLen, True); if (len < 0) //can not read entry, use default string { strncpy( buffer, defaultString, bufLen-1 ); buffer[bufLen-1] = 0; len = strlen(buffer); } if (is) fclose(is); return len; } //---------------------------------------------------------------------------- // getProfileInt: //---------------------------------------------------------------------------- long GetPrivateProfileInt( const char *section, const char *entry, long defaultInt, const char *fileName ) { char buf[256]; char iBuf[34]; //"34" is max space "_itoa" required under 32 bit C++ sprintf(iBuf, "%d", defaultInt); GetPrivateProfileString( section, entry, iBuf, buf, 256, fileName ); return atol( buf ); } static void writeEntry( FILE *os, const char *entry, const char *string ) { fprintf(os, "%s=%s\n", entry, string); } //------------------------------------------------------------------------------ // writeProfileString: //------------------------------------------------------------------------------ int WritePrivateProfileString( const char *section, const char *entry, const char *string, const char *fileName ) { char path [8192] = {0}; char drive[256] = {0}; char dir [256] = {0}; char file [256] = {0}; char ext [256] = {0}; char buf [256] = {0}; int titleFound; // work better on network! _splitpath( path, drive, dir, file, ext ); _makepath( path, drive, dir, mkstemp("iniXXXXXX"), "" ); FILE *is = fopen(fileName, "rt"); FILE *os = fopen(path, "wt"); if(!is || !os || entry == 0) // maybe can not create file or invalid entry { if (is) fclose(is); if (os) fclose(os); return 0; } titleFound = False; if (is) { while (fgets(buf, 256, is) != NULL) { fputs(buf, os); if( containTitle(buf, section) ) { titleFound = True; break; } } } if (!titleFound) // add section { fprintf(os, "[%s]\n", section); writeEntry( os, entry, string ); } else { while (fgets(buf, 256, is) != NULL) { if (isTitleLine(buf)) // section ended, but still not found the entry break; if (textPos(buf, entry)) // entry found, so rewrite it { break; } fputs(buf, os); } writeEntry(os, entry, string); if (is) { while(fgets(buf, 256, is) != NULL) // copy left lines fputs(buf, os); } } if (is) fclose(is); if (os) fclose(os); unlink(fileName); rename(path, fileName); return strlen(string); } #pragma warn .aus