LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Ini_writetofile deletes everything else in the file

How could I access/ modify values in an INI file without losing whatever else is in the file like the comments and whatnot?

The mothod provided in the example of CVI7 reads the whole thing or write the entire data pack and it seems to delete the old data as opposed to modifying it.


thanks
Amin
0 Kudos
Message 1 of 11
(4,862 Views)
Yes, this is correct: Ini_WriteToFile writes all (and only) actual content of the IniText stucture to the file.

If you want to modify something on an existing INI file, you must first read from the file into memory, next modify the desired value and then save all the IniText structure to file.

That is:
Ini_New
Ini_ReadFromFile
Ini_Putxxx
Ini_WriteToFile
Ini_Dispose

Roberto


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 11
(4,855 Views)
One last note: the only thing you're not able to maintain are the comments (lines starting with semicolon).
At least, I never find a way to do so...


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 3 of 11
(4,852 Views)
Hi Amin,
sorry for my bad english ... this is a solution to your problem.

Open the file INIFILE.C (you find it, for example, in C:\PROGRAM FILES\NATIONAL INSTRUMENTS\CVI70\toolslib\toolbox\INIFILE.C)

You must modify two functions:

Ini_WriteEntry ()
Ini_ReadGeneric ().


Function Ini_WriteEntry() before:

.......
len = strlen(entry->value);

if (len <= INI_NUM_CHARS_PER_LINE)
{
sprintf (outputBuffer, entry->addMarkerQuotes ? "%s%s\"%s\"" : "%s%s%s", entry->name, iniText->nameValueOutputSeparatorToken, entry->value);
errChk ((*outputFunc)(outputDest, outputBuffer));
}
else
{
srcTextPtr = entry->value;
i = 1;
.......


Function Ini_WriteEntry() after:

.......
len = strlen(entry->value);

if (len <= INI_NUM_CHARS_PER_LINE)
{
if (entry->name[0] == ';')
sprintf (outputBuffer, "%s", entry->name);
else
sprintf (outputBuffer, entry->addMarkerQuotes ? "%s%s\"%s\"" : "%s%s%s", entry->name, iniText->nameValueOutputSeparatorToken, entry->value);
errChk ((*outputFunc)(outputDest, outputBuffer));
}
else
{
srcTextPtr = entry->value;
i = 1;
.......


Function Ini_ReadGeneric() before:

.......
switch (lineType)
{
case kIni_SectionLine:
if (theIniText->sectionFilter && !theIniText->sectionFilter(theIniText, theIniText->sectionFilterCallbackData, sectionBuf))
currentSection = NULL;
else
{
nullChk(newSection = Ini_NewSection(sectionBuf, theIniText->sorted));
newSection->sourceLine = lineRead;
errChk(ListInsertItem(theIniText->sectionList, &newSection, END_OF_LIST));
currentSection = newSection;
newSection = NULL;
}
break;
case kIni_TagAndValueLine:
if (currentSection)
{
nullChk(newEntry = Ini_NewEntry(itemNameBuf, valueBuf, TRUE));
newEntry->sourceLine = lineRead;
errChk(ListInsertItem(currentSection->entryList, &newEntry, END_OF_LIST));
newEntry = NULL;
}
break;
default:
break;
}
.......


Function Ini_ReadGeneric() after:

.......
switch (lineType)
{
case kIni_SectionLine:
if (theIniText->sectionFilter && !theIniText->sectionFilter(theIniText, theIniText->sectionFilterCallbackData, sectionBuf))
currentSection = NULL;
else
{
nullChk(newSection = Ini_NewSection(sectionBuf, theIniText->sorted));
newSection->sourceLine = lineRead;
errChk(ListInsertItem(theIniText->sectionList, &newSection, END_OF_LIST));
currentSection = newSection;
newSection = NULL;
}
break;
case kIni_TagAndValueLine:
if (currentSection)
{
nullChk(newEntry = Ini_NewEntry(itemNameBuf, valueBuf, TRUE));
newEntry->sourceLine = lineRead;
errChk(ListInsertItem(currentSection->entryList, &newEntry, END_OF_LIST));
newEntry = NULL;
}
break;
case kIni_CommentLine:
if (currentSection)
{
nullChk(newEntry = Ini_NewEntry(lineBuf, "", TRUE));
newEntry->sourceLine = lineRead;
errChk(ListInsertItem(currentSection->entryList, &newEntry, END_OF_LIST));
newEntry = NULL;
}
break;
default:
break;
}
.......





Inifile before reading:

[EXAMPLE]
; Acquisition setup
OnOff = 1
Board = 1 ; Number of board
NumberOfChannels = 10 ; Number of channels
....


Inifile after writing:

[EXAMPLE]
; Acquisition setup
OnOff = 1
Board = 1
NumberOfChannels = 10
....


Bye,
Luca
Message 4 of 11
(4,832 Views)
Roberto,

the comments were exactly what I was trying to save. I wanted to make sure people in production line know what to do with the file and the whole software when I leave this place.



Luca,
I needed something to save the header comments which seems to be what your modification does. I was looking at that file today, I think I will add your modification once I get my mind off the rest of the software.


By theway, why "sorry"? you helping me so even if I don't like it I could just suck it up. But your English looked pretty good to me anyways

I know for fact Borland Delphi 3 and 4 had a LOT more functions to deal with files and INI files. You could almost treat them as RAM objects. This is a bit of a disappointment.
0 Kudos
Message 5 of 11
(4,827 Views)
Well, here we are entering into personal attitudes and style in programming.

I tend not to modify standard instruments and code shipped with CVI mainly to avoid the need to maintain the modification throughout new releases of CVI and related instruments. Moreover, since this code is not written by me, I'm not absolutely sure that future releases can support the improvement I am introducing.

In a case like that you mention, I simply would add some items to the INI file for the comments, letting the instrument read and save them back to file with standard functions.

More or less like this:

[Section 1]
Section1 comment="This is a comment to section 1"
Item1="Value 1"
Item2="Value2"
Item2 comment="This is a comment to item 2"
Item3=123
etc. etc.

Just my 2c.


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 6 of 11
(4,816 Views)

I have been unable to find out how to actually re-build the FP after maiking the code changes you describe?

 

Can someone point me to the proper procedure?

 

There is no inifil.prj available.

 

Thanks

 

 

0 Kudos
Message 7 of 11
(4,317 Views)

You don't need a project, you just need to recompile inifile.c after you're done making your changes. To compile the file, open it in the source editor, and then select Options>>Create Object File. That will create a new version of inifile.obj. Then you'll need to unload and reload inifile.fp.

 

Luis

Message 8 of 11
(4,297 Views)

Thank you Louis.  I thought that any changes to the C code of a Function Panel might require more than a simple compilatioin.

0 Kudos
Message 9 of 11
(4,284 Views)

You raise a good point. To clarify: as long as you don't change the public interface of inifile.c, then you don't need to do anything else. But if you change the exported function signatures in any way, or you add or remove a function, then you would have to also modify the fp file accordingly.

 

Luis

0 Kudos
Message 10 of 11
(4,267 Views)