Menu

#2 proposal 1.1.10

open
nobody
None
5
2005-01-04
2004-08-18
Karel
No

Hello,

I used your libini. It was a great help.
I feel free to give you the update I did in order that I
could use it.
I hope you can make some time to eventually release it
on this site.

Note: around this c lib I created a wrapper class; just
tell me if you are interessed then I send you that source
as well.

ChangeLog:

Fixed:

Modified:

*libini.so is renamed to libgccini.so so -l option should be
changed to -lgccini
*Ini parser is case insensitive for headings and keys
- changed files:
- heading.i: __ini_locateHeading (ini_t *ini, const
char *heading)
- key.i: __ini_locateKey (ini_t *ini, const char
*key)
- ini.cpp: __ini_createCrc32 (const char *pBuf,
size_t length)
*ini_store starts writing with a space ' ' see also bugs
*ini_readInt returns zero only if succesful conversion is
done.
*ini_readDouble returns zero only if succesful conversion
is done.
*ini_readLong returns zero only if succesful conversion is
done.
*ini_readBool true has now synoniem yes, on; false has
no, off
*libini.spec.in: make it compactible with red hat 5.2 rpm
2.5.5

Added:

*support for exploring an ini file by indeces
- function int ini_locateKeyIndex(ini_fd_t fd, const int
key);
- function int ini_locateKeys (ini_fd_t fd);
- function int ini_locateHeadingIndex (ini_fd_t fd, const
int heading);
- funciton int ini_locateHeadings(ini_fd_t fd);
- function const char * INI_LINKAGE ini_currentKey
(ini_fd_t fd);
- function const char * INI_LINKAGE ini_currentHeading
(ini_fd_t fd);

*bugs:
- I didn't check support for SWIG translations... and
also no VB, VC check
- when an ini-file starts with "key=value" the 'k' is
disappeared (already in V1.9)

Discussion

  • Karel

    Karel - 2004-08-18

    Logged In: YES
    user_id=1103526

    Attachement seems to be missing..

     
  • Karel

    Karel - 2004-08-18

    Logged In: YES
    user_id=1103526

    Attachment send by email at s_a_white@email.com

     
  • Simon White

    Simon White - 2004-08-18

    Logged In: YES
    user_id=59929

    Thankyou for the submission. Am curious as to the reasons
    behind the library name change from -lini to -lgccini?

    I'd be interested in having a look at the wrapper.
    Compatibility interfaces for those found standard on a
    particular platform are also welcome.

     
  • Karel

    Karel - 2004-08-18

    Logged In: YES
    user_id=1103526

    Hi Simon,

    ok, the reason why I changed it is more due to my system.
    I have to use 3rd party software and they have there own ini
    parser lib which they call also libini.so (This one is buggy
    when you open more then 2 files at a time). But I can't ask to
    change it.
    And thus to avoid undefined reference I renamed the library
    to libgccini analog to libtclini. I'm sorry for this.

    The wrapper is made and used on RH5.2 RH7.2 and RH7.3.
    Pls see below the listing:

    Regards,
    Karel.

    /* $Id: IniParser.h,v 1.1 2004/08/18 12:57:11 kva Exp $ */
    #ifndef INIPARSER_H
    #define INIPARSER_H

    #include <stdarg.h>

    #include <string>

    typedef void *ini_fd_t;

    class IniParser
    {
    public:
    enum Mode {READ, NEW, EXISTS};
    IniParser ();
    IniParser (const char *fileName);
    IniParser (const char *fileName, Mode mode, const char
    *lineComment);
    ~IniParser ();

    bool open ();
    bool open (const char *fileName, ...);
    bool open (const char *fileName, Mode mode);
    bool open (const char *fileName, Mode mode, const char
    *lineComment);

    bool close ();
    bool flush ();
    bool remove ();
    bool add (IniParser &iniParser);
    bool update (IniParser &iniParser);

    bool setLineComment (const char *lineComment);
    bool setMode (Mode mode);
    bool setFileName (const char *fileName, ...);
    bool setValueDelimiter (const char *delimiters);

    bool heading (const char *heading);
    bool heading (const int index);
    int nHeadings ();
    const char *currentHeading ();

    bool key (const char *key);
    bool key (const int index);
    int nKeys ();
    const char *currentKey ();

    bool value (const int index);
    int nValues ();

    bool readString (std::string &value);
    bool readDouble (double &value);
    bool readFloat (float &value);
    bool readLong (long &value);
    bool readInt (int &value);
    bool readShort (short &value);
    bool readBool (int &value);

    bool writeString (const std::string &value);
    bool writeDouble (const double &value);
    bool writeFloat (const float value);
    bool writeLong (const long value);
    bool writeInt (const int value);
    bool writeShort (const short value);
    bool writeBool (const int value);

    bool deleteHeading (const char *heading);
    bool deleteHeading (const int index);

    bool deleteKey (const char *key);
    bool deleteKey (const int index);

    void print ();

    protected:
    private:
    ini_fd_t fd_;
    std::string fileName_;
    Mode mode_;
    std::string lineComment_;

    bool foundHeading_;
    bool foundKey_;
    };

    #endif //INIPARSER_H

    /* $Id: IniParser.cpp,v 1.1 2004/08/18 12:57:11 kva Exp $ */
    #include <stdio.h>
    #include <limits.h>
    #include <float.h>

    #include <mlxtestlib/utility/IniParser.h>

    #include <libini.h>

    IniParser::IniParser ()
    {
    foundHeading_ = false;
    foundKey_ = false;
    fd_ = NULL;
    mode_ = READ;
    lineComment_ = "#";
    }

    IniParser::IniParser (const char *fileName)
    {
    foundHeading_ = false;
    foundKey_ = false;
    fd_ = NULL;
    mode_ = READ;
    lineComment_ = "#";
    open (fileName);
    }

    IniParser::IniParser (const char *fileName, Mode mode, const
    char *lineComment)
    {
    foundHeading_ = false;
    foundKey_ = false;
    fd_ = NULL;
    mode_ = READ;
    lineComment_ = "#";
    open (fileName, mode, lineComment);
    }

    IniParser::~IniParser ()
    {
    close ();
    }

    bool
    IniParser::open ()
    {
    if (fileName_ == "") return false;
    return open (fileName_.c_str (), mode_, lineComment_.c_str
    ());
    }

    bool
    IniParser::open (const char *fileName, ...)
    {
    char buffer[512];
    va_list ap;
    va_start (ap, fileName);
    vsnprintf (buffer, 512, fileName, ap);
    buffer[511] = '\0';
    va_end (ap);

    return open (buffer, mode_, lineComment_.c_str ());
    }

    bool
    IniParser::open (const char *fileName, Mode mode)
    {
    return open (fileName, mode, lineComment_.c_str ());
    }

    bool
    IniParser::open (const char *fileName, Mode mode, const
    char *lineComment)
    {
    setFileName (fileName);
    setMode (mode);
    setLineComment (lineComment);

    char modeBuffer = 'w';
    switch (mode_)
    {
    case NEW:
    modeBuffer = 'w';
    break;
    case EXISTS:
    modeBuffer = 'a';
    break;
    case READ:
    modeBuffer = 'r';
    break;
    }

    // a bug is in the libini --> the first key/value is not read!
    unless the very first char is a ' '
    // bug fix is done in this function
    // now copy the file to a temp file starting with a ' ' and
    read this one.
    std::string tempName = tmpnam (NULL);
    FILE *readFile = fopen (fileName_.c_str (), "r");
    bool fileIsBugFree = false;
    if (readFile == NULL)
    {
    foundHeading_ = false;
    foundKey_ = false;
    if (mode_ != NEW) return false;
    fileIsBugFree = true;
    }
    if (!fileIsBugFree)
    {
    char firstChar = '\0';
    fread (&firstChar, 1, 1, readFile);
    switch (firstChar)
    {
    case '\n':
    case '\r':
    case ' ':
    case '[':
    case '\0':
    fileIsBugFree = true;
    break;
    }
    fclose (readFile);
    }
    if (fileIsBugFree)
    {
    tempName = fileName_;
    }
    if (!fileIsBugFree)
    {
    readFile = fopen (fileName_.c_str (), "r");
    FILE *tempFile = fopen (tempName.c_str (), "w");
    if ((tempFile == NULL) || (readFile == NULL))
    {
    foundHeading_ = false;
    foundKey_ = false;
    return false;
    } else
    {
    // first write a ' '
    fprintf (tempFile, " ");
    // now copy the file
    while (!feof (readFile))
    {
    char buffer[128];
    int count = fread (buffer, 1, sizeof (buffer), readFile);
    if (count > 0)
    {
    fwrite (buffer, 1, count, tempFile);
    }
    }
    fclose (tempFile);
    fclose (readFile);

    // when we need to write the file back we should have
    write access and thus we have the corrected file back
    if (mode_ != READ)
    {
    readFile = fopen (fileName_.c_str (), "w");
    tempFile = fopen (tempName.c_str (), "r");
    if ((tempFile == NULL) || (readFile == NULL))
    {
    foundHeading_ = false;
    foundKey_ = false;
    return false;
    } else
    {
    // now copy the file
    while (!feof (tempFile))
    {
    char buffer[128];
    int count = fread (buffer, 1, sizeof (buffer),
    tempFile);
    if (count > 0)
    {
    fwrite (buffer, 1, count, readFile);
    }
    }
    fclose (tempFile);
    fclose (readFile);
    tempName = fileName_;
    }

    }

    }
    // end of bugfix
    }

    fd_ = ini_open (tempName.c_str (), &modeBuffer,
    lineComment_.c_str ());
    // fd_ = ini_open (fileName_.c_str (), &modeBuffer,
    lineComment_.c_str ());

    // remove temporary shit
    if (tempName != fileName)
    ::remove (tempName.c_str ());

    if (fd_)
    {
    heading (""); // default heading is ""
    } else
    {
    foundHeading_ = false;
    foundKey_ = false;
    }
    if (fd_)

    if (fd_ == NULL) return false;
    return true;
    }

    bool
    IniParser::close ()
    {
    if (fd_) ini_close (fd_);
    fd_ = NULL;
    foundHeading_ = false;
    foundKey_ = false;
    return true;
    }

    bool
    IniParser::flush ()
    {
    if (!fd_) return false;
    int ret = ini_flush (fd_);
    foundHeading_ = false;
    foundKey_ = false;
    return (ret >= 0);
    }

    bool
    IniParser::remove ()
    {
    if (!fd_) return false;
    int ret = ini_delete (fd_);
    foundHeading_ = false;
    foundKey_ = false;
    return (ret >= 0);
    }

    bool
    IniParser::add (IniParser &iniParser)
    {
    if (!fd_) return false;
    int ret = ini_append (fd_, iniParser.fd_);
    foundHeading_ = false;
    foundKey_ = false;
    return (ret >= 0);
    }

    bool
    IniParser::update (IniParser &iniParser)
    {
    foundHeading_ = false;
    foundKey_ = false;
    return false; // todo : create implementaiton
    }

    bool
    IniParser::setLineComment (const char *lineComment)
    {
    lineComment_ = lineComment;
    return true;
    }

    bool
    IniParser::setMode (Mode mode)
    {
    mode_ = mode;
    return true;
    }

    bool
    IniParser::setFileName (const char *fileName, ...)
    {
    char buffer[512];
    va_list ap;
    va_start (ap, fileName);
    vsnprintf (buffer, 512, fileName, ap);
    buffer[511] = '\0';
    va_end (ap);

    fileName_ = buffer;

    return (strlen (buffer) < 512);
    }

    bool
    IniParser::setValueDelimiter (const char *delimiters)
    {
    if (!fd_) return false;
    int ret = ini_listDelims (fd_, delimiters);
    return (ret >= 0);
    }

    bool
    IniParser::heading (const char *heading)
    {
    if (!fd_) return false;
    int ret = ini_locateHeading (fd_, heading);
    if (ret >= 0)
    {
    foundHeading_ = true;
    foundKey_ = false;
    return true;
    }
    foundHeading_ = false;
    foundKey_ = false;
    return false;
    }

    bool
    IniParser::heading (const int index)
    {
    if (!fd_) return false;
    int ret = ini_locateHeadingIndex (fd_, index);
    if (ret >= 0)
    {
    foundHeading_ = true;
    foundKey_ = false;
    return true;
    }
    foundHeading_ = false;
    foundKey_ = false;
    return false;
    }

    int
    IniParser::nHeadings ()
    {
    if (!fd_) return -1;
    return ini_locateHeadings (fd_);
    }

    const char *
    IniParser::currentHeading ()
    {
    if (!fd_) return NULL;
    if (!foundHeading_) return NULL;
    return ini_currentHeading (fd_);
    }

    bool
    IniParser::key (const char *key)
    {
    if (!fd_) return false;
    int ret = ini_locateKey (fd_, key);
    if (!foundHeading_) return false; // keep it here after locate -
    -> for writing purposes
    if (ret >= 0)
    {
    foundKey_ = true;
    return true;
    }
    foundKey_ = false;
    return false;
    }

    bool
    IniParser::key (const int index)
    {
    if (!fd_) return false;
    if (!foundHeading_) return false; // keep it here before
    locate --> not possible to write to new heading by selection
    of index!
    int ret = ini_locateKeyIndex (fd_, index);
    if (ret >= 0)
    {
    foundKey_ = true;
    return true;
    }
    foundKey_ = false;
    return false;
    }

    int
    IniParser::nKeys ()
    {
    if (!fd_) return -1;
    return ini_locateKeys (fd_);
    }

    const char *
    IniParser::currentKey ()
    {
    if (!fd_) return NULL;
    if (!foundHeading_) return NULL;
    if (!foundKey_) return NULL;
    return ini_currentKey (fd_);
    }

    bool
    IniParser::value (const int index)
    {
    if (!fd_) return false;
    if (!foundKey_) return false;
    int ret = ini_listIndex (fd_, index);
    return (ret >= 0);
    }

    int
    IniParser::nValues ()
    {
    if (!fd_) return -1;
    if (!foundKey_) return -1;
    int ret = ini_listLength (fd_);
    return ret;
    }

    bool
    IniParser::readString (std::string &value)
    {
    value = "";
    if (!fd_) return false;
    if (!foundKey_) return false;
    char *buffer;
    int minSize = ini_dataLength (fd_);
    buffer = new char[minSize+10];

    int ret = ini_readString (fd_, buffer, minSize + 5);
    if (ret >= 0) value = buffer;
    delete[] buffer;
    return (ret >= 0);
    }

    bool
    IniParser::readDouble (double &value)
    {
    value = DBL_MAX;
    if (!foundKey_) return false;
    int ret = ini_readDouble (fd_, &value);
    if (ret < 0) value = DBL_MAX;
    return (ret >= 0);
    }

    bool
    IniParser::readFloat (float &value)
    {
    value = FLT_MAX;
    if (!foundKey_) return false;
    double doubleValue;
    int ret = ini_readDouble (fd_, &doubleValue);
    if (ret >= 0) value = doubleValue;
    return (ret >= 0);
    }

    bool
    IniParser::readLong (long &value)
    {
    value = LONG_MAX;
    if (!foundKey_) return false;
    int ret = ini_readLong (fd_, &value);
    if (ret < 0) value = LONG_MAX;
    return (ret >= 0);
    }

    bool
    IniParser::readInt (int &value)
    {
    value = INT_MAX;
    if (!foundKey_) return false;
    int ret = ini_readInt (fd_, &value);
    printf ("ret = %d %d\n", ret, value);
    if (ret < 0) value = INT_MAX;
    return (ret >= 0);
    }

    bool
    IniParser::readShort (short &value)
    {
    value = SHRT_MAX;
    if (!foundKey_) return false;
    int intValue;
    int ret = ini_readInt (fd_, &intValue);
    if (ret >= 0) value = (short)intValue;
    return (ret >= 0);
    }

    bool
    IniParser::readBool (int &value)
    {
    value = -1;
    if (!foundKey_) return false;
    int ret = ini_readBool (fd_, &value);
    if (ret < 0) value = -1;
    return (ret >= 0);
    }

    bool
    IniParser::writeString (const std::string &value)
    {
    if (!fd_) return false;
    //if (!foundKey_) return false;
    int ret = ini_writeString (fd_, value.c_str ());
    ini_flush (fd_);
    return (ret >= 0);
    }

    bool
    IniParser::writeDouble (const double &value)
    {
    if (!fd_) return false;
    if (!foundKey_) return false;
    int ret = ini_writeDouble (fd_, value);
    ini_flush (fd_);
    return (ret >= 0);
    }

    bool
    IniParser::writeFloat (const float value)
    {
    if (!fd_) return false;
    if (!foundKey_) return false;
    int ret = ini_writeDouble (fd_, value);
    ini_flush (fd_);
    return (ret >= 0);
    }

    bool
    IniParser::writeLong (const long value)
    {
    if (!fd_) return false;
    if (!foundKey_) return false;
    int ret = ini_writeLong (fd_, value);
    ini_flush (fd_);
    return (ret >= 0);
    }

    bool
    IniParser::writeInt (const int value)
    {
    if (!fd_) return false;
    if (!foundKey_) return false;
    int ret = ini_writeLong (fd_, value);
    ini_flush (fd_);
    return (ret >= 0);

    }

    bool
    IniParser::writeShort (const short value)
    {
    if (!fd_) return false;
    if (!foundKey_) return false;
    int ret = ini_writeLong (fd_, value);
    ini_flush (fd_);
    return (ret >= 0);
    }

    bool
    IniParser::writeBool (const int value)
    {
    if (!fd_) return false;
    if (!foundKey_) return false;
    int ret = ini_writeBool (fd_, value);
    ini_flush (fd_);
    return (ret >= 0);
    }

    bool
    IniParser::deleteHeading (const char *heading)
    {
    if (!fd_) return false;
    if (!this->heading (heading)) return false;
    int ret = ini_deleteHeading (fd_);
    if (ret >= 0)
    {
    foundHeading_ = false;
    foundKey_ = false;
    }
    return (ret >= 0);
    }

    bool
    IniParser::deleteHeading (const int index)
    {
    if (!fd_) return false;
    if (!this->heading (index)) return false;
    int ret = ini_deleteHeading (fd_);
    if (ret >= 0)
    {
    foundHeading_ = false;
    foundKey_ = false;
    }
    return (ret >= 0);
    }

    bool
    IniParser::deleteKey (const char *key)
    {
    if (!fd_) return false;
    if (!foundHeading_) return false;
    if (!this->key (key)) return false;
    int ret = ini_deleteKey (fd_);
    if (ret >= 0)
    {
    foundKey_ = false;
    }
    return (ret >= 0);
    }

    bool
    IniParser::deleteKey (const int index)
    {
    if (!fd_) return false;
    if (!foundHeading_) return false;
    if (!this->key (index)) return false;
    int ret = ini_deleteKey (fd_);
    if (ret >= 0)
    {
    foundKey_ = false;
    }
    return (ret >= 0);
    }

    void
    IniParser::print ()
    {
    heading ("");
    for (int k=0; k<nKeys (); k++)
    {
    key (k);
    std::string value;
    if (readString (value))
    {
    printf ("%s = %s\n", currentKey (), value.c_str ());
    }
    }

    for (int h=0; h<nHeadings (); h++)
    {
    heading (h);
    if (!strcmp (currentHeading (), "")) continue;
    printf ("[%s]\n", currentHeading ());
    for (int k=0; k<nKeys (); k++)
    {
    key (k);
    std::string value;
    readString (value);
    printf (" %s = %s\n", currentKey (), value.c_str ());
    }
    }
    }

    #ifdef TEST_INI_PARSER

    int main ()
    {
    IniParser ini ("ex.ini", IniParser::READ, "#");
    // IniParser ini ("ex.ini");
    // ini.setValueDelimiter (",.");
    // if (ini.heading ("dir")) printf ("ok\n");
    if (ini.key ("kVa")) printf ("ok\n");
    std::string test;
    if (ini.readString (test)) printf ("ok\n");
    printf ("%s\n", test.c_str ());

    if (ini.key ("bool")) printf ("okkey\n");
    int testBool;
    if (ini.readInt (testBool)) printf ("okread\n");
    printf ("bool = %d\n", testBool);

    ini.writeString ("write!!");

    // if (ini.heading ("Home")) printf ("ok\n");
    // if (ini.key ("tel")) printf ("ok\n");
    if (ini.readString (test)) printf ("ok\n");
    printf ("%s\n", test.c_str ());
    if (ini.readString (test)) printf ("ok\n");
    printf ("%s\n", test.c_str ());
    if (ini.readString (test)) printf ("ok\n");
    printf ("%s\n", test.c_str ());
    if (ini.readString (test)) printf ("ok\n");
    printf ("%s\n", test.c_str ());

    printf ("headings %d\n", ini.nHeadings ());
    for (int h=0; h < ini.nHeadings (); h++)
    {
    ini.heading (h);
    printf ("[%s]\n", ini.currentHeading ());
    for (int k=0; k < ini.nKeys (); k++)
    {
    ini.key (k);
    std::string value;
    ini.readString (value);
    printf (" %s = %s \n", ini.currentKey (), value.c_str ());
    }
    }

    return 0;
    }

    #endif

     
  • Simon White

    Simon White - 2004-11-27
    • status: open --> closed
     
  • Simon White

    Simon White - 2004-11-27

    Logged In: YES
    user_id=59929

    Patches integrated:

    *ini_readInt returns zero only if succesful conversion is
    done.
    *ini_readDouble returns zero only if succesful conversion
    is done.
    *ini_readLong returns zero only if succesful conversion is
    done.
    *ini_readBool true has now synoniem yes, on; false has
    no, off
    *libini.spec.in: make it compactible with red hat 5.2 rpm
    2.5.5

    Patches delayed (something should be available for 1.1.11):

    *support for exploring an ini file by indeces

    Patches redundent (other code fixed or alternatives put in
    place):

    *Ini parser is case insensitive for headings and keys
    *ini_store starts writing with a space ' ' see also bugs

    Patches not being applied:

    *libini.so is renamed to libgccini.so so -l option should be
    changed to -lgccini

    A C++ interface on some form will be provided 1.1.11.

     
  • Simon White

    Simon White - 2004-12-13

    Logged In: YES
    user_id=59929

    The spec patch has caused an undesirable side effect that I
    did not realise would occur. Is this spec file change
    absolutely required for the older redhat or was it just away
    for you to install the rpm in a different location than default?

     
  • Simon White

    Simon White - 2005-01-04

    Logged In: YES
    user_id=59929

    Believe I have found a fix for the spec issue. Please can
    you test the new spec file as now works again for newer
    versions of rpm?

    CHANGE: Found a RedHat page on defining macros if they don't
    exist, so now use:

    %{!?_prefix: %define _prefix /usr}

    etc. Hope RedHat 5.2 supports that.

     
  • Simon White

    Simon White - 2005-01-04
    • status: closed --> open
     
  • Simon White

    Simon White - 2005-01-04

    Logged In: YES
    user_id=59929

    Re opened, something funny with pending. Please read
    attached comments at the sourceforge page.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.