From 079fae8450c50c5b5324d828a0c688e693d2b7f7 Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 6 Nov 2018 19:30:32 -0700 Subject: [PATCH 01/42] Typo fixes in README --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index dbc30d0..fe63a7d 100644 --- a/README.md +++ b/README.md @@ -5,15 +5,15 @@ ## I - Overview -This modules offers parsing of ini files from the C level. -See a complete documentation in HTML format, from this directory -open the file html/index.html with any HTML-capable browser. +This modules offers parsing of ini files from C. +See the complete documentation in HTML format: from this directory, +open the file `html/index.html` with any HTML-capable browser. -Key features : +Key features: - Small : around 1500 sloc inside 4 files (2 .c and 2 .h) - Portable : no dependancies, written in `-ansi -pedantic` C89 - - Fully reintrant : easy to make it thread-safe (just surround + - Fully re-entrant : easy to make it thread-safe (just surround library calls by mutex) ## II - Building project @@ -23,13 +23,13 @@ A simple `make` at the root of the project should be enough to get the static You should consider trying the following rules too : - - `make check` : run the unitary tests + - `make check` : run the unit tests - `make example` : compile the example, run it with `./example/iniexample` ## III - License This software is released under MIT License. -See LICENSE for full informations +See LICENSE for more details ## IV - Versions From 06acd33b1b5d66057cd3164b3e29237fcfd8a8a6 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 17 Nov 2018 13:55:41 +0100 Subject: [PATCH 02/42] Removed unused defines. The defines MAXVALSZ and DICT_INVALID_KEY are not used anymore. --- src/dictionary.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/dictionary.c b/src/dictionary.c index cb7ccd4..2daea03 100644 --- a/src/dictionary.c +++ b/src/dictionary.c @@ -20,15 +20,9 @@ #include #include -/** Maximum value size for integers and doubles. */ -#define MAXVALSZ 1024 - /** Minimal allocated number of entries in a dictionary */ #define DICTMINSZ 128 -/** Invalid key token */ -#define DICT_INVALID_KEY ((char*)-1) - /*--------------------------------------------------------------------------- Private functions ---------------------------------------------------------------------------*/ From 0a71800dcf802240efb3169e3c68002d855cbeac Mon Sep 17 00:00:00 2001 From: hityc2019 Date: Tue, 2 Jul 2019 09:05:34 +0800 Subject: [PATCH 03/42] add testcase:iniparser_dump();iniparser_dump_ini();iniparser_dumpsection_ini() --- test/Makefile | 1 + test/ressources/old.ini | 4 ++ test/test_iniparser.c | 140 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 test/ressources/old.ini diff --git a/test/Makefile b/test/Makefile index 15a8d26..d649ec0 100644 --- a/test/Makefile +++ b/test/Makefile @@ -33,3 +33,4 @@ clean veryclean: rm -rf AllTests.c rm -rf $(OBJ) AllTests.o rm -rf testrun + rm -rf ./ressources/new.ini ./ressources/test.ini ./ressources/test.txt \ No newline at end of file diff --git a/test/ressources/old.ini b/test/ressources/old.ini new file mode 100644 index 0000000..a8c0411 --- /dev/null +++ b/test/ressources/old.ini @@ -0,0 +1,4 @@ +[section] +key_01 = hello world ;test ini + +key1 = 321abc diff --git a/test/test_iniparser.c b/test/test_iniparser.c index c76529c..25eec30 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -14,7 +14,10 @@ #define GOOD_INI_PATH "ressources/good_ini" #define BAD_INI_PATH "ressources/bad_ini" - +#define INI_PATH "ressources/old.ini" +#define INI_PATH_1 "ressources/new.ini" +#define INI_PATH_2 "ressources/test.ini" +#define INI_PATH_3 "ressources/test.txt" /* Tool function to create and populate a generic non-empty dictionary */ static dictionary * generate_dictionary(unsigned sections, unsigned entries_per_section) @@ -696,3 +699,138 @@ void Test_iniparser_error_callback(CuTest *tc) CuAssertPtrEquals(tc, NULL, dic); CuAssertStrEquals(tc, "", _last_error); } + +void Test_iniparser_dump(CuTest *tc) +{ + dictionary *dic; + FILE *fp = NULL; + char buff[255]; + + /*loading old.ini*/ + dic = iniparser_load(INI_PATH); + if(dic ==NULL) + { + printf("error: old.ini is not exist"); + exit(-1); + } + /*check the data of old.ini*/ + CuAssertStrEquals(tc,"hello world",iniparser_getstring(dic,"section:key_01",NULL)); + CuAssertStrEquals(tc,"321abc",iniparser_getstring(dic,"section:key1",NULL)); + /*open test.txt*/ + fp = fopen(INI_PATH_3,"w"); + if(fp == NULL) + { + printf("error: test.txt is not exist"); + exit(-1); + } + /*dump the data of old.ini to new.ini*/ + iniparser_dump(dic,fp); + fclose(fp); + iniparser_freedict(dic); + /*read the data of test.txt*/ + fp = fopen(INI_PATH_3,"r"); + if(fp == NULL) + { + printf("error: test.txt is not exist"); + exit(-1); + } + fgets(buff,100,fp); + /*remove '\n'*/ + if(buff[strlen(buff)-1] == '\n') + { + buff[strlen(buff)-1] = '\0'; + } + CuAssertStrEquals(tc,"[section]=UNDEF",buff); + fgets(buff,100,fp); + if(buff[strlen(buff)-1] == '\n') + { + buff[strlen(buff)-1] = '\0'; + } + CuAssertStrEquals(tc,"[section:key_01]=[hello world]",buff); + fgets(buff,100,fp); + if(buff[strlen(buff)-1] == '\n') + { + buff[strlen(buff)-1] = '\0'; + } + CuAssertStrEquals(tc,"[section:key1]=[321abc]",buff); + fclose(fp); +} + +void Test_iniparser_dump_ini(CuTest *tc) +{ + dictionary *dic; + FILE *fp = NULL; + + /*loading old.ini*/ + dic = iniparser_load(INI_PATH); + if(dic ==NULL) + { + printf("error: old.ini is not exist"); + exit(-1); + } + /*check the data of old.ini*/ + CuAssertStrEquals(tc,"hello world",iniparser_getstring(dic,"section:key_01",NULL)); + CuAssertStrEquals(tc,"321abc",iniparser_getstring(dic,"section:key1",NULL)); + /*open new.ini*/ + fp = fopen(INI_PATH_1,"w"); + if(fp == NULL) + { + printf("error: new.ini is not exist"); + exit(-1); + } + /*dump the data of old.ini to new.ini*/ + iniparser_dump_ini(dic,fp); + fclose(fp); + iniparser_freedict(dic); + /*loading new.ini*/ + dic = iniparser_load(INI_PATH_1); + if(dic ==NULL) + { + printf("error: new.ini is not exist"); + exit(-1); + } + /*check the data of new.ini*/ + CuAssertStrEquals(tc,"hello world",iniparser_getstring(dic,"section:key_01",NULL)); + CuAssertStrEquals(tc,"321abc",iniparser_getstring(dic,"section:key1",NULL)); + iniparser_freedict(dic); +} + +void Test_iniparser_dumpsection_ini(CuTest *tc) +{ + dictionary *dic; + FILE *fp = NULL; + + /*loading old.ini*/ + dic = iniparser_load(INI_PATH); + if(dic ==NULL) + { + printf("error: old.ini is not exist"); + exit(-1); + } + /*check the data of old.ini*/ + CuAssertStrEquals(tc,"hello world",iniparser_getstring(dic,"section:key_01",NULL)); + CuAssertStrEquals(tc,"321abc",iniparser_getstring(dic,"section:key1",NULL)); + /*open test.ini*/ + fp = fopen(INI_PATH_2,"w"); + if(fp == NULL) + { + printf("error: test.ini is not exist"); + exit(-1); + } + /*dump the data of old.ini to test.ini*/ + iniparser_dumpsection_ini(dic,"section",fp); + fclose(fp); + iniparser_freedict(dic); + /*loading test.ini*/ + dic = iniparser_load(INI_PATH_2); + if(dic ==NULL) + { + printf("error: test.ini is not exist"); + exit(-1); + } + /*check the data of test.ini*/ + CuAssertStrEquals(tc,"hello world",iniparser_getstring(dic,"section:key_01",NULL)); + CuAssertStrEquals(tc,"321abc",iniparser_getstring(dic,"section:key1",NULL)); + iniparser_freedict(dic); +} + From f56f67bc43bd108cc43d0db4ca9bc912112bf37e Mon Sep 17 00:00:00 2001 From: lilinchao Date: Mon, 5 Aug 2019 15:57:14 +0800 Subject: [PATCH 04/42] add dictionary_del line187,188 --- test/test_dictionary.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test_dictionary.c b/test/test_dictionary.c index f89f1c1..250c878 100644 --- a/test/test_dictionary.c +++ b/test/test_dictionary.c @@ -184,6 +184,9 @@ void Test_dictionary_unset(CuTest *tc) CuAssertStrEquals(tc, dic1_dump, dic2_dump); free(dic1_dump); free(dic2_dump); + + dictionary_del(dic1); + dictionary_del(dic2); } void Test_dictionary_dump(CuTest *tc) From 15659d9b6fa52434d1ad700076693d922fd46d38 Mon Sep 17 00:00:00 2001 From: chenguoping Date: Fri, 30 Aug 2019 14:41:30 +0800 Subject: [PATCH 05/42] add test_iniparser_find_entry --- html/doxygen.css | 545 ----------------------------------- html/doxygen.png | Bin 1281 -> 0 bytes html/globals_func.html | 64 ----- html/index.html | 101 ------- html/iniparser_8h.html | 583 -------------------------------------- html/iniparser_8main.html | 19 -- html/tab_b.gif | Bin 35 -> 0 bytes html/tab_l.gif | Bin 706 -> 0 bytes html/tab_r.gif | Bin 2585 -> 0 bytes html/tabs.css | 105 ------- test/test_iniparser.c | 28 ++ 11 files changed, 28 insertions(+), 1417 deletions(-) delete mode 100644 html/doxygen.css delete mode 100644 html/doxygen.png delete mode 100644 html/globals_func.html delete mode 100644 html/index.html delete mode 100644 html/iniparser_8h.html delete mode 100644 html/iniparser_8main.html delete mode 100644 html/tab_b.gif delete mode 100644 html/tab_l.gif delete mode 100644 html/tab_r.gif delete mode 100644 html/tabs.css diff --git a/html/doxygen.css b/html/doxygen.css deleted file mode 100644 index d6aaf28..0000000 --- a/html/doxygen.css +++ /dev/null @@ -1,545 +0,0 @@ -/* The standard CSS for doxygen */ - -body, table, div, p, dl { - font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; - font-size: 12px; -} - -/* @group Heading Levels */ - -h1 { - text-align: center; - font-size: 150%; -} - -h2 { - font-size: 120%; -} - -h3 { - font-size: 100%; -} - -dt { - font-weight: bold; -} - -div.multicol { - -moz-column-gap: 1em; - -webkit-column-gap: 1em; - -moz-column-count: 3; - -webkit-column-count: 3; -} - -p.startli, p.startdd, p.starttd { - margin-top: 2px; -} - -p.endli { - margin-bottom: 0px; -} - -p.enddd { - margin-bottom: 4px; -} - -p.endtd { - margin-bottom: 2px; -} - -/* @end */ - -caption { - font-weight: bold; -} - -span.legend { - font-size: 70%; - text-align: center; -} - -h3.version { - font-size: 90%; - text-align: center; -} - -div.qindex, div.navtab{ - background-color: #e8eef2; - border: 1px solid #84b0c7; - text-align: center; - margin: 2px; - padding: 2px; -} - -div.qindex, div.navpath { - width: 100%; - line-height: 140%; -} - -div.navtab { - margin-right: 15px; -} - -/* @group Link Styling */ - -a { - color: #153788; - font-weight: normal; - text-decoration: none; -} - -.contents a:visited { - color: #1b77c5; -} - -a:hover { - text-decoration: underline; -} - -a.qindex { - font-weight: bold; -} - -a.qindexHL { - font-weight: bold; - background-color: #6666cc; - color: #ffffff; - border: 1px double #9295C2; -} - -.contents a.qindexHL:visited { - color: #ffffff; -} - -a.el { - font-weight: bold; -} - -a.elRef { -} - -a.code { - color: #3030f0; -} - -a.codeRef { - color: #3030f0; -} - -/* @end */ - -dl.el { - margin-left: -1cm; -} - -.fragment { - font-family: monospace, fixed; - font-size: 105%; -} - -pre.fragment { - border: 1px solid #CCCCCC; - background-color: #f5f5f5; - padding: 4px 6px; - margin: 4px 8px 4px 2px; - overflow: auto; - word-wrap: break-word; - font-size: 9pt; - line-height: 125%; -} - -div.ah { - background-color: black; - font-weight: bold; - color: #ffffff; - margin-bottom: 3px; - margin-top: 3px -} - -div.groupHeader { - margin-left: 16px; - margin-top: 12px; - margin-bottom: 6px; - font-weight: bold; -} - -div.groupText { - margin-left: 16px; - font-style: italic; -} - -body { - background: white; - color: black; - margin-right: 20px; - margin-left: 20px; -} - -td.indexkey { - background-color: #e8eef2; - font-weight: bold; - border: 1px solid #CCCCCC; - margin: 2px 0px 2px 0; - padding: 2px 10px; -} - -td.indexvalue { - background-color: #e8eef2; - border: 1px solid #CCCCCC; - padding: 2px 10px; - margin: 2px 0px; -} - -tr.memlist { - background-color: #f0f0f0; -} - -p.formulaDsp { - text-align: center; -} - -img.formulaDsp { - -} - -img.formulaInl { - vertical-align: middle; -} - -div.center { - text-align: center; - margin-top: 0px; - margin-bottom: 0px; - padding: 0px; -} - -div.center img { - border: 0px; -} - -img.footer { - border: 0px; - vertical-align: middle; -} - -/* @group Code Colorization */ - -span.keyword { - color: #008000 -} - -span.keywordtype { - color: #604020 -} - -span.keywordflow { - color: #e08000 -} - -span.comment { - color: #800000 -} - -span.preprocessor { - color: #806020 -} - -span.stringliteral { - color: #002080 -} - -span.charliteral { - color: #008080 -} - -span.vhdldigit { - color: #ff00ff -} - -span.vhdlchar { - color: #000000 -} - -span.vhdlkeyword { - color: #700070 -} - -span.vhdllogic { - color: #ff0000 -} - -/* @end */ - -.search { - color: #003399; - font-weight: bold; -} - -form.search { - margin-bottom: 0px; - margin-top: 0px; -} - -input.search { - font-size: 75%; - color: #000080; - font-weight: normal; - background-color: #e8eef2; -} - -td.tiny { - font-size: 75%; -} - -.dirtab { - padding: 4px; - border-collapse: collapse; - border: 1px solid #84b0c7; -} - -th.dirtab { - background: #e8eef2; - font-weight: bold; -} - -hr { - height: 0px; - border: none; - border-top: 1px solid #666; -} - -hr.footer { - height: 1px; -} - -/* @group Member Descriptions */ - -.mdescLeft, .mdescRight, -.memItemLeft, .memItemRight, -.memTemplItemLeft, .memTemplItemRight, .memTemplParams { - background-color: #FAFAFA; - border: none; - margin: 4px; - padding: 1px 0 0 8px; -} - -.mdescLeft, .mdescRight { - padding: 0px 8px 4px 8px; - color: #555; -} - -.memItemLeft, .memItemRight, .memTemplParams { - border-top: 1px solid #ccc; -} - -.memItemLeft, .memTemplItemLeft { - white-space: nowrap; -} - -.memTemplParams { - color: #606060; - white-space: nowrap; -} - -/* @end */ - -/* @group Member Details */ - -/* Styles for detailed member documentation */ - -.memtemplate { - font-size: 80%; - color: #606060; - font-weight: normal; - margin-left: 3px; -} - -.memnav { - background-color: #e8eef2; - border: 1px solid #84b0c7; - text-align: center; - margin: 2px; - margin-right: 15px; - padding: 2px; -} - -.memitem { - padding: 0; - margin-bottom: 10px; -} - -.memname { - white-space: nowrap; - font-weight: bold; - margin-left: 6px; -} - -.memproto { - border-top: 1px solid #84b0c7; - border-left: 1px solid #84b0c7; - border-right: 1px solid #84b0c7; - padding: 0; - background-color: #d5e1e8; - font-weight: bold; - /* firefox specific markup */ - background-image: -moz-linear-gradient(rgba(228, 233, 245, 1.0) 0%, rgba(193, 205, 232, 1.0) 100%); - -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; - -moz-border-radius-topright: 8px; - -moz-border-radius-topleft: 8px; - /* webkit specific markup */ - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(228, 233, 245, 1.0)), to(rgba(193, 205, 232, 1.0))); - -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); - -webkit-border-top-right-radius: 8px; - -webkit-border-top-left-radius: 8px; - -} - -.memdoc { - border-bottom: 1px solid #84b0c7; - border-left: 1px solid #84b0c7; - border-right: 1px solid #84b0c7; - padding: 2px 5px; - background-color: #eef3f5; - border-top-width: 0; - /* firefox specific markup */ - -moz-border-radius-bottomleft: 8px; - -moz-border-radius-bottomright: 8px; - -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; - /* webkit specific markup */ - -webkit-border-bottom-left-radius: 8px; - -webkit-border-bottom-right-radius: 8px; - -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -} - -.paramkey { - text-align: right; -} - -.paramtype { - white-space: nowrap; -} - -.paramname { - color: #602020; - white-space: nowrap; -} -.paramname em { - font-style: normal; -} - -/* @end */ - -/* @group Directory (tree) */ - -/* for the tree view */ - -.ftvtree { - font-family: sans-serif; - margin: 0.5em; -} - -/* these are for tree view when used as main index */ - -.directory { - font-size: 9pt; - font-weight: bold; -} - -.directory h3 { - margin: 0px; - margin-top: 1em; - font-size: 11pt; -} - -/* -The following two styles can be used to replace the root node title -with an image of your choice. Simply uncomment the next two styles, -specify the name of your image and be sure to set 'height' to the -proper pixel height of your image. -*/ - -/* -.directory h3.swap { - height: 61px; - background-repeat: no-repeat; - background-image: url("yourimage.gif"); -} -.directory h3.swap span { - display: none; -} -*/ - -.directory > h3 { - margin-top: 0; -} - -.directory p { - margin: 0px; - white-space: nowrap; -} - -.directory div { - display: none; - margin: 0px; -} - -.directory img { - vertical-align: -30%; -} - -/* these are for tree view when not used as main index */ - -.directory-alt { - font-size: 100%; - font-weight: bold; -} - -.directory-alt h3 { - margin: 0px; - margin-top: 1em; - font-size: 11pt; -} - -.directory-alt > h3 { - margin-top: 0; -} - -.directory-alt p { - margin: 0px; - white-space: nowrap; -} - -.directory-alt div { - display: none; - margin: 0px; -} - -.directory-alt img { - vertical-align: -30%; -} - -/* @end */ - -address { - font-style: normal; - color: #333; -} - -table.doxtable { - border-collapse:collapse; -} - -table.doxtable td, table.doxtable th { - border: 1px solid #153788; - padding: 3px 7px 2px; -} - -table.doxtable th { - background-color: #254798; - color: #FFFFFF; - font-size: 110%; - padding-bottom: 4px; - padding-top: 5px; - text-align:left; -} - diff --git a/html/doxygen.png b/html/doxygen.png deleted file mode 100644 index f0a274bbaffdd67f6d784c894d9cf28729db0e14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1281 zcmaJ>ZA?>F7(Vx-ms?uoS`b@hdRtpo6o^%HU>M$hfGrBvQnk$LE?p^P!kn&ikhyq! zX~V@&tPF5Qt@V?oTL96Bi%aRiwbe1)9DWQI#?)=HxS7QSw`J`5fAJ*eJbB;uNuKA& zdERDo*{Y<(If(#(B$Lr#;nB(8Y#ia=ZCeW?JfPLuQY`=@cW$k}Rivq|vbxGrRq1Tl9;+(gNt?}UtVKM2`T5t1jLzuL@0UIs`S#vlhl4)^ zLgSYrPj@$+`|j?eSbXTmiHGkWxV8V}BzNR?pl9k_s4pDu9vd5a_UzZEPk)}Ad{AV_ zzddrjrh4=Imr`E06;LY{)YYt?o}L~H@7C}F^WB!Ra=v`Q0bj{>5&$66CWF>mf6vjP z2N>RRY6ZYa=K`76>+|_)Xdwko+7wv}7cN|btOhWb(*{sta~6b?S8Omrxw}!4`NhGr zZVpNqpu1@BE`QGWNTpEpcJVW5izu~2B^GlM?1(OPg)zwW;QcP@Ltcclm>XbJL9C|j z=9!2?ua=uIlf0%AndzHsRC}IyTL$EhAee(fdKB`?27KeS^2M8M_7b~PiCFO&r5LC7 z7gl1*a<8;SjNaw#h=843_AV9iZbWQOAp5YOC^&_F*9K0> zB|6%IDb?aM#3viTxkLU4aXg&@+CkNTOnQ1iMP*^?b|^lJy$4C)Zk4isV!|RZ*XhXh zw8q3$=*0LeGC!XI_Wc?dkT~3+*Gu%%yIqP+Wr3H$=&ROMQU6q}Ag^P~>c5vAEO;a- z_dK-3PPeKar%)6$j~vI2#*-YH!1h6HYVtwCX5_wM`iF#UKz&&@9Oo5w3%XGYrX zW>dY~)SG-((Yim%`InwgTvyRC?e=Wh^8KCao!R6Eg&TpVWUY1sN~4G}V?nFnEGo-; zHZ_$eW9-GnC%^WS9b z@p;-$oH#MtC0v>Q$HX%4^JdFdO$0cbv-W)Q TtK}Eh@>>I#ipmV1>S*>q-hkC} diff --git a/html/globals_func.html b/html/globals_func.html deleted file mode 100644 index 429cf31..0000000 --- a/html/globals_func.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - -iniparser: Data Fields - - - - - -
- -
-
-
-
Generated on Wed Mar 2 22:04:59 2011 for iniparser by  - -doxygen 1.6.3
- - diff --git a/html/index.html b/html/index.html deleted file mode 100644 index 92b5684..0000000 --- a/html/index.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - -iniparser: iniparser documentation - - - - - -
-

iniparser documentation

4.0

-Introduction

-

iniParser is a simple C library offering ini file parsing services. The library is pretty small (less than 1500 lines of C) and robust, and does not depend on any other external library to compile. It is written in ANSI C and should compile on most platforms without difficulty.

-

-What is an ini file?

-

An ini file is an ASCII file describing simple parameters (character strings, integers, floating-point values or booleans) in an explicit format, easy to use and modify for users.

-

An ini file is segmented into Sections, declared by the following syntax:

-
-    [Section Name]
-	

i.e. the section name enclosed in square brackets, alone on a line. Sections names are allowed to contain any character but square brackets or linefeeds.

-

In any section are zero or more variables, declared with the following syntax:

-
-    Key = value ; comment
-	

The key is any string (possibly containing blanks). The value is any character on the right side of the equal sign. Values can be given enclosed with quotes. If no quotes are present, the value is understood as containing all characters between the first and the last non-blank characters before the comment. The following declarations are identical:

-
-    Hello = "this is a long string value" ; comment
-    Hello = this is a long string value ; comment
-	

The semicolon and comment at the end of the line are optional. If there is a comment, it starts from the first character after the semicolon up to the end of the line.

-

Multi-line values can be provided by ending the line with a backslash (\).

-
-    Multiple = Line 1 \
-    Line 2 \
-    Line 3 \
-    Line 4 ; comment
-    

This would yield: "multiple" <- "Line1 Line2 Line3 Line4"

-

Comments in an ini file are:

-
    -
  • Lines starting with a hash sign
  • -
  • Blank lines (only blanks or tabs)
  • -
  • Comments given on value lines after the semicolon (if present)
  • -
-

-Compiling/installing the library

-

Edit the Makefile to indicate the C compiler you want to use, the options to provide to compile ANSI C, and possibly the options to pass to the ar program on your machine to build a library (.a) from a set of object (.o) files.

-

Defaults are set for the gcc compiler and the standard ar library builder.

-

Type 'make', that should do it.

-

To use the library in your programs, add the following line on top of your module:

-
    #include "iniparser.h"
-

And link your program with the iniparser library by adding -liniparser.a to the compile line.

-

See the file test/initest.c for an example.

-

iniparser is an ANSI C library. If you want to compile it with a C++ compiler you will likely run into compatibility issues. Headers probably have to include the extern "C" hack and function prototypes will want to add some const here and there to keep the compiler happy. This job is left to the reader as there are too many C++ compilers around, each with its own requirements as to what represents acceptable C code in a C++ environment. You have been warned.

-

-Library reference

-

The library is completely documented in its header file. On-line documentation has been generated and can be consulted here:

- -

-Using the parser

-

Comments are discarded by the parser. Then sections are identified, and in each section a new entry is created for every keyword found. The keywords are stored with the following syntax:

-
-    [Section]
-    Keyword = value ; comment
-	

is converted to the following key pair:

-
-    ("section:keyword", "value")
-	

This means that if you want to retrieve the value that was stored in the section called Pizza, in the keyword Cheese, you would make a request to the dictionary for "pizza:cheese". All section and keyword names are converted to lowercase before storage in the structure. The value side is conserved as it has been parsed, though.

-

Section names are also stored in the structure. They are stored using as key the section name, and a NULL associated value. They can be queried through iniparser_find_entry().

-

To launch the parser, use the function called iniparser_load(), which takes an input file name and returns a newly allocated dictionary structure. This latter object should remain opaque to the user and only accessed through the following accessor functions:

- -

Finally, discard this structure using iniparser_freedict().

-

All values parsed from the ini file are stored as strings. The accessors are just converting these strings to the requested type on the fly, but you could basically perform this conversion by yourself after having called the string accessor.

-

Notice that iniparser_getboolean() will return an integer (0 or 1), trying to make sense of what was found in the file. Strings starting with "y", "Y", "t", "T" or "1" are considered true values (return 1), strings starting with "n", "N", "f", "F", "0" are considered false (return 0). This allows some flexibility in handling of boolean answers.

-

If you want to add extra information into the structure that was not present in the ini file, you can use iniparser_set() to insert a string.

-

If you want to add a section to the structure, add a key with a NULL value. Example:

-
-    iniparser_set(ini, "section", NULL);
-    iniparser_set(ini, "section:key1", NULL);
-    iniparser_set(ini, "section:key2", NULL);
-    

-A word about the implementation

-

The dictionary structure is a pretty simple dictionary implementation which might find some uses in other applications. If you are curious, look into the source.

-

-Known defects

-

The dictionary structure is extremely unefficient for searching as keys are sorted in the same order as they are read from the ini file, which is convenient when dumping back to a file. The simplistic first-approach linear search implemented there can become a bottleneck if you have a very large number of keys.

-

People who need to load large amounts of data from an ini file should definitely turn to more appropriate solutions: sqlite3 or similar. There are otherwise many other dictionary implementations available on the net to replace this one.

-

-Authors

-

Nicolas Devillard (ndevilla AT free DOT fr).

-
-
Generated on Sun Jun 12 19:07:18 2016 for iniparser by  - -doxygen 1.8.11
- - diff --git a/html/iniparser_8h.html b/html/iniparser_8h.html deleted file mode 100644 index a909c4b..0000000 --- a/html/iniparser_8h.html +++ /dev/null @@ -1,583 +0,0 @@ - - - - -iniparser: iniparser.h File Reference - - - - - -
-

iniparser.h File Reference

-

Parser for ini files. -More...

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Functions

int iniparser_getnsec (dictionary *d)
 Get number of sections in a dictionary.
char * iniparser_getsecname (dictionary *d, int n)
 Get name for section n in a dictionary.
void iniparser_dump_ini (dictionary *d, FILE *f)
 Save a dictionary to a loadable ini file.
void iniparser_dump (dictionary *d, FILE *f)
 Dump a dictionary to an opened file pointer.
char * iniparser_getstring (dictionary *d, char *key, char *def)
 Get the string associated to a key.
int iniparser_getint (dictionary *d, char *key, int notfound)
 Get the string associated to a key, convert to an int.
double iniparser_getdouble (dictionary *d, char *key, double notfound)
 Get the string associated to a key, convert to a double.
int iniparser_getboolean (dictionary *d, char *key, int notfound)
 Get the string associated to a key, convert to a boolean.
int iniparser_set (dictionary *ini, char *entry, char *val)
 Set an entry in a dictionary.
void iniparser_unset (dictionary *ini, char *entry)
 Delete an entry in a dictionary.
int iniparser_find_entry (dictionary *ini, char *entry)
 Finds out if a given entry exists in a dictionary.
dictionary * iniparser_load (char *ininame)
 Parse an ini file and return an allocated dictionary object.
void iniparser_freedict (dictionary *d)
 Free all memory associated to an ini dictionary.
-

Detailed Description

-

Parser for ini files.

-
Author:
N. Devillard
-
Date:
Sep 2007
-
Version:
3.0
-

Function Documentation

- -
-
- - - - - - - - - - - - - - - - - - -
void iniparser_dump (dictionary *  d,
FILE *  f 
)
-
-
- -

Dump a dictionary to an opened file pointer.

-
Parameters:
- - - -
d Dictionary to dump.
f Opened file pointer to dump to.
-
-
-
Returns:
void
-

This function prints out the contents of a dictionary, one element by line, onto the provided file pointer. It is OK to specify stderr or stdout as output files. This function is meant for debugging purposes mostly.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
void iniparser_dump_ini (dictionary *  d,
FILE *  f 
)
-
-
- -

Save a dictionary to a loadable ini file.

-
Parameters:
- - - -
d Dictionary to dump
f Opened file pointer to dump to
-
-
-
Returns:
void
-

This function dumps a given dictionary into a loadable ini file. It is Ok to specify stderr or stdout as output files.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
int iniparser_find_entry (dictionary *  ini,
char *  entry 
)
-
-
- -

Finds out if a given entry exists in a dictionary.

-
Parameters:
- - - -
ini Dictionary to search
entry Name of the entry to look for
-
-
-
Returns:
integer 1 if entry exists, 0 otherwise
-

Finds out if a given entry exists in the dictionary. Since sections are stored as keys with NULL associated values, this is the only way of querying for the presence of sections in a dictionary.

- -
-
- -
-
- - - - - - - - - -
void iniparser_freedict (dictionary *  d ) 
-
-
- -

Free all memory associated to an ini dictionary.

-
Parameters:
- - -
d Dictionary to free
-
-
-
Returns:
void
-

Free all memory associated to an ini dictionary. It is mandatory to call this function before the dictionary object gets out of the current context.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int iniparser_getboolean (dictionary *  d,
char *  key,
int  notfound 
)
-
-
- -

Get the string associated to a key, convert to a boolean.

-
Parameters:
- - - - -
d Dictionary to search
key Key string to look for
notfound Value to return in case of error
-
-
-
Returns:
integer
-

This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned.

-

A true boolean is found if one of the following is matched:

-
    -
  • A string starting with 'y'
  • -
  • A string starting with 'Y'
  • -
  • A string starting with 't'
  • -
  • A string starting with 'T'
  • -
  • A string starting with '1'
  • -
-

A false boolean is found if one of the following is matched:

-
    -
  • A string starting with 'n'
  • -
  • A string starting with 'N'
  • -
  • A string starting with 'f'
  • -
  • A string starting with 'F'
  • -
  • A string starting with '0'
  • -
-

The notfound value returned if no boolean is identified, does not necessarily have to be 0 or 1.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
double iniparser_getdouble (dictionary *  d,
char *  key,
double  notfound 
)
-
-
- -

Get the string associated to a key, convert to a double.

-
Parameters:
- - - - -
d Dictionary to search
key Key string to look for
notfound Value to return in case of error
-
-
-
Returns:
double
-

This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int iniparser_getint (dictionary *  d,
char *  key,
int  notfound 
)
-
-
- -

Get the string associated to a key, convert to an int.

-
Parameters:
- - - - -
d Dictionary to search
key Key string to look for
notfound Value to return in case of error
-
-
-
Returns:
integer
-

This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned.

-

Supported values for integers include the usual C notation so decimal, octal (starting with 0) and hexadecimal (starting with 0x) are supported. Examples:

-
    -
  • "42" -> 42
  • -
  • "042" -> 34 (octal -> decimal)
  • -
  • "0x42" -> 66 (hexa -> decimal)
  • -
-

Warning: the conversion may overflow in various ways. Conversion is totally outsourced to strtol(), see the associated man page for overflow handling.

-

Credits: Thanks to A. Becker for suggesting strtol()

- -
-
- -
-
- - - - - - - - - -
int iniparser_getnsec (dictionary *  d ) 
-
-
- -

Get number of sections in a dictionary.

-
Parameters:
- - -
d Dictionary to examine
-
-
-
Returns:
int Number of sections found in dictionary
-

This function returns the number of sections found in a dictionary. The test to recognize sections is done on the string stored in the dictionary: a section name is given as "section" whereas a key is stored as "section:key", thus the test looks for entries that do not contain a colon.

-

This clearly fails in the case a section name contains a colon, but this should simply be avoided.

-

This function returns -1 in case of error.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
char* iniparser_getsecname (dictionary *  d,
int  n 
)
-
-
- -

Get name for section n in a dictionary.

-
Parameters:
- - - -
d Dictionary to examine
n Section number (from 0 to nsec-1).
-
-
-
Returns:
Pointer to char string
-

This function locates the n-th section in a dictionary and returns its name as a pointer to a string statically allocated inside the dictionary. Do not free or modify the returned string!

-

This function returns NULL in case of error.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
char* iniparser_getstring (dictionary *  d,
char *  key,
char *  def 
)
-
-
- -

Get the string associated to a key.

-
Parameters:
- - - - -
d Dictionary to search
key Key string to look for
def Default value to return if key not found.
-
-
-
Returns:
pointer to statically allocated character string
-

This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the pointer passed as 'def' is returned. The returned char pointer is pointing to a string allocated in the dictionary, do not free or modify it.

- -
-
- -
-
- - - - - - - - - -
dictionary* iniparser_load (char *  ininame ) 
-
-
- -

Parse an ini file and return an allocated dictionary object.

-
Parameters:
- - -
ininame Name of the ini file to read.
-
-
-
Returns:
Pointer to newly allocated dictionary
-

This is the parser for ini files. This function is called, providing the name of the file to be read. It returns a dictionary object that should not be accessed directly, but through accessor functions instead.

-

The returned dictionary must be freed using iniparser_freedict().

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int iniparser_set (dictionary *  ini,
char *  entry,
char *  val 
)
-
-
- -

Set an entry in a dictionary.

-
Parameters:
- - - - -
ini Dictionary to modify.
entry Entry to modify (entry name)
val New value to associate to the entry.
-
-
-
Returns:
int 0 if Ok, -1 otherwise.
-

If the given entry can be found in the dictionary, it is modified to contain the provided value. If it cannot be found, -1 is returned. It is Ok to set val to NULL.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
void iniparser_unset (dictionary *  ini,
char *  entry 
)
-
-
- -

Delete an entry in a dictionary.

-
Parameters:
- - - -
ini Dictionary to modify
entry Entry to delete (entry name)
-
-
-
Returns:
void
-

If the given entry can be found, it is deleted from the dictionary.

- -
-
-
-
Generated on Wed Mar 2 22:04:59 2011 for iniparser by  - -doxygen 1.6.3
- - diff --git a/html/iniparser_8main.html b/html/iniparser_8main.html deleted file mode 100644 index 3761667..0000000 --- a/html/iniparser_8main.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - -iniparser: iniparser.main File Reference - - - - - -
-

iniparser.main File Reference

-
-
-
Generated on Wed Mar 2 22:04:59 2011 for iniparser by  - -doxygen 1.6.3
- - diff --git a/html/tab_b.gif b/html/tab_b.gif deleted file mode 100644 index 0d623483ffdf5f9f96900108042a7ab0643fe2a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35 ncmZ?wbhEHbWMp7uXkcJy*>IeJfk6j|fqX^=1|}vKMh0sDa2W*H diff --git a/html/tab_l.gif b/html/tab_l.gif deleted file mode 100644 index 9b1e6337c9299a700401a2a78a2c6ffced475216..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 706 zcmZ?wbhEHbZT`}F1e&(Gg}Y(8=I;HA5#Z$3JI=gGB)FQ#odI(O&E^@q;x zK6mr*m3xOS-#u~t!I@i+u0DKm^U160k6t`|^WpV}&n+8{U%dD9&a>B#U%!9-@yol< zU%&tQ{rk_K|NsC0`}dE5ET99@1@a36+kb~?0UJ*yc&I3X_m z!ND^5$O7$#8OFRuDhG}!?8z?cdZK&!`PWjdR;Aj^wZ` zeK{IEYHBJ)6K8VIp1`BVt++swf6j+=L{p1*nO(VhE`pFexG@5$|>uaCcd z`0m=9m+yak{QmXN#Sc$^{$X9h9&q2jiKAI|&T)a;PPx2K9p`YIdw8HtR5k2Q$2-O2 z*;3y{MQ-RnJTgJfI&R5|O)AHxDf_00XbPvDZPy4t=hHd)nfLPvms&O`Ok(sD()5v$ z5U@&h;a=#xbxVbo2~X&Xj0Ie(f{v>vERH+qC+nTG=B8Nca=wU-O$?1&vUgV~9=!H; zx>3p9Yn%*<>t~sk+&0xfyS8RsPfYBd<~wWK%j-LmpU>O7yX^h#UCp1x-p#i7@bE;py8XI6 zmY<)m>~)W~yIWcMVoiPg{duuf<*)9qZ9l$m*Ph&W&$jlv*Vpa+{pH@n=IQ$L?0$ax ec60Ul|8o2P|NVbd{6P)#weSbE3}s?04AuZvx_~SI diff --git a/html/tab_r.gif b/html/tab_r.gif deleted file mode 100644 index ce9dd9f533cb5486d6941844f442b59d4a9e9175..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2585 zcmbV}`9Bkk1ILFF--w5zJc=ZZT(zjE=;2|_S)Qm~rCWz1Pc)KPl;jv%A#&v2*x}yc zmf2~Jm~&=xjJY?PqwIN}f8qQ2{r$uH{c*nJbmr{cR5??*egHrs-B=MzCF`3%e{FAW z{oL5xTHn~5TM{jaB;@|_Ue5F&Zb@p(kMyG{*;gWDg zyeL|eZf7Qd8=#bXzSiR{yzRgLSj-fJS8>lBjVHN z^o-0eS=nE6a`W;LChBs=`+QAJP~{b93>H^eRb5kCSC1zUNezun%`L5M?RDzv#%jk7 zYVRX=vATPD`+oEfum^{RM@GjuP?-r=yh0!p;Vx^T9G7~`7%5ydH%70=jyJ;;`d;hv92x3R=z{xp+Lg2!*@OK*K15-t&okoPtSED)h&$RLxdbA zseWm^C3d%-yRNi-ryk^!ek+C`n&~cd$#ZWct_cUL{l~i+Nzx^5d!n94(>bW-iL~Rl z&8r)?q|1DIo=0=judQ{FaGcfLERz8gfn3-Qt<2lksh{mzpT}DXxUuR^z=^key&q4! z+wWI45vL0k$R^(F#{qfqhUsN@WA+w-V?LPH33!Q?WFSB3)WBojE@hK41Nb?KfS+Qo zXgrzfsP$wr4Qzy*{OD>uJBjdgGM@VMml5)2f~_}lD*YyOb}Hjeobhz#4c`w(l^>KK zr?Ud;W~Z}*w;%hZ|2^p^+f06gJDJQD zeIhGADbDmm&6arh(q>EZ<7mjzg7l|z$hRL8=1>)Nv=S7CY$B}iYJ&*T_-T_OG*L1q ztZ3Lana33?y3AKnyq^YCF|4x%Rb5WU&2qcl{TFKey%QJeMxn^SdT!hZ5+0i1zeusiYVp-phBl7b5+Px-X&LhByq z0F&<;K0l2+v>qiHlXb#$jXMv$uK-dEGE9L~qtdU(XeRXmvu*K2Q&6!fD**JxYP4b4BR7FdJ$Qx9G9`J%-_X!a#LGpp3g9)VWytGCa;7`S1_e8F~!R+aSJ zOF17p2`H?2kPs8Q`_;U}+D%3p zs2-0BTqFwpUoBk`?P;iPQ(IbEA|JmMx!P&YYG|R@S=5Mnw;-?A6rEEVyV%d7{iU4a zNk`i!%F(Ykpm`}#oH;BjY->@b8vQedv;pza2FL&*6ufjd+*3Ute&>kes~TU?^KkojsTh(o~(3tk1Y6>4(yn( z#U*ID9@eg-beKo1B;HXe+}{Z%n@7m0+yxivuqk9~;!1LGQlah)xYK4>wgL}l6dsaN zIxlRlq`*`j9PG4*0hD6YV_b_2w5b#)o7J?`q#{GjvvKlD`T*dWcZx<-s(ZvLB44E# z=!|sw!?)@%y$oRNL#25WS3lzdii}TuQ3?CLnvQ1_n};2sT_;Y;#d3=+-(O% zMN$>O!3;ke(UuLR%h_&)N zs^!-@A>QR}4yB1bPp`9S19ikTbZ~O{&FF-yHK{En;mmShDUIEw03`j(DBIsM}Rjki2J#SQa3gFZTKBPDeIiLt9Z z%bL3(B@Qw%(B`wSMS~dPh$=R`(}lBoFXKy(s|*{#ru$wjsBc_O#zxNk9w+UUHmx(U zmJ8+M+ndtnZ<7|VU9Mbt61zpo9T&3%Wx&XII=#QJxjR`CZf22ac3d51Z?GD%LEe_&*t46Qf;4`bZ7p2K(Ab5>GfT^}4! zBT&HZD`^PEgWoI&{~o-ID0F?O`75sm(87x%A{(}Ch1)QlzdJ)1B-eqe5a(weg0`4lQIf1evjvbBY50DVbzO7CLf|vP z2#0(U-|jZ`H{y5N^o7%iK6H>_HEGN->U6^!)1{XpJV!!4(Ig7wzZQ*9WYF4X1rG0x z=1uA@i`rIAciubDC{;~b(|&|A@xkjRP5aRcvRU9tvIm}jDB6J eQ0-6-y)mpwdT=ayS0tBxKDA*~;EWmo diff --git a/html/tabs.css b/html/tabs.css deleted file mode 100644 index a444163..0000000 --- a/html/tabs.css +++ /dev/null @@ -1,105 +0,0 @@ -/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */ - -DIV.tabs -{ - float : left; - width : 100%; - background : url("tab_b.gif") repeat-x bottom; - margin-bottom : 4px; -} - -DIV.tabs UL -{ - margin : 0px; - padding-left : 10px; - list-style : none; -} - -DIV.tabs LI, DIV.tabs FORM -{ - display : inline; - margin : 0px; - padding : 0px; -} - -DIV.tabs FORM -{ - float : right; -} - -DIV.tabs A -{ - float : left; - background : url("tab_r.gif") no-repeat right top; - border-bottom : 1px solid #84B0C7; - font-size : 80%; - font-weight : bold; - text-decoration : none; -} - -DIV.tabs A:hover -{ - background-position: 100% -150px; -} - -DIV.tabs A:link, DIV.tabs A:visited, -DIV.tabs A:active, DIV.tabs A:hover -{ - color: #1A419D; -} - -DIV.tabs SPAN -{ - float : left; - display : block; - background : url("tab_l.gif") no-repeat left top; - padding : 5px 9px; - white-space : nowrap; -} - -DIV.tabs #MSearchBox -{ - float : right; - display : inline; - font-size : 1em; -} - -DIV.tabs TD -{ - font-size : 80%; - font-weight : bold; - text-decoration : none; -} - - - -/* Commented Backslash Hack hides rule from IE5-Mac \*/ -DIV.tabs SPAN {float : none;} -/* End IE5-Mac hack */ - -DIV.tabs A:hover SPAN -{ - background-position: 0% -150px; -} - -DIV.tabs LI.current A -{ - background-position: 100% -150px; - border-width : 0px; -} - -DIV.tabs LI.current SPAN -{ - background-position: 0% -150px; - padding-bottom : 6px; -} - -DIV.navpath -{ - background : none; - border : none; - border-bottom : 1px solid #84B0C7; - text-align : center; - margin : 2px; - padding : 2px; -} diff --git a/test/test_iniparser.c b/test/test_iniparser.c index b7cd5fc..7429fed 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -696,3 +696,31 @@ void Test_iniparser_error_callback(CuTest *tc) CuAssertPtrEquals(tc, NULL, dic); CuAssertStrEquals(tc, "", _last_error); } +void Test_iniparser_find_entry(CuTest *tc) +{ + dictionary *dic; + int i; + /* NULL test */ + CuAssertIntEquals(tc, 0, iniparser_find_entry(NULL, NULL)); + CuAssertIntEquals(tc, 0, iniparser_find_entry(NULL, "dummy")); + + /* Empty dictionary test*/ + dic = dictionary_new(10); + CuAssertPtrNotNull(tc, dic); + CuAssertIntEquals(tc, 0, iniparser_find_entry(dic, NULL)); + CuAssertIntEquals(tc, 0, iniparser_find_entry(dic, "dummy")); + dictionary_del(dic); + + /*Regular dictionary */ + dic = generate_dictionary(1, 8); + CuAssertPtrNotNull(tc, dic); + for (i = 1; i < 8; i++) + { + CuAssertIntEquals(tc, 1, iniparser_find_entry(dic, dic->key[i])); + } + CuAssertIntEquals(tc, 0, iniparser_find_entry(dic, "dummy")); + + iniparser_freedict(dic); +} + + From c62750fee242ca18e087646dda1aedf9f750e0cb Mon Sep 17 00:00:00 2001 From: chenguoping Date: Mon, 2 Sep 2019 11:51:45 +0800 Subject: [PATCH 06/42] add NULL check in dictionary_get --- html/doxygen.css | 545 ----------------------------------- html/doxygen.png | Bin 1281 -> 0 bytes html/globals_func.html | 64 ----- html/index.html | 101 ------- html/iniparser_8h.html | 583 -------------------------------------- html/iniparser_8main.html | 19 -- html/tab_b.gif | Bin 35 -> 0 bytes html/tab_l.gif | Bin 706 -> 0 bytes html/tab_r.gif | Bin 2585 -> 0 bytes html/tabs.css | 105 ------- src/dictionary.c | 3 +- test/test_dictionary.c | 49 ++++ 12 files changed, 51 insertions(+), 1418 deletions(-) delete mode 100644 html/doxygen.css delete mode 100644 html/doxygen.png delete mode 100644 html/globals_func.html delete mode 100644 html/index.html delete mode 100644 html/iniparser_8h.html delete mode 100644 html/iniparser_8main.html delete mode 100644 html/tab_b.gif delete mode 100644 html/tab_l.gif delete mode 100644 html/tab_r.gif delete mode 100644 html/tabs.css diff --git a/html/doxygen.css b/html/doxygen.css deleted file mode 100644 index d6aaf28..0000000 --- a/html/doxygen.css +++ /dev/null @@ -1,545 +0,0 @@ -/* The standard CSS for doxygen */ - -body, table, div, p, dl { - font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; - font-size: 12px; -} - -/* @group Heading Levels */ - -h1 { - text-align: center; - font-size: 150%; -} - -h2 { - font-size: 120%; -} - -h3 { - font-size: 100%; -} - -dt { - font-weight: bold; -} - -div.multicol { - -moz-column-gap: 1em; - -webkit-column-gap: 1em; - -moz-column-count: 3; - -webkit-column-count: 3; -} - -p.startli, p.startdd, p.starttd { - margin-top: 2px; -} - -p.endli { - margin-bottom: 0px; -} - -p.enddd { - margin-bottom: 4px; -} - -p.endtd { - margin-bottom: 2px; -} - -/* @end */ - -caption { - font-weight: bold; -} - -span.legend { - font-size: 70%; - text-align: center; -} - -h3.version { - font-size: 90%; - text-align: center; -} - -div.qindex, div.navtab{ - background-color: #e8eef2; - border: 1px solid #84b0c7; - text-align: center; - margin: 2px; - padding: 2px; -} - -div.qindex, div.navpath { - width: 100%; - line-height: 140%; -} - -div.navtab { - margin-right: 15px; -} - -/* @group Link Styling */ - -a { - color: #153788; - font-weight: normal; - text-decoration: none; -} - -.contents a:visited { - color: #1b77c5; -} - -a:hover { - text-decoration: underline; -} - -a.qindex { - font-weight: bold; -} - -a.qindexHL { - font-weight: bold; - background-color: #6666cc; - color: #ffffff; - border: 1px double #9295C2; -} - -.contents a.qindexHL:visited { - color: #ffffff; -} - -a.el { - font-weight: bold; -} - -a.elRef { -} - -a.code { - color: #3030f0; -} - -a.codeRef { - color: #3030f0; -} - -/* @end */ - -dl.el { - margin-left: -1cm; -} - -.fragment { - font-family: monospace, fixed; - font-size: 105%; -} - -pre.fragment { - border: 1px solid #CCCCCC; - background-color: #f5f5f5; - padding: 4px 6px; - margin: 4px 8px 4px 2px; - overflow: auto; - word-wrap: break-word; - font-size: 9pt; - line-height: 125%; -} - -div.ah { - background-color: black; - font-weight: bold; - color: #ffffff; - margin-bottom: 3px; - margin-top: 3px -} - -div.groupHeader { - margin-left: 16px; - margin-top: 12px; - margin-bottom: 6px; - font-weight: bold; -} - -div.groupText { - margin-left: 16px; - font-style: italic; -} - -body { - background: white; - color: black; - margin-right: 20px; - margin-left: 20px; -} - -td.indexkey { - background-color: #e8eef2; - font-weight: bold; - border: 1px solid #CCCCCC; - margin: 2px 0px 2px 0; - padding: 2px 10px; -} - -td.indexvalue { - background-color: #e8eef2; - border: 1px solid #CCCCCC; - padding: 2px 10px; - margin: 2px 0px; -} - -tr.memlist { - background-color: #f0f0f0; -} - -p.formulaDsp { - text-align: center; -} - -img.formulaDsp { - -} - -img.formulaInl { - vertical-align: middle; -} - -div.center { - text-align: center; - margin-top: 0px; - margin-bottom: 0px; - padding: 0px; -} - -div.center img { - border: 0px; -} - -img.footer { - border: 0px; - vertical-align: middle; -} - -/* @group Code Colorization */ - -span.keyword { - color: #008000 -} - -span.keywordtype { - color: #604020 -} - -span.keywordflow { - color: #e08000 -} - -span.comment { - color: #800000 -} - -span.preprocessor { - color: #806020 -} - -span.stringliteral { - color: #002080 -} - -span.charliteral { - color: #008080 -} - -span.vhdldigit { - color: #ff00ff -} - -span.vhdlchar { - color: #000000 -} - -span.vhdlkeyword { - color: #700070 -} - -span.vhdllogic { - color: #ff0000 -} - -/* @end */ - -.search { - color: #003399; - font-weight: bold; -} - -form.search { - margin-bottom: 0px; - margin-top: 0px; -} - -input.search { - font-size: 75%; - color: #000080; - font-weight: normal; - background-color: #e8eef2; -} - -td.tiny { - font-size: 75%; -} - -.dirtab { - padding: 4px; - border-collapse: collapse; - border: 1px solid #84b0c7; -} - -th.dirtab { - background: #e8eef2; - font-weight: bold; -} - -hr { - height: 0px; - border: none; - border-top: 1px solid #666; -} - -hr.footer { - height: 1px; -} - -/* @group Member Descriptions */ - -.mdescLeft, .mdescRight, -.memItemLeft, .memItemRight, -.memTemplItemLeft, .memTemplItemRight, .memTemplParams { - background-color: #FAFAFA; - border: none; - margin: 4px; - padding: 1px 0 0 8px; -} - -.mdescLeft, .mdescRight { - padding: 0px 8px 4px 8px; - color: #555; -} - -.memItemLeft, .memItemRight, .memTemplParams { - border-top: 1px solid #ccc; -} - -.memItemLeft, .memTemplItemLeft { - white-space: nowrap; -} - -.memTemplParams { - color: #606060; - white-space: nowrap; -} - -/* @end */ - -/* @group Member Details */ - -/* Styles for detailed member documentation */ - -.memtemplate { - font-size: 80%; - color: #606060; - font-weight: normal; - margin-left: 3px; -} - -.memnav { - background-color: #e8eef2; - border: 1px solid #84b0c7; - text-align: center; - margin: 2px; - margin-right: 15px; - padding: 2px; -} - -.memitem { - padding: 0; - margin-bottom: 10px; -} - -.memname { - white-space: nowrap; - font-weight: bold; - margin-left: 6px; -} - -.memproto { - border-top: 1px solid #84b0c7; - border-left: 1px solid #84b0c7; - border-right: 1px solid #84b0c7; - padding: 0; - background-color: #d5e1e8; - font-weight: bold; - /* firefox specific markup */ - background-image: -moz-linear-gradient(rgba(228, 233, 245, 1.0) 0%, rgba(193, 205, 232, 1.0) 100%); - -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; - -moz-border-radius-topright: 8px; - -moz-border-radius-topleft: 8px; - /* webkit specific markup */ - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(228, 233, 245, 1.0)), to(rgba(193, 205, 232, 1.0))); - -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); - -webkit-border-top-right-radius: 8px; - -webkit-border-top-left-radius: 8px; - -} - -.memdoc { - border-bottom: 1px solid #84b0c7; - border-left: 1px solid #84b0c7; - border-right: 1px solid #84b0c7; - padding: 2px 5px; - background-color: #eef3f5; - border-top-width: 0; - /* firefox specific markup */ - -moz-border-radius-bottomleft: 8px; - -moz-border-radius-bottomright: 8px; - -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; - /* webkit specific markup */ - -webkit-border-bottom-left-radius: 8px; - -webkit-border-bottom-right-radius: 8px; - -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); -} - -.paramkey { - text-align: right; -} - -.paramtype { - white-space: nowrap; -} - -.paramname { - color: #602020; - white-space: nowrap; -} -.paramname em { - font-style: normal; -} - -/* @end */ - -/* @group Directory (tree) */ - -/* for the tree view */ - -.ftvtree { - font-family: sans-serif; - margin: 0.5em; -} - -/* these are for tree view when used as main index */ - -.directory { - font-size: 9pt; - font-weight: bold; -} - -.directory h3 { - margin: 0px; - margin-top: 1em; - font-size: 11pt; -} - -/* -The following two styles can be used to replace the root node title -with an image of your choice. Simply uncomment the next two styles, -specify the name of your image and be sure to set 'height' to the -proper pixel height of your image. -*/ - -/* -.directory h3.swap { - height: 61px; - background-repeat: no-repeat; - background-image: url("yourimage.gif"); -} -.directory h3.swap span { - display: none; -} -*/ - -.directory > h3 { - margin-top: 0; -} - -.directory p { - margin: 0px; - white-space: nowrap; -} - -.directory div { - display: none; - margin: 0px; -} - -.directory img { - vertical-align: -30%; -} - -/* these are for tree view when not used as main index */ - -.directory-alt { - font-size: 100%; - font-weight: bold; -} - -.directory-alt h3 { - margin: 0px; - margin-top: 1em; - font-size: 11pt; -} - -.directory-alt > h3 { - margin-top: 0; -} - -.directory-alt p { - margin: 0px; - white-space: nowrap; -} - -.directory-alt div { - display: none; - margin: 0px; -} - -.directory-alt img { - vertical-align: -30%; -} - -/* @end */ - -address { - font-style: normal; - color: #333; -} - -table.doxtable { - border-collapse:collapse; -} - -table.doxtable td, table.doxtable th { - border: 1px solid #153788; - padding: 3px 7px 2px; -} - -table.doxtable th { - background-color: #254798; - color: #FFFFFF; - font-size: 110%; - padding-bottom: 4px; - padding-top: 5px; - text-align:left; -} - diff --git a/html/doxygen.png b/html/doxygen.png deleted file mode 100644 index f0a274bbaffdd67f6d784c894d9cf28729db0e14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1281 zcmaJ>ZA?>F7(Vx-ms?uoS`b@hdRtpo6o^%HU>M$hfGrBvQnk$LE?p^P!kn&ikhyq! zX~V@&tPF5Qt@V?oTL96Bi%aRiwbe1)9DWQI#?)=HxS7QSw`J`5fAJ*eJbB;uNuKA& zdERDo*{Y<(If(#(B$Lr#;nB(8Y#ia=ZCeW?JfPLuQY`=@cW$k}Rivq|vbxGrRq1Tl9;+(gNt?}UtVKM2`T5t1jLzuL@0UIs`S#vlhl4)^ zLgSYrPj@$+`|j?eSbXTmiHGkWxV8V}BzNR?pl9k_s4pDu9vd5a_UzZEPk)}Ad{AV_ zzddrjrh4=Imr`E06;LY{)YYt?o}L~H@7C}F^WB!Ra=v`Q0bj{>5&$66CWF>mf6vjP z2N>RRY6ZYa=K`76>+|_)Xdwko+7wv}7cN|btOhWb(*{sta~6b?S8Omrxw}!4`NhGr zZVpNqpu1@BE`QGWNTpEpcJVW5izu~2B^GlM?1(OPg)zwW;QcP@Ltcclm>XbJL9C|j z=9!2?ua=uIlf0%AndzHsRC}IyTL$EhAee(fdKB`?27KeS^2M8M_7b~PiCFO&r5LC7 z7gl1*a<8;SjNaw#h=843_AV9iZbWQOAp5YOC^&_F*9K0> zB|6%IDb?aM#3viTxkLU4aXg&@+CkNTOnQ1iMP*^?b|^lJy$4C)Zk4isV!|RZ*XhXh zw8q3$=*0LeGC!XI_Wc?dkT~3+*Gu%%yIqP+Wr3H$=&ROMQU6q}Ag^P~>c5vAEO;a- z_dK-3PPeKar%)6$j~vI2#*-YH!1h6HYVtwCX5_wM`iF#UKz&&@9Oo5w3%XGYrX zW>dY~)SG-((Yim%`InwgTvyRC?e=Wh^8KCao!R6Eg&TpVWUY1sN~4G}V?nFnEGo-; zHZ_$eW9-GnC%^WS9b z@p;-$oH#MtC0v>Q$HX%4^JdFdO$0cbv-W)Q TtK}Eh@>>I#ipmV1>S*>q-hkC} diff --git a/html/globals_func.html b/html/globals_func.html deleted file mode 100644 index 429cf31..0000000 --- a/html/globals_func.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - -iniparser: Data Fields - - - - - -
- -
-
-
-
Generated on Wed Mar 2 22:04:59 2011 for iniparser by  - -doxygen 1.6.3
- - diff --git a/html/index.html b/html/index.html deleted file mode 100644 index 92b5684..0000000 --- a/html/index.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - -iniparser: iniparser documentation - - - - - -
-

iniparser documentation

4.0

-Introduction

-

iniParser is a simple C library offering ini file parsing services. The library is pretty small (less than 1500 lines of C) and robust, and does not depend on any other external library to compile. It is written in ANSI C and should compile on most platforms without difficulty.

-

-What is an ini file?

-

An ini file is an ASCII file describing simple parameters (character strings, integers, floating-point values or booleans) in an explicit format, easy to use and modify for users.

-

An ini file is segmented into Sections, declared by the following syntax:

-
-    [Section Name]
-	

i.e. the section name enclosed in square brackets, alone on a line. Sections names are allowed to contain any character but square brackets or linefeeds.

-

In any section are zero or more variables, declared with the following syntax:

-
-    Key = value ; comment
-	

The key is any string (possibly containing blanks). The value is any character on the right side of the equal sign. Values can be given enclosed with quotes. If no quotes are present, the value is understood as containing all characters between the first and the last non-blank characters before the comment. The following declarations are identical:

-
-    Hello = "this is a long string value" ; comment
-    Hello = this is a long string value ; comment
-	

The semicolon and comment at the end of the line are optional. If there is a comment, it starts from the first character after the semicolon up to the end of the line.

-

Multi-line values can be provided by ending the line with a backslash (\).

-
-    Multiple = Line 1 \
-    Line 2 \
-    Line 3 \
-    Line 4 ; comment
-    

This would yield: "multiple" <- "Line1 Line2 Line3 Line4"

-

Comments in an ini file are:

-
    -
  • Lines starting with a hash sign
  • -
  • Blank lines (only blanks or tabs)
  • -
  • Comments given on value lines after the semicolon (if present)
  • -
-

-Compiling/installing the library

-

Edit the Makefile to indicate the C compiler you want to use, the options to provide to compile ANSI C, and possibly the options to pass to the ar program on your machine to build a library (.a) from a set of object (.o) files.

-

Defaults are set for the gcc compiler and the standard ar library builder.

-

Type 'make', that should do it.

-

To use the library in your programs, add the following line on top of your module:

-
    #include "iniparser.h"
-

And link your program with the iniparser library by adding -liniparser.a to the compile line.

-

See the file test/initest.c for an example.

-

iniparser is an ANSI C library. If you want to compile it with a C++ compiler you will likely run into compatibility issues. Headers probably have to include the extern "C" hack and function prototypes will want to add some const here and there to keep the compiler happy. This job is left to the reader as there are too many C++ compilers around, each with its own requirements as to what represents acceptable C code in a C++ environment. You have been warned.

-

-Library reference

-

The library is completely documented in its header file. On-line documentation has been generated and can be consulted here:

- -

-Using the parser

-

Comments are discarded by the parser. Then sections are identified, and in each section a new entry is created for every keyword found. The keywords are stored with the following syntax:

-
-    [Section]
-    Keyword = value ; comment
-	

is converted to the following key pair:

-
-    ("section:keyword", "value")
-	

This means that if you want to retrieve the value that was stored in the section called Pizza, in the keyword Cheese, you would make a request to the dictionary for "pizza:cheese". All section and keyword names are converted to lowercase before storage in the structure. The value side is conserved as it has been parsed, though.

-

Section names are also stored in the structure. They are stored using as key the section name, and a NULL associated value. They can be queried through iniparser_find_entry().

-

To launch the parser, use the function called iniparser_load(), which takes an input file name and returns a newly allocated dictionary structure. This latter object should remain opaque to the user and only accessed through the following accessor functions:

- -

Finally, discard this structure using iniparser_freedict().

-

All values parsed from the ini file are stored as strings. The accessors are just converting these strings to the requested type on the fly, but you could basically perform this conversion by yourself after having called the string accessor.

-

Notice that iniparser_getboolean() will return an integer (0 or 1), trying to make sense of what was found in the file. Strings starting with "y", "Y", "t", "T" or "1" are considered true values (return 1), strings starting with "n", "N", "f", "F", "0" are considered false (return 0). This allows some flexibility in handling of boolean answers.

-

If you want to add extra information into the structure that was not present in the ini file, you can use iniparser_set() to insert a string.

-

If you want to add a section to the structure, add a key with a NULL value. Example:

-
-    iniparser_set(ini, "section", NULL);
-    iniparser_set(ini, "section:key1", NULL);
-    iniparser_set(ini, "section:key2", NULL);
-    

-A word about the implementation

-

The dictionary structure is a pretty simple dictionary implementation which might find some uses in other applications. If you are curious, look into the source.

-

-Known defects

-

The dictionary structure is extremely unefficient for searching as keys are sorted in the same order as they are read from the ini file, which is convenient when dumping back to a file. The simplistic first-approach linear search implemented there can become a bottleneck if you have a very large number of keys.

-

People who need to load large amounts of data from an ini file should definitely turn to more appropriate solutions: sqlite3 or similar. There are otherwise many other dictionary implementations available on the net to replace this one.

-

-Authors

-

Nicolas Devillard (ndevilla AT free DOT fr).

-
-
Generated on Sun Jun 12 19:07:18 2016 for iniparser by  - -doxygen 1.8.11
- - diff --git a/html/iniparser_8h.html b/html/iniparser_8h.html deleted file mode 100644 index a909c4b..0000000 --- a/html/iniparser_8h.html +++ /dev/null @@ -1,583 +0,0 @@ - - - - -iniparser: iniparser.h File Reference - - - - - -
-

iniparser.h File Reference

-

Parser for ini files. -More...

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Functions

int iniparser_getnsec (dictionary *d)
 Get number of sections in a dictionary.
char * iniparser_getsecname (dictionary *d, int n)
 Get name for section n in a dictionary.
void iniparser_dump_ini (dictionary *d, FILE *f)
 Save a dictionary to a loadable ini file.
void iniparser_dump (dictionary *d, FILE *f)
 Dump a dictionary to an opened file pointer.
char * iniparser_getstring (dictionary *d, char *key, char *def)
 Get the string associated to a key.
int iniparser_getint (dictionary *d, char *key, int notfound)
 Get the string associated to a key, convert to an int.
double iniparser_getdouble (dictionary *d, char *key, double notfound)
 Get the string associated to a key, convert to a double.
int iniparser_getboolean (dictionary *d, char *key, int notfound)
 Get the string associated to a key, convert to a boolean.
int iniparser_set (dictionary *ini, char *entry, char *val)
 Set an entry in a dictionary.
void iniparser_unset (dictionary *ini, char *entry)
 Delete an entry in a dictionary.
int iniparser_find_entry (dictionary *ini, char *entry)
 Finds out if a given entry exists in a dictionary.
dictionary * iniparser_load (char *ininame)
 Parse an ini file and return an allocated dictionary object.
void iniparser_freedict (dictionary *d)
 Free all memory associated to an ini dictionary.
-

Detailed Description

-

Parser for ini files.

-
Author:
N. Devillard
-
Date:
Sep 2007
-
Version:
3.0
-

Function Documentation

- -
-
- - - - - - - - - - - - - - - - - - -
void iniparser_dump (dictionary *  d,
FILE *  f 
)
-
-
- -

Dump a dictionary to an opened file pointer.

-
Parameters:
- - - -
d Dictionary to dump.
f Opened file pointer to dump to.
-
-
-
Returns:
void
-

This function prints out the contents of a dictionary, one element by line, onto the provided file pointer. It is OK to specify stderr or stdout as output files. This function is meant for debugging purposes mostly.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
void iniparser_dump_ini (dictionary *  d,
FILE *  f 
)
-
-
- -

Save a dictionary to a loadable ini file.

-
Parameters:
- - - -
d Dictionary to dump
f Opened file pointer to dump to
-
-
-
Returns:
void
-

This function dumps a given dictionary into a loadable ini file. It is Ok to specify stderr or stdout as output files.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
int iniparser_find_entry (dictionary *  ini,
char *  entry 
)
-
-
- -

Finds out if a given entry exists in a dictionary.

-
Parameters:
- - - -
ini Dictionary to search
entry Name of the entry to look for
-
-
-
Returns:
integer 1 if entry exists, 0 otherwise
-

Finds out if a given entry exists in the dictionary. Since sections are stored as keys with NULL associated values, this is the only way of querying for the presence of sections in a dictionary.

- -
-
- -
-
- - - - - - - - - -
void iniparser_freedict (dictionary *  d ) 
-
-
- -

Free all memory associated to an ini dictionary.

-
Parameters:
- - -
d Dictionary to free
-
-
-
Returns:
void
-

Free all memory associated to an ini dictionary. It is mandatory to call this function before the dictionary object gets out of the current context.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int iniparser_getboolean (dictionary *  d,
char *  key,
int  notfound 
)
-
-
- -

Get the string associated to a key, convert to a boolean.

-
Parameters:
- - - - -
d Dictionary to search
key Key string to look for
notfound Value to return in case of error
-
-
-
Returns:
integer
-

This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned.

-

A true boolean is found if one of the following is matched:

-
    -
  • A string starting with 'y'
  • -
  • A string starting with 'Y'
  • -
  • A string starting with 't'
  • -
  • A string starting with 'T'
  • -
  • A string starting with '1'
  • -
-

A false boolean is found if one of the following is matched:

-
    -
  • A string starting with 'n'
  • -
  • A string starting with 'N'
  • -
  • A string starting with 'f'
  • -
  • A string starting with 'F'
  • -
  • A string starting with '0'
  • -
-

The notfound value returned if no boolean is identified, does not necessarily have to be 0 or 1.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
double iniparser_getdouble (dictionary *  d,
char *  key,
double  notfound 
)
-
-
- -

Get the string associated to a key, convert to a double.

-
Parameters:
- - - - -
d Dictionary to search
key Key string to look for
notfound Value to return in case of error
-
-
-
Returns:
double
-

This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int iniparser_getint (dictionary *  d,
char *  key,
int  notfound 
)
-
-
- -

Get the string associated to a key, convert to an int.

-
Parameters:
- - - - -
d Dictionary to search
key Key string to look for
notfound Value to return in case of error
-
-
-
Returns:
integer
-

This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the notfound value is returned.

-

Supported values for integers include the usual C notation so decimal, octal (starting with 0) and hexadecimal (starting with 0x) are supported. Examples:

-
    -
  • "42" -> 42
  • -
  • "042" -> 34 (octal -> decimal)
  • -
  • "0x42" -> 66 (hexa -> decimal)
  • -
-

Warning: the conversion may overflow in various ways. Conversion is totally outsourced to strtol(), see the associated man page for overflow handling.

-

Credits: Thanks to A. Becker for suggesting strtol()

- -
-
- -
-
- - - - - - - - - -
int iniparser_getnsec (dictionary *  d ) 
-
-
- -

Get number of sections in a dictionary.

-
Parameters:
- - -
d Dictionary to examine
-
-
-
Returns:
int Number of sections found in dictionary
-

This function returns the number of sections found in a dictionary. The test to recognize sections is done on the string stored in the dictionary: a section name is given as "section" whereas a key is stored as "section:key", thus the test looks for entries that do not contain a colon.

-

This clearly fails in the case a section name contains a colon, but this should simply be avoided.

-

This function returns -1 in case of error.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
char* iniparser_getsecname (dictionary *  d,
int  n 
)
-
-
- -

Get name for section n in a dictionary.

-
Parameters:
- - - -
d Dictionary to examine
n Section number (from 0 to nsec-1).
-
-
-
Returns:
Pointer to char string
-

This function locates the n-th section in a dictionary and returns its name as a pointer to a string statically allocated inside the dictionary. Do not free or modify the returned string!

-

This function returns NULL in case of error.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
char* iniparser_getstring (dictionary *  d,
char *  key,
char *  def 
)
-
-
- -

Get the string associated to a key.

-
Parameters:
- - - - -
d Dictionary to search
key Key string to look for
def Default value to return if key not found.
-
-
-
Returns:
pointer to statically allocated character string
-

This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, the pointer passed as 'def' is returned. The returned char pointer is pointing to a string allocated in the dictionary, do not free or modify it.

- -
-
- -
-
- - - - - - - - - -
dictionary* iniparser_load (char *  ininame ) 
-
-
- -

Parse an ini file and return an allocated dictionary object.

-
Parameters:
- - -
ininame Name of the ini file to read.
-
-
-
Returns:
Pointer to newly allocated dictionary
-

This is the parser for ini files. This function is called, providing the name of the file to be read. It returns a dictionary object that should not be accessed directly, but through accessor functions instead.

-

The returned dictionary must be freed using iniparser_freedict().

- -
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - -
int iniparser_set (dictionary *  ini,
char *  entry,
char *  val 
)
-
-
- -

Set an entry in a dictionary.

-
Parameters:
- - - - -
ini Dictionary to modify.
entry Entry to modify (entry name)
val New value to associate to the entry.
-
-
-
Returns:
int 0 if Ok, -1 otherwise.
-

If the given entry can be found in the dictionary, it is modified to contain the provided value. If it cannot be found, -1 is returned. It is Ok to set val to NULL.

- -
-
- -
-
- - - - - - - - - - - - - - - - - - -
void iniparser_unset (dictionary *  ini,
char *  entry 
)
-
-
- -

Delete an entry in a dictionary.

-
Parameters:
- - - -
ini Dictionary to modify
entry Entry to delete (entry name)
-
-
-
Returns:
void
-

If the given entry can be found, it is deleted from the dictionary.

- -
-
-
-
Generated on Wed Mar 2 22:04:59 2011 for iniparser by  - -doxygen 1.6.3
- - diff --git a/html/iniparser_8main.html b/html/iniparser_8main.html deleted file mode 100644 index 3761667..0000000 --- a/html/iniparser_8main.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - -iniparser: iniparser.main File Reference - - - - - -
-

iniparser.main File Reference

-
-
-
Generated on Wed Mar 2 22:04:59 2011 for iniparser by  - -doxygen 1.6.3
- - diff --git a/html/tab_b.gif b/html/tab_b.gif deleted file mode 100644 index 0d623483ffdf5f9f96900108042a7ab0643fe2a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35 ncmZ?wbhEHbWMp7uXkcJy*>IeJfk6j|fqX^=1|}vKMh0sDa2W*H diff --git a/html/tab_l.gif b/html/tab_l.gif deleted file mode 100644 index 9b1e6337c9299a700401a2a78a2c6ffced475216..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 706 zcmZ?wbhEHbZT`}F1e&(Gg}Y(8=I;HA5#Z$3JI=gGB)FQ#odI(O&E^@q;x zK6mr*m3xOS-#u~t!I@i+u0DKm^U160k6t`|^WpV}&n+8{U%dD9&a>B#U%!9-@yol< zU%&tQ{rk_K|NsC0`}dE5ET99@1@a36+kb~?0UJ*yc&I3X_m z!ND^5$O7$#8OFRuDhG}!?8z?cdZK&!`PWjdR;Aj^wZ` zeK{IEYHBJ)6K8VIp1`BVt++swf6j+=L{p1*nO(VhE`pFexG@5$|>uaCcd z`0m=9m+yak{QmXN#Sc$^{$X9h9&q2jiKAI|&T)a;PPx2K9p`YIdw8HtR5k2Q$2-O2 z*;3y{MQ-RnJTgJfI&R5|O)AHxDf_00XbPvDZPy4t=hHd)nfLPvms&O`Ok(sD()5v$ z5U@&h;a=#xbxVbo2~X&Xj0Ie(f{v>vERH+qC+nTG=B8Nca=wU-O$?1&vUgV~9=!H; zx>3p9Yn%*<>t~sk+&0xfyS8RsPfYBd<~wWK%j-LmpU>O7yX^h#UCp1x-p#i7@bE;py8XI6 zmY<)m>~)W~yIWcMVoiPg{duuf<*)9qZ9l$m*Ph&W&$jlv*Vpa+{pH@n=IQ$L?0$ax ec60Ul|8o2P|NVbd{6P)#weSbE3}s?04AuZvx_~SI diff --git a/html/tab_r.gif b/html/tab_r.gif deleted file mode 100644 index ce9dd9f533cb5486d6941844f442b59d4a9e9175..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2585 zcmbV}`9Bkk1ILFF--w5zJc=ZZT(zjE=;2|_S)Qm~rCWz1Pc)KPl;jv%A#&v2*x}yc zmf2~Jm~&=xjJY?PqwIN}f8qQ2{r$uH{c*nJbmr{cR5??*egHrs-B=MzCF`3%e{FAW z{oL5xTHn~5TM{jaB;@|_Ue5F&Zb@p(kMyG{*;gWDg zyeL|eZf7Qd8=#bXzSiR{yzRgLSj-fJS8>lBjVHN z^o-0eS=nE6a`W;LChBs=`+QAJP~{b93>H^eRb5kCSC1zUNezun%`L5M?RDzv#%jk7 zYVRX=vATPD`+oEfum^{RM@GjuP?-r=yh0!p;Vx^T9G7~`7%5ydH%70=jyJ;;`d;hv92x3R=z{xp+Lg2!*@OK*K15-t&okoPtSED)h&$RLxdbA zseWm^C3d%-yRNi-ryk^!ek+C`n&~cd$#ZWct_cUL{l~i+Nzx^5d!n94(>bW-iL~Rl z&8r)?q|1DIo=0=judQ{FaGcfLERz8gfn3-Qt<2lksh{mzpT}DXxUuR^z=^key&q4! z+wWI45vL0k$R^(F#{qfqhUsN@WA+w-V?LPH33!Q?WFSB3)WBojE@hK41Nb?KfS+Qo zXgrzfsP$wr4Qzy*{OD>uJBjdgGM@VMml5)2f~_}lD*YyOb}Hjeobhz#4c`w(l^>KK zr?Ud;W~Z}*w;%hZ|2^p^+f06gJDJQD zeIhGADbDmm&6arh(q>EZ<7mjzg7l|z$hRL8=1>)Nv=S7CY$B}iYJ&*T_-T_OG*L1q ztZ3Lana33?y3AKnyq^YCF|4x%Rb5WU&2qcl{TFKey%QJeMxn^SdT!hZ5+0i1zeusiYVp-phBl7b5+Px-X&LhByq z0F&<;K0l2+v>qiHlXb#$jXMv$uK-dEGE9L~qtdU(XeRXmvu*K2Q&6!fD**JxYP4b4BR7FdJ$Qx9G9`J%-_X!a#LGpp3g9)VWytGCa;7`S1_e8F~!R+aSJ zOF17p2`H?2kPs8Q`_;U}+D%3p zs2-0BTqFwpUoBk`?P;iPQ(IbEA|JmMx!P&YYG|R@S=5Mnw;-?A6rEEVyV%d7{iU4a zNk`i!%F(Ykpm`}#oH;BjY->@b8vQedv;pza2FL&*6ufjd+*3Ute&>kes~TU?^KkojsTh(o~(3tk1Y6>4(yn( z#U*ID9@eg-beKo1B;HXe+}{Z%n@7m0+yxivuqk9~;!1LGQlah)xYK4>wgL}l6dsaN zIxlRlq`*`j9PG4*0hD6YV_b_2w5b#)o7J?`q#{GjvvKlD`T*dWcZx<-s(ZvLB44E# z=!|sw!?)@%y$oRNL#25WS3lzdii}TuQ3?CLnvQ1_n};2sT_;Y;#d3=+-(O% zMN$>O!3;ke(UuLR%h_&)N zs^!-@A>QR}4yB1bPp`9S19ikTbZ~O{&FF-yHK{En;mmShDUIEw03`j(DBIsM}Rjki2J#SQa3gFZTKBPDeIiLt9Z z%bL3(B@Qw%(B`wSMS~dPh$=R`(}lBoFXKy(s|*{#ru$wjsBc_O#zxNk9w+UUHmx(U zmJ8+M+ndtnZ<7|VU9Mbt61zpo9T&3%Wx&XII=#QJxjR`CZf22ac3d51Z?GD%LEe_&*t46Qf;4`bZ7p2K(Ab5>GfT^}4! zBT&HZD`^PEgWoI&{~o-ID0F?O`75sm(87x%A{(}Ch1)QlzdJ)1B-eqe5a(weg0`4lQIf1evjvbBY50DVbzO7CLf|vP z2#0(U-|jZ`H{y5N^o7%iK6H>_HEGN->U6^!)1{XpJV!!4(Ig7wzZQ*9WYF4X1rG0x z=1uA@i`rIAciubDC{;~b(|&|A@xkjRP5aRcvRU9tvIm}jDB6J eQ0-6-y)mpwdT=ayS0tBxKDA*~;EWmo diff --git a/html/tabs.css b/html/tabs.css deleted file mode 100644 index a444163..0000000 --- a/html/tabs.css +++ /dev/null @@ -1,105 +0,0 @@ -/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */ - -DIV.tabs -{ - float : left; - width : 100%; - background : url("tab_b.gif") repeat-x bottom; - margin-bottom : 4px; -} - -DIV.tabs UL -{ - margin : 0px; - padding-left : 10px; - list-style : none; -} - -DIV.tabs LI, DIV.tabs FORM -{ - display : inline; - margin : 0px; - padding : 0px; -} - -DIV.tabs FORM -{ - float : right; -} - -DIV.tabs A -{ - float : left; - background : url("tab_r.gif") no-repeat right top; - border-bottom : 1px solid #84B0C7; - font-size : 80%; - font-weight : bold; - text-decoration : none; -} - -DIV.tabs A:hover -{ - background-position: 100% -150px; -} - -DIV.tabs A:link, DIV.tabs A:visited, -DIV.tabs A:active, DIV.tabs A:hover -{ - color: #1A419D; -} - -DIV.tabs SPAN -{ - float : left; - display : block; - background : url("tab_l.gif") no-repeat left top; - padding : 5px 9px; - white-space : nowrap; -} - -DIV.tabs #MSearchBox -{ - float : right; - display : inline; - font-size : 1em; -} - -DIV.tabs TD -{ - font-size : 80%; - font-weight : bold; - text-decoration : none; -} - - - -/* Commented Backslash Hack hides rule from IE5-Mac \*/ -DIV.tabs SPAN {float : none;} -/* End IE5-Mac hack */ - -DIV.tabs A:hover SPAN -{ - background-position: 0% -150px; -} - -DIV.tabs LI.current A -{ - background-position: 100% -150px; - border-width : 0px; -} - -DIV.tabs LI.current SPAN -{ - background-position: 0% -150px; - padding-bottom : 6px; -} - -DIV.navpath -{ - background : none; - border : none; - border-bottom : 1px solid #84B0C7; - text-align : center; - margin : 2px; - padding : 2px; -} diff --git a/src/dictionary.c b/src/dictionary.c index cb7ccd4..5f4de0d 100644 --- a/src/dictionary.c +++ b/src/dictionary.c @@ -210,7 +210,8 @@ const char * dictionary_get(const dictionary * d, const char * key, const char * { unsigned hash ; ssize_t i ; - + if(d == NULL || key == NULL) + return def ; hash = dictionary_hash(key); for (i=0 ; isize ; i++) { if (d->key[i]==NULL) diff --git a/test/test_dictionary.c b/test/test_dictionary.c index 250c878..d1b89c4 100644 --- a/test/test_dictionary.c +++ b/test/test_dictionary.c @@ -238,3 +238,52 @@ void Test_dictionary_dump(CuTest *tc) dictionary_del(dic); } + +void Test_dictionary_get(CuTest *tc) +{ + dictionary *dic; + int i, j; + char sec_name[32]; + char key_name[64]; + + /*NULL test*/ + CuAssertPtrEquals(tc, NULL, dictionary_get(NULL, NULL, NULL)); + CuAssertPtrEquals(tc, NULL, dictionary_get(NULL, "string", NULL)); + + /*Check the def return element*/ + dic = dictionary_new(DICTMINSZ); + CuAssertPtrNotNull(tc, dic); + CuAssertPtrEquals(tc, NULL, dictionary_get(dic, "dummy", NULL)); + CuAssertStrEquals(tc, "def", dictionary_get(dic, NULL, "def")); + CuAssertStrEquals(tc, "def", dictionary_get(dic, "dummy", "def")); + + /*Populate the dictionary*/ + for (i = 1; i < 3; ++i) + { + sprintf(sec_name, "sec%d", i); + dictionary_set(dic, sec_name, ""); + for (j = 1; j < 5; ++j) + { + sprintf(key_name, "%s:key%d", sec_name, j); + dictionary_set(dic, key_name, "dummy_value"); + CuAssertStrEquals(tc, "dummy_value", + dictionary_get(dic, key_name, "string")); + } + } + + /*Test get dictionary section value*/ + CuAssertStrEquals(tc, "", + dictionary_get(dic, "sec1", NULL)); + CuAssertStrEquals(tc, "", + dictionary_get(dic, "sec1", "def")); + + /*delete and set a key in a dictionary*/ + dictionary_unset(dic, "sec1:key4"); + CuAssertStrEquals(tc, "def", + dictionary_get(dic, "sec1:key4", "def")); + dictionary_set(dic, "sec1:key4", "dummy_value"); + CuAssertStrEquals(tc, "dummy_value", + dictionary_get(dic, "sec1:key4", "def")); + + dictionary_del(dic); +} From a817973177bce835344078d1a1d99d37fefd5588 Mon Sep 17 00:00:00 2001 From: zrrto <2516122612@qq.com> Date: Mon, 2 Sep 2019 14:36:13 +0800 Subject: [PATCH 07/42] Update test_dictionary.c --- test/test_dictionary.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/test_dictionary.c b/test/test_dictionary.c index d1b89c4..5fa8210 100644 --- a/test/test_dictionary.c +++ b/test/test_dictionary.c @@ -184,9 +184,6 @@ void Test_dictionary_unset(CuTest *tc) CuAssertStrEquals(tc, dic1_dump, dic2_dump); free(dic1_dump); free(dic2_dump); - - dictionary_del(dic1); - dictionary_del(dic2); } void Test_dictionary_dump(CuTest *tc) From a8f0fa0d582af1c69d0acbc6cbe5192d5d3aca02 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Tue, 6 Oct 2020 22:03:49 +1100 Subject: [PATCH 08/42] docs: fix simple typo, objet -> object There is a small typo in src/dictionary.c, src/dictionary.h. Should read `object` rather than `objet`. --- src/dictionary.c | 2 +- src/dictionary.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dictionary.c b/src/dictionary.c index cb7ccd4..aa3d232 100644 --- a/src/dictionary.c +++ b/src/dictionary.c @@ -140,7 +140,7 @@ unsigned dictionary_hash(const char * key) /** @brief Create a new dictionary object. @param size Optional initial size of the dictionary. - @return 1 newly allocated dictionary objet. + @return 1 newly allocated dictionary object. This function allocates a new dictionary object of given size and returns it. If you do not know in advance (roughly) the number of entries in the diff --git a/src/dictionary.h b/src/dictionary.h index d04b6ce..f0fd540 100644 --- a/src/dictionary.h +++ b/src/dictionary.h @@ -73,7 +73,7 @@ unsigned dictionary_hash(const char * key); /** @brief Create a new dictionary object. @param size Optional initial size of the dictionary. - @return 1 newly allocated dictionary objet. + @return 1 newly allocated dictionary object. This function allocates a new dictionary object of given size and returns it. If you do not know in advance (roughly) the number of entries in the From b7a2c2999aabf2a83ccc164b9729259ea400e747 Mon Sep 17 00:00:00 2001 From: Dan Bungert Date: Thu, 18 Feb 2021 17:35:58 -0700 Subject: [PATCH 09/42] Fail testrun on test failure Test failures can go unnoticed, as currently the test runner unconditionally returns exit code 0. Consult the number of test failures and exit code 1 if there are any. --- test/make-tests.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/make-tests.sh b/test/make-tests.sh index f2a3f2a..78e6901 100755 --- a/test/make-tests.sh +++ b/test/make-tests.sh @@ -26,10 +26,11 @@ cat $FILES | grep '^void Test' | echo \ ' -void RunAllTests(void) +int RunAllTests(void) { CuString *output = CuStringNew(); CuSuite* suite = CuSuiteNew(); + int ret = 0; ' cat $FILES | grep '^void Test' | @@ -42,15 +43,16 @@ echo \ ' CuSuiteRun(suite); CuSuiteSummary(suite, output); + if (suite->failCount > 0) ret = 1; CuSuiteDetails(suite, output); printf("%s\n", output->buffer); CuStringDelete(output); CuSuiteDelete(suite); + return ret; } int main(void) { - RunAllTests(); - return 0; + return RunAllTests(); } ' From fbb5e60c9a598f24edcd91776849603986e89e6d Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Fri, 16 Apr 2021 17:06:34 -0700 Subject: [PATCH 10/42] test/testiniparser.c: fix missing comma in token test list Fix missing comma separating two test cases in the Test_iniparser_getboolean() token_true list. Without this, the 'Y' testcase was being skipped. (Issue was found by coverity.) Signed-off-by: Steve Beattie Bug: https://github.com/ndevilla/iniparser/issues/131 --- test/test_iniparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_iniparser.c b/test/test_iniparser.c index b7cd5fc..6c42e53 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -455,7 +455,7 @@ void Test_iniparser_getboolean(CuTest *tc) "T", "yes", "y", - "YES" + "YES", "Y", NULL }; From 0f5a112836be0d9c7db59b8c9b832979298e14cc Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Wed, 24 Aug 2022 20:49:08 +0200 Subject: [PATCH 11/42] Fix tests on 32bit The long has different width on 32bit and 64bit. Use predefined macro for the maximum value. Signed-off-by: Michal Suchanek --- test/test_iniparser.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/test_iniparser.c b/test/test_iniparser.c index b7cd5fc..020e6ae 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "CuTest.h" #include "dictionary.h" @@ -15,6 +16,8 @@ #define GOOD_INI_PATH "ressources/good_ini" #define BAD_INI_PATH "ressources/bad_ini" +#define stringify_2(x...) #x +#define stringify(x...) stringify_2(x) /* Tool function to create and populate a generic non-empty dictionary */ static dictionary * generate_dictionary(unsigned sections, unsigned entries_per_section) @@ -350,8 +353,8 @@ void Test_iniparser_getlongint(CuTest *tc) { 1000, "1000" }, { 077, "077" }, { -01000, "-01000" }, - { 0x7FFFFFFFFFFFFFFF, "0x7FFFFFFFFFFFFFFF" }, - { -0x7FFFFFFFFFFFFFFF, "-0x7FFFFFFFFFFFFFFF" }, + { LONG_MAX, stringify(LONG_MAX) }, + { -LONG_MAX, stringify(-LONG_MAX) }, { 0x4242, "0x4242" }, { 0, NULL} /* must be last */ }; @@ -370,8 +373,8 @@ void Test_iniparser_getlongint(CuTest *tc) /* Check the def return element */ dic = dictionary_new(10); CuAssertLongIntEquals(tc, 42, iniparser_getlongint(dic, "dummy", 42)); - CuAssertLongIntEquals(tc, 0x7FFFFFFFFFFFFFFF, iniparser_getlongint(dic, NULL, 0x7FFFFFFFFFFFFFFF)); - CuAssertLongIntEquals(tc, -0x7FFFFFFFFFFFFFFF, iniparser_getlongint(dic, "dummy", -0x7FFFFFFFFFFFFFFF)); + CuAssertLongIntEquals(tc, LONG_MAX, iniparser_getlongint(dic, NULL, LONG_MAX)); + CuAssertLongIntEquals(tc, -LONG_MAX, iniparser_getlongint(dic, "dummy", -LONG_MAX)); dictionary_del(dic); /* Generic dictionary */ From ace9871f65d11b5d73f0b9ee8cf5d2807439442d Mon Sep 17 00:00:00 2001 From: Antonio Date: Fri, 2 Jun 2023 15:03:10 -0300 Subject: [PATCH 12/42] Handle null return from iniparser_getstring Fix handling of NULL returns from iniparser_getstring in iniparser_getboolean, iniparser_getlongint and iniparser_getdouble, avoiding a crash. --- src/iniparser.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/iniparser.c b/src/iniparser.c index f1d1658..dbceb20 100644 --- a/src/iniparser.c +++ b/src/iniparser.c @@ -456,7 +456,7 @@ long int iniparser_getlongint(const dictionary * d, const char * key, long int n const char * str ; str = iniparser_getstring(d, key, INI_INVALID_KEY); - if (str==INI_INVALID_KEY) return notfound ; + if (str==NULL || str==INI_INVALID_KEY) return notfound ; return strtol(str, NULL, 0); } @@ -511,7 +511,7 @@ double iniparser_getdouble(const dictionary * d, const char * key, double notfou const char * str ; str = iniparser_getstring(d, key, INI_INVALID_KEY); - if (str==INI_INVALID_KEY) return notfound ; + if (str==NULL || str==INI_INVALID_KEY) return notfound ; return atof(str); } @@ -553,7 +553,7 @@ int iniparser_getboolean(const dictionary * d, const char * key, int notfound) const char * c ; c = iniparser_getstring(d, key, INI_INVALID_KEY); - if (c==INI_INVALID_KEY) return notfound ; + if (c==NULL || c==INI_INVALID_KEY) return notfound ; if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') { ret = 1 ; } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') { From df88e4b9081f224eef599b1c7d856281218abcc6 Mon Sep 17 00:00:00 2001 From: Nicolas D Date: Fri, 15 Sep 2023 20:31:05 +0200 Subject: [PATCH 13/42] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index dbc30d0..92f0681 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ # Iniparser 4 # +*Sept 2023: We are looking for volunteers to help us maintain this library!* + +Maintaining open-source projects takes time we cannot always easily find. If you feel up to the task and already know this library well, please get in touch by email (ndevilla AT gmail) and let's figure it out! + ## I - Overview From 5142f0feab8ab456cb6af607eba0516ae46e1eb2 Mon Sep 17 00:00:00 2001 From: Nicolas D Date: Fri, 15 Sep 2023 20:32:52 +0200 Subject: [PATCH 14/42] Update README.md --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 92f0681..ace1df9 100644 --- a/README.md +++ b/README.md @@ -11,14 +11,13 @@ Maintaining open-source projects takes time we cannot always easily find. If you This modules offers parsing of ini files from the C level. See a complete documentation in HTML format, from this directory -open the file html/index.html with any HTML-capable browser. +open the file html/index.html with any browser. Key features : - Small : around 1500 sloc inside 4 files (2 .c and 2 .h) - - Portable : no dependancies, written in `-ansi -pedantic` C89 - - Fully reintrant : easy to make it thread-safe (just surround - library calls by mutex) + - Portable : no dependencies, written in `-ansi -pedantic` C89 + - Easy to make it thread-safe, just surround library calls by a mutex. ## II - Building project @@ -27,7 +26,7 @@ A simple `make` at the root of the project should be enough to get the static You should consider trying the following rules too : - - `make check` : run the unitary tests + - `make check` : run unit tests - `make example` : compile the example, run it with `./example/iniexample` ## III - License @@ -40,7 +39,6 @@ See LICENSE for full informations Current version is 4.1. Version 4.0 introduces breaking changes in the api. Older versions 3.1 and 3.2 with the legacy api are available as tags. - ## V - FAQ See [FAQ-en.md](FAQ-en.md) in this directory for answers to Frequently Asked Questions. From 92a84e7ff41d1a7864932caae7671ce6984d1c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Fri, 2 Feb 2024 17:21:07 +0100 Subject: [PATCH 15/42] Proof quick and dirty that 64bit support on 32bit architecture is possible --- src/iniparser.c | 10 ++++++++++ src/iniparser.h | 1 + test/CuTest.c | 4 ++-- test/CuTest.h | 2 +- test/test_iniparser.c | 16 ++++++++-------- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/iniparser.c b/src/iniparser.c index dbceb20..0f8e783 100644 --- a/src/iniparser.c +++ b/src/iniparser.c @@ -460,6 +460,16 @@ long int iniparser_getlongint(const dictionary * d, const char * key, long int n return strtol(str, NULL, 0); } +long long int iniparser_getlonglongint(const dictionary * d, const char * key, long long int notfound) +{ + const char * str ; + + str = iniparser_getstring(d, key, INI_INVALID_KEY); + if (str==NULL || str==INI_INVALID_KEY) return notfound ; + return strtoll(str, NULL, 0); +} + + /*-------------------------------------------------------------------------*/ /** diff --git a/src/iniparser.h b/src/iniparser.h index 37ff7b7..48d67fa 100644 --- a/src/iniparser.h +++ b/src/iniparser.h @@ -229,6 +229,7 @@ int iniparser_getint(const dictionary * d, const char * key, int notfound); /*--------------------------------------------------------------------------*/ long int iniparser_getlongint(const dictionary * d, const char * key, long int notfound); +long long int iniparser_getlonglongint(const dictionary * d, const char * key, long long int notfound); /*-------------------------------------------------------------------------*/ /** diff --git a/test/CuTest.c b/test/CuTest.c index 463f170..56099bf 100644 --- a/test/CuTest.c +++ b/test/CuTest.c @@ -212,11 +212,11 @@ void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const cha } void CuAssertLongIntEquals_LineMsg(CuTest *tc, const char *file, int line, const char *message, - long int expected, long int actual) + long long int expected, long long int actual) { char buf[STRING_MAX]; if (expected == actual) return; - sprintf(buf, "expected <%ld> but was <%ld>", expected, actual); + sprintf(buf, "expected <%lld> but was <%lld>", expected, actual); CuFail_Line(tc, file, line, message, buf); } diff --git a/test/CuTest.h b/test/CuTest.h index 0f58592..8a42725 100644 --- a/test/CuTest.h +++ b/test/CuTest.h @@ -66,7 +66,7 @@ void CuAssertIntEquals_LineMsg(CuTest* tc, int expected, int actual); void CuAssertLongIntEquals_LineMsg(CuTest *tc, const char *file, int line, const char *message, - long int expected, long int actual); + long long int expected, long long int actual); void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, double expected, double actual, double delta); diff --git a/test/test_iniparser.c b/test/test_iniparser.c index b7cd5fc..ddf289e 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -343,7 +343,7 @@ void Test_iniparser_getlongint(CuTest *tc) unsigned i; char key_name[64]; dictionary *dic; - const struct { long int num; const char *value; } good_val[] = { + const struct { long long int num; const char *value; } good_val[] = { { 0, "0" }, { 1, "1" }, { -1, "-1" }, @@ -364,14 +364,14 @@ void Test_iniparser_getlongint(CuTest *tc) "0xG1" }; /* NULL test */ - CuAssertLongIntEquals(tc, -42, iniparser_getlongint(NULL, NULL, -42)); - CuAssertLongIntEquals(tc, -42, iniparser_getlongint(NULL, "dummy", -42)); + CuAssertLongIntEquals(tc, -42, iniparser_getlonglongint(NULL, NULL, -42)); + CuAssertLongIntEquals(tc, -42, iniparser_getlonglongint(NULL, "dummy", -42)); /* Check the def return element */ dic = dictionary_new(10); - CuAssertLongIntEquals(tc, 42, iniparser_getlongint(dic, "dummy", 42)); - CuAssertLongIntEquals(tc, 0x7FFFFFFFFFFFFFFF, iniparser_getlongint(dic, NULL, 0x7FFFFFFFFFFFFFFF)); - CuAssertLongIntEquals(tc, -0x7FFFFFFFFFFFFFFF, iniparser_getlongint(dic, "dummy", -0x7FFFFFFFFFFFFFFF)); + CuAssertLongIntEquals(tc, 42, iniparser_getlonglongint(dic, "dummy", 42)); + CuAssertLongIntEquals(tc, 0x7FFFFFFFFFFFFFFF, iniparser_getlonglongint(dic, NULL, 0x7FFFFFFFFFFFFFFF)); + CuAssertLongIntEquals(tc, -0x7FFFFFFFFFFFFFFF, iniparser_getlonglongint(dic, "dummy", -0x7FFFFFFFFFFFFFFF)); dictionary_del(dic); /* Generic dictionary */ @@ -383,7 +383,7 @@ void Test_iniparser_getlongint(CuTest *tc) for (i = 0; good_val[i].value != NULL; ++i) { sprintf(key_name, "longint:value%d", i); CuAssertLongIntEquals(tc, good_val[i].num, - iniparser_getlongint(dic, key_name, 0)); + iniparser_getlonglongint(dic, key_name, 0)); } dictionary_del(dic); @@ -396,7 +396,7 @@ void Test_iniparser_getlongint(CuTest *tc) for (i = 0; i < sizeof (bad_val) / sizeof (char *); ++i) { sprintf(key_name, "longint:bad%d", i); CuAssertLongIntEquals(tc, 0, - iniparser_getlongint(dic, key_name, 0)); + iniparser_getlonglongint(dic, key_name, 0)); } dictionary_del(dic); } From f2df1d1f384721d8c02e35c3f8ee6c1829391986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Fri, 2 Feb 2024 18:10:42 +0100 Subject: [PATCH 16/42] Comply with ANSI C --- src/iniparser.c | 5 +++-- src/iniparser.h | 2 +- test/CuTest.c | 4 ++-- test/CuTest.h | 3 ++- test/test_iniparser.c | 16 ++++++++-------- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/iniparser.c b/src/iniparser.c index 0f8e783..e54f45f 100644 --- a/src/iniparser.c +++ b/src/iniparser.c @@ -9,6 +9,7 @@ /*---------------------------- Includes ------------------------------------*/ #include #include +#include #include "iniparser.h" /*---------------------------- Defines -------------------------------------*/ @@ -460,13 +461,13 @@ long int iniparser_getlongint(const dictionary * d, const char * key, long int n return strtol(str, NULL, 0); } -long long int iniparser_getlonglongint(const dictionary * d, const char * key, long long int notfound) +int64_t iniparser_getint64(const dictionary * d, const char * key, int64_t notfound) { const char * str ; str = iniparser_getstring(d, key, INI_INVALID_KEY); if (str==NULL || str==INI_INVALID_KEY) return notfound ; - return strtoll(str, NULL, 0); + return strtoimax(str, NULL, 0); } diff --git a/src/iniparser.h b/src/iniparser.h index 48d67fa..97cbbb2 100644 --- a/src/iniparser.h +++ b/src/iniparser.h @@ -229,7 +229,7 @@ int iniparser_getint(const dictionary * d, const char * key, int notfound); /*--------------------------------------------------------------------------*/ long int iniparser_getlongint(const dictionary * d, const char * key, long int notfound); -long long int iniparser_getlonglongint(const dictionary * d, const char * key, long long int notfound); +int64_t iniparser_getint64(const dictionary * d, const char * key, int64_t notfound); /*-------------------------------------------------------------------------*/ /** diff --git a/test/CuTest.c b/test/CuTest.c index 56099bf..fde87ff 100644 --- a/test/CuTest.c +++ b/test/CuTest.c @@ -212,11 +212,11 @@ void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const cha } void CuAssertLongIntEquals_LineMsg(CuTest *tc, const char *file, int line, const char *message, - long long int expected, long long int actual) + int64_t expected, int64_t actual) { char buf[STRING_MAX]; if (expected == actual) return; - sprintf(buf, "expected <%lld> but was <%lld>", expected, actual); + sprintf(buf, "expected <%ld> but was <%ld>", (long)expected, (long)actual); CuFail_Line(tc, file, line, message, buf); } diff --git a/test/CuTest.h b/test/CuTest.h index 8a42725..9845fef 100644 --- a/test/CuTest.h +++ b/test/CuTest.h @@ -3,6 +3,7 @@ #include #include +#include #define CUTEST_VERSION "CuTest 1.5" @@ -66,7 +67,7 @@ void CuAssertIntEquals_LineMsg(CuTest* tc, int expected, int actual); void CuAssertLongIntEquals_LineMsg(CuTest *tc, const char *file, int line, const char *message, - long long int expected, long long int actual); + int64_t expected, int64_t actual); void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, double expected, double actual, double delta); diff --git a/test/test_iniparser.c b/test/test_iniparser.c index ddf289e..a71dbb6 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -343,7 +343,7 @@ void Test_iniparser_getlongint(CuTest *tc) unsigned i; char key_name[64]; dictionary *dic; - const struct { long long int num; const char *value; } good_val[] = { + const struct { int64_t num; const char *value; } good_val[] = { { 0, "0" }, { 1, "1" }, { -1, "-1" }, @@ -364,14 +364,14 @@ void Test_iniparser_getlongint(CuTest *tc) "0xG1" }; /* NULL test */ - CuAssertLongIntEquals(tc, -42, iniparser_getlonglongint(NULL, NULL, -42)); - CuAssertLongIntEquals(tc, -42, iniparser_getlonglongint(NULL, "dummy", -42)); + CuAssertLongIntEquals(tc, -42, iniparser_getint64(NULL, NULL, -42)); + CuAssertLongIntEquals(tc, -42, iniparser_getint64(NULL, "dummy", -42)); /* Check the def return element */ dic = dictionary_new(10); - CuAssertLongIntEquals(tc, 42, iniparser_getlonglongint(dic, "dummy", 42)); - CuAssertLongIntEquals(tc, 0x7FFFFFFFFFFFFFFF, iniparser_getlonglongint(dic, NULL, 0x7FFFFFFFFFFFFFFF)); - CuAssertLongIntEquals(tc, -0x7FFFFFFFFFFFFFFF, iniparser_getlonglongint(dic, "dummy", -0x7FFFFFFFFFFFFFFF)); + CuAssertLongIntEquals(tc, 42, iniparser_getint64(dic, "dummy", 42)); + CuAssertLongIntEquals(tc, 0x7FFFFFFFFFFFFFFF, iniparser_getint64(dic, NULL, 0x7FFFFFFFFFFFFFFF)); + CuAssertLongIntEquals(tc, -0x7FFFFFFFFFFFFFFF, iniparser_getint64(dic, "dummy", -0x7FFFFFFFFFFFFFFF)); dictionary_del(dic); /* Generic dictionary */ @@ -383,7 +383,7 @@ void Test_iniparser_getlongint(CuTest *tc) for (i = 0; good_val[i].value != NULL; ++i) { sprintf(key_name, "longint:value%d", i); CuAssertLongIntEquals(tc, good_val[i].num, - iniparser_getlonglongint(dic, key_name, 0)); + iniparser_getint64(dic, key_name, 0)); } dictionary_del(dic); @@ -396,7 +396,7 @@ void Test_iniparser_getlongint(CuTest *tc) for (i = 0; i < sizeof (bad_val) / sizeof (char *); ++i) { sprintf(key_name, "longint:bad%d", i); CuAssertLongIntEquals(tc, 0, - iniparser_getlonglongint(dic, key_name, 0)); + iniparser_getint64(dic, key_name, 0)); } dictionary_del(dic); } From 8d09292af71db5f5a07c439519293796059fbef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Fri, 2 Feb 2024 18:39:50 +0100 Subject: [PATCH 17/42] Restore the long int test code and add API description to int64_t getter --- src/iniparser.h | 28 ++++++++++++++++ test/CuTest.c | 9 +++++ test/CuTest.h | 5 +++ test/test_iniparser.c | 77 +++++++++++++++++++++++++++++++++++++++---- 4 files changed, 112 insertions(+), 7 deletions(-) diff --git a/src/iniparser.h b/src/iniparser.h index 97cbbb2..ddad9c3 100644 --- a/src/iniparser.h +++ b/src/iniparser.h @@ -229,6 +229,34 @@ int iniparser_getint(const dictionary * d, const char * key, int notfound); /*--------------------------------------------------------------------------*/ long int iniparser_getlongint(const dictionary * d, const char * key, long int notfound); +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an int64_t + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + - "42" -> 42 + - "042" -> 34 (octal -> decimal) + - "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtoimax(), see the associated man page for overflow + handling. + + This function is usefull on 32bit architectures where `long int` is only + 32bit. + */ +/*--------------------------------------------------------------------------*/ int64_t iniparser_getint64(const dictionary * d, const char * key, int64_t notfound); /*-------------------------------------------------------------------------*/ diff --git a/test/CuTest.c b/test/CuTest.c index fde87ff..485c481 100644 --- a/test/CuTest.c +++ b/test/CuTest.c @@ -212,6 +212,15 @@ void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const cha } void CuAssertLongIntEquals_LineMsg(CuTest *tc, const char *file, int line, const char *message, + long int expected, long int actual) +{ + char buf[STRING_MAX]; + if (expected == actual) return; + sprintf(buf, "expected <%ld> but was <%ld>", expected, actual); + CuFail_Line(tc, file, line, message, buf); +} + +void CuAssertInt64Equals_LineMsg(CuTest *tc, const char *file, int line, const char *message, int64_t expected, int64_t actual) { char buf[STRING_MAX]; diff --git a/test/CuTest.h b/test/CuTest.h index 9845fef..72fd5cd 100644 --- a/test/CuTest.h +++ b/test/CuTest.h @@ -66,6 +66,9 @@ void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, int expected, int actual); void CuAssertLongIntEquals_LineMsg(CuTest *tc, + const char *file, int line, const char *message, + long int expected, long int actual); +void CuAssertInt64Equals_LineMsg(CuTest *tc, const char *file, int line, const char *message, int64_t expected, int64_t actual); void CuAssertDblEquals_LineMsg(CuTest* tc, @@ -87,6 +90,8 @@ void CuAssertPtrEquals_LineMsg(CuTest* tc, #define CuAssertIntEquals_Msg(tc,ms,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) #define CuAssertLongIntEquals(tc,ex,ac) CuAssertLongIntEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) #define CuAssertLongIntEquals_Msg(tc,ms,ex,ac) CuAssertLongIntEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) +#define CuAssertInt64Equals(tc,ex,ac) CuAssertInt64Equals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) +#define CuAssertInt64Equals_Msg(tc,ms,ex,ac) CuAssertInt64Equals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) #define CuAssertDblEquals(tc,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac),(dl)) #define CuAssertDblEquals_Msg(tc,ms,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac),(dl)) #define CuAssertPtrEquals(tc,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) diff --git a/test/test_iniparser.c b/test/test_iniparser.c index a71dbb6..88b14b0 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -343,7 +343,7 @@ void Test_iniparser_getlongint(CuTest *tc) unsigned i; char key_name[64]; dictionary *dic; - const struct { int64_t num; const char *value; } good_val[] = { + const struct { long int num; const char *value; } good_val[] = { { 0, "0" }, { 1, "1" }, { -1, "-1" }, @@ -364,14 +364,14 @@ void Test_iniparser_getlongint(CuTest *tc) "0xG1" }; /* NULL test */ - CuAssertLongIntEquals(tc, -42, iniparser_getint64(NULL, NULL, -42)); - CuAssertLongIntEquals(tc, -42, iniparser_getint64(NULL, "dummy", -42)); + CuAssertLongIntEquals(tc, -42, iniparser_getlongint(NULL, NULL, -42)); + CuAssertLongIntEquals(tc, -42, iniparser_getlongint(NULL, "dummy", -42)); /* Check the def return element */ dic = dictionary_new(10); - CuAssertLongIntEquals(tc, 42, iniparser_getint64(dic, "dummy", 42)); - CuAssertLongIntEquals(tc, 0x7FFFFFFFFFFFFFFF, iniparser_getint64(dic, NULL, 0x7FFFFFFFFFFFFFFF)); - CuAssertLongIntEquals(tc, -0x7FFFFFFFFFFFFFFF, iniparser_getint64(dic, "dummy", -0x7FFFFFFFFFFFFFFF)); + CuAssertLongIntEquals(tc, 42, iniparser_getlongint(dic, "dummy", 42)); + CuAssertLongIntEquals(tc, 0x7FFFFFFFFFFFFFFF, iniparser_getlongint(dic, NULL, 0x7FFFFFFFFFFFFFFF)); + CuAssertLongIntEquals(tc, -0x7FFFFFFFFFFFFFFF, iniparser_getlongint(dic, "dummy", -0x7FFFFFFFFFFFFFFF)); dictionary_del(dic); /* Generic dictionary */ @@ -383,7 +383,7 @@ void Test_iniparser_getlongint(CuTest *tc) for (i = 0; good_val[i].value != NULL; ++i) { sprintf(key_name, "longint:value%d", i); CuAssertLongIntEquals(tc, good_val[i].num, - iniparser_getint64(dic, key_name, 0)); + iniparser_getlongint(dic, key_name, 0)); } dictionary_del(dic); @@ -396,6 +396,69 @@ void Test_iniparser_getlongint(CuTest *tc) for (i = 0; i < sizeof (bad_val) / sizeof (char *); ++i) { sprintf(key_name, "longint:bad%d", i); CuAssertLongIntEquals(tc, 0, + iniparser_getlongint(dic, key_name, 0)); + } + dictionary_del(dic); +} + +void Test_iniparser_getint64(CuTest *tc) +{ + unsigned i; + char key_name[64]; + dictionary *dic; + const struct { int64_t num; const char *value; } good_val[] = { + { 0, "0" }, + { 1, "1" }, + { -1, "-1" }, + { 1000, "1000" }, + { 077, "077" }, + { -01000, "-01000" }, + { 0x7FFFFFFFFFFFFFFF, "0x7FFFFFFFFFFFFFFF" }, + { -0x7FFFFFFFFFFFFFFF, "-0x7FFFFFFFFFFFFFFF" }, + { 0x4242, "0x4242" }, + { 0, NULL} /* must be last */ + }; + const char *bad_val[] = { + "", + "notanumber", + "0x", + "k2000", + " ", + "0xG1" + }; + /* NULL test */ + CuAssertInt64Equals(tc, -42, iniparser_getint64(NULL, NULL, -42)); + CuAssertInt64Equals(tc, -42, iniparser_getint64(NULL, "dummy", -42)); + + /* Check the def return element */ + dic = dictionary_new(10); + CuAssertInt64Equals(tc, 42, iniparser_getint64(dic, "dummy", 42)); + CuAssertInt64Equals(tc, 0x7FFFFFFFFFFFFFFF, iniparser_getint64(dic, NULL, 0x7FFFFFFFFFFFFFFF)); + CuAssertInt64Equals(tc, -0x7FFFFFFFFFFFFFFF, iniparser_getint64(dic, "dummy", -0x7FFFFFFFFFFFFFFF)); + dictionary_del(dic); + + /* Generic dictionary */ + dic = dictionary_new(10); + for (i = 0; good_val[i].value != NULL; ++i) { + sprintf(key_name, "longint:value%d", i); + dictionary_set(dic, key_name, good_val[i].value); + } + for (i = 0; good_val[i].value != NULL; ++i) { + sprintf(key_name, "longint:value%d", i); + CuAssertInt64Equals(tc, good_val[i].num, + iniparser_getint64(dic, key_name, 0)); + } + dictionary_del(dic); + + /* Test bad names */ + dic = dictionary_new(10); + for (i = 0; i < sizeof (bad_val) / sizeof (char *); ++i) { + sprintf(key_name, "longint:bad%d", i); + dictionary_set(dic, key_name, bad_val[i]); + } + for (i = 0; i < sizeof (bad_val) / sizeof (char *); ++i) { + sprintf(key_name, "longint:bad%d", i); + CuAssertInt64Equals(tc, 0, iniparser_getint64(dic, key_name, 0)); } dictionary_del(dic); From 60c19255fefec60cc258e6be141593796284fcb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Fri, 2 Feb 2024 18:58:13 +0100 Subject: [PATCH 18/42] Prevent `long int` overflow on 32bit architectures --- test/test_iniparser.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/test_iniparser.c b/test/test_iniparser.c index 88b14b0..774d842 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "CuTest.h" #include "dictionary.h" @@ -350,8 +351,13 @@ void Test_iniparser_getlongint(CuTest *tc) { 1000, "1000" }, { 077, "077" }, { -01000, "-01000" }, +#if INT_MAX == LONG_MAX + { 0x7FFFFFFF, "0x7FFFFFFF" }, + { -0x7FFFFFFF, "-0x7FFFFFFF" }, +#else { 0x7FFFFFFFFFFFFFFF, "0x7FFFFFFFFFFFFFFF" }, { -0x7FFFFFFFFFFFFFFF, "-0x7FFFFFFFFFFFFFFF" }, +#endif { 0x4242, "0x4242" }, { 0, NULL} /* must be last */ }; @@ -370,8 +376,13 @@ void Test_iniparser_getlongint(CuTest *tc) /* Check the def return element */ dic = dictionary_new(10); CuAssertLongIntEquals(tc, 42, iniparser_getlongint(dic, "dummy", 42)); +#if INT_MAX == LONG_MAX + CuAssertLongIntEquals(tc, 0x7FFFFFFF, iniparser_getlongint(dic, NULL, 0x7FFFFFFF)); + CuAssertLongIntEquals(tc, -0x7FFFFFFF, iniparser_getlongint(dic, "dummy", -0x7FFFFFFF)); +#else CuAssertLongIntEquals(tc, 0x7FFFFFFFFFFFFFFF, iniparser_getlongint(dic, NULL, 0x7FFFFFFFFFFFFFFF)); CuAssertLongIntEquals(tc, -0x7FFFFFFFFFFFFFFF, iniparser_getlongint(dic, "dummy", -0x7FFFFFFFFFFFFFFF)); +#endif dictionary_del(dic); /* Generic dictionary */ From bb8dab265e5f5b3d67c9ca9273354753990b6544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Fri, 2 Feb 2024 19:24:06 +0100 Subject: [PATCH 19/42] Add comment to explain misleading type conversion --- test/CuTest.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/CuTest.c b/test/CuTest.c index 485c481..e56d57e 100644 --- a/test/CuTest.c +++ b/test/CuTest.c @@ -225,6 +225,13 @@ void CuAssertInt64Equals_LineMsg(CuTest *tc, const char *file, int line, const c { char buf[STRING_MAX]; if (expected == actual) return; + /* This should be: + * + * sprintf(buf, "expected <%"PRIi64"> but was <%"PRIi64">", expected, actual); + * + * But ANSI does not allow %lld and thus on 32bit platforms this would + * fail to compile + */ sprintf(buf, "expected <%ld> but was <%ld>", (long)expected, (long)actual); CuFail_Line(tc, file, line, message, buf); } From 143887d5e9969d00d9cc2169cc82006eb022a592 Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Wed, 24 Aug 2022 20:49:08 +0200 Subject: [PATCH 20/42] Fix tests on 32bit The long has different width on 32bit and 64bit. Use predefined macro for the maximum value. Signed-off-by: Michal Suchanek --- test/test_iniparser.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/test/test_iniparser.c b/test/test_iniparser.c index 774d842..f84d683 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -16,6 +16,8 @@ #define GOOD_INI_PATH "ressources/good_ini" #define BAD_INI_PATH "ressources/bad_ini" +#define stringify_2(x...) #x +#define stringify(x...) stringify_2(x) /* Tool function to create and populate a generic non-empty dictionary */ static dictionary * generate_dictionary(unsigned sections, unsigned entries_per_section) @@ -351,13 +353,8 @@ void Test_iniparser_getlongint(CuTest *tc) { 1000, "1000" }, { 077, "077" }, { -01000, "-01000" }, -#if INT_MAX == LONG_MAX - { 0x7FFFFFFF, "0x7FFFFFFF" }, - { -0x7FFFFFFF, "-0x7FFFFFFF" }, -#else - { 0x7FFFFFFFFFFFFFFF, "0x7FFFFFFFFFFFFFFF" }, - { -0x7FFFFFFFFFFFFFFF, "-0x7FFFFFFFFFFFFFFF" }, -#endif + { LONG_MAX, stringify(LONG_MAX) }, + { -LONG_MAX, stringify(-LONG_MAX) }, { 0x4242, "0x4242" }, { 0, NULL} /* must be last */ }; @@ -376,13 +373,8 @@ void Test_iniparser_getlongint(CuTest *tc) /* Check the def return element */ dic = dictionary_new(10); CuAssertLongIntEquals(tc, 42, iniparser_getlongint(dic, "dummy", 42)); -#if INT_MAX == LONG_MAX - CuAssertLongIntEquals(tc, 0x7FFFFFFF, iniparser_getlongint(dic, NULL, 0x7FFFFFFF)); - CuAssertLongIntEquals(tc, -0x7FFFFFFF, iniparser_getlongint(dic, "dummy", -0x7FFFFFFF)); -#else - CuAssertLongIntEquals(tc, 0x7FFFFFFFFFFFFFFF, iniparser_getlongint(dic, NULL, 0x7FFFFFFFFFFFFFFF)); - CuAssertLongIntEquals(tc, -0x7FFFFFFFFFFFFFFF, iniparser_getlongint(dic, "dummy", -0x7FFFFFFFFFFFFFFF)); -#endif + CuAssertLongIntEquals(tc, LONG_MAX, iniparser_getlongint(dic, NULL, LONG_MAX)); + CuAssertLongIntEquals(tc, -LONG_MAX, iniparser_getlongint(dic, "dummy", -LONG_MAX)); dictionary_del(dic); /* Generic dictionary */ From 0a4c95e36869510c868066b3a6c9cd5d9779ccaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Fri, 2 Feb 2024 20:35:22 +0100 Subject: [PATCH 21/42] Fix ANSI C compliance This solves these warnings: ``` test_iniparser.c:19:22: warning: ISO C does not permit named variadic macros [-Wvariadic-macros] 19 | #define stringify_2(x...) #x | ^~~ test_iniparser.c:20:20: warning: ISO C does not permit named variadic macros [-Wvariadic-macros] 20 | #define stringify(x...) stringify_2(x) | ^~~ ``` --- test/test_iniparser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_iniparser.c b/test/test_iniparser.c index f84d683..1566bde 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -16,8 +16,8 @@ #define GOOD_INI_PATH "ressources/good_ini" #define BAD_INI_PATH "ressources/bad_ini" -#define stringify_2(x...) #x -#define stringify(x...) stringify_2(x) +#define stringify_2(x) #x +#define stringify(x) stringify_2(x) /* Tool function to create and populate a generic non-empty dictionary */ static dictionary * generate_dictionary(unsigned sections, unsigned entries_per_section) From f205191fdb4fcfac001adf8d644d39e214e44042 Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Fri, 2 Feb 2024 21:09:44 +0100 Subject: [PATCH 22/42] Fix warning about variadic macro For some reason when built with -m32 gcc produces this warning: test_iniparser.c:19:22: warning: ISO C does not permit named variadic macros [-Wvariadic-macros] 19 | #define stringify_2(x...) #x For the limited use in this test there is no need for variadic stringify. With this the warning is avoided, and the test passes on both 32bit and 64bit. Signed-off-by: Michal Suchanek --- test/test_iniparser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_iniparser.c b/test/test_iniparser.c index 020e6ae..ea0b3b1 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -16,8 +16,8 @@ #define GOOD_INI_PATH "ressources/good_ini" #define BAD_INI_PATH "ressources/bad_ini" -#define stringify_2(x...) #x -#define stringify(x...) stringify_2(x) +#define stringify_2(x) #x +#define stringify(x) stringify_2(x) /* Tool function to create and populate a generic non-empty dictionary */ static dictionary * generate_dictionary(unsigned sections, unsigned entries_per_section) From bfda7df403d2f13caeba58fc473c6f18abc9f2a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Fri, 2 Feb 2024 20:49:53 +0100 Subject: [PATCH 23/42] Add support for uint64_t --- src/iniparser.c | 9 +++++++ src/iniparser.h | 31 +++++++++++++++++++++ test/CuTest.c | 16 +++++++++++ test/CuTest.h | 5 ++++ test/test_iniparser.c | 63 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 124 insertions(+) diff --git a/src/iniparser.c b/src/iniparser.c index e54f45f..725ab11 100644 --- a/src/iniparser.c +++ b/src/iniparser.c @@ -470,6 +470,15 @@ int64_t iniparser_getint64(const dictionary * d, const char * key, int64_t notfo return strtoimax(str, NULL, 0); } +uint64_t iniparser_getuint64(const dictionary * d, const char * key, uint64_t notfound) +{ + const char * str ; + + str = iniparser_getstring(d, key, INI_INVALID_KEY); + if (str==NULL || str==INI_INVALID_KEY) return notfound ; + return strtoumax(str, NULL, 0); +} + /*-------------------------------------------------------------------------*/ diff --git a/src/iniparser.h b/src/iniparser.h index ddad9c3..84b92a3 100644 --- a/src/iniparser.h +++ b/src/iniparser.h @@ -17,6 +17,7 @@ #include #include #include +#include /* * The following #include is necessary on many Unixes but not Linux. @@ -259,6 +260,36 @@ long int iniparser_getlongint(const dictionary * d, const char * key, long int n /*--------------------------------------------------------------------------*/ int64_t iniparser_getint64(const dictionary * d, const char * key, int64_t notfound); +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an uint64_t + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + - "42" -> 42 + - "042" -> 34 (octal -> decimal) + - "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtoumax(), see the associated man page for overflow + handling. + + This function is usefull on 32bit architectures where `long int` is only + 32bit. + */ +/*--------------------------------------------------------------------------*/ +uint64_t iniparser_getuint64(const dictionary * d, const char * key, uint64_t notfound); + /*-------------------------------------------------------------------------*/ /** @brief Get the string associated to a key, convert to a double diff --git a/test/CuTest.c b/test/CuTest.c index e56d57e..1cc9f56 100644 --- a/test/CuTest.c +++ b/test/CuTest.c @@ -236,6 +236,22 @@ void CuAssertInt64Equals_LineMsg(CuTest *tc, const char *file, int line, const c CuFail_Line(tc, file, line, message, buf); } +void CuAssertUInt64Equals_LineMsg(CuTest *tc, const char *file, int line, const char *message, + uint64_t expected, uint64_t actual) +{ + char buf[STRING_MAX]; + if (expected == actual) return; + /* This should be: + * + * sprintf(buf, "expected <%"PRIu64"> but was <%"PRIu64">", expected, actual); + * + * But ANSI does not allow %llu and thus on 32bit platforms this would + * fail to compile + */ + sprintf(buf, "expected <%lu> but was <%lu>", (unsigned long)expected, (unsigned long)actual); + CuFail_Line(tc, file, line, message, buf); +} + void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, double expected, double actual, double delta) { diff --git a/test/CuTest.h b/test/CuTest.h index 72fd5cd..56bce18 100644 --- a/test/CuTest.h +++ b/test/CuTest.h @@ -71,6 +71,9 @@ void CuAssertLongIntEquals_LineMsg(CuTest *tc, void CuAssertInt64Equals_LineMsg(CuTest *tc, const char *file, int line, const char *message, int64_t expected, int64_t actual); +void CuAssertUInt64Equals_LineMsg(CuTest *tc, + const char *file, int line, const char *message, + uint64_t expected, uint64_t actual); void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, double expected, double actual, double delta); @@ -92,6 +95,8 @@ void CuAssertPtrEquals_LineMsg(CuTest* tc, #define CuAssertLongIntEquals_Msg(tc,ms,ex,ac) CuAssertLongIntEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) #define CuAssertInt64Equals(tc,ex,ac) CuAssertInt64Equals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) #define CuAssertInt64Equals_Msg(tc,ms,ex,ac) CuAssertInt64Equals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) +#define CuAssertUInt64Equals(tc,ex,ac) CuAssertUInt64Equals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) +#define CuAssertUInt64Equals_Msg(tc,ms,ex,ac) CuAssertUInt64Equals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) #define CuAssertDblEquals(tc,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac),(dl)) #define CuAssertDblEquals_Msg(tc,ms,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac),(dl)) #define CuAssertPtrEquals(tc,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) diff --git a/test/test_iniparser.c b/test/test_iniparser.c index 1566bde..2d07a08 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -467,6 +467,69 @@ void Test_iniparser_getint64(CuTest *tc) dictionary_del(dic); } +void Test_iniparser_getuint64(CuTest *tc) +{ + unsigned i; + char key_name[64]; + dictionary *dic; + const struct { uint64_t num; const char *value; } good_val[] = { + { 0, "0" }, + { 1, "1" }, + { -1, "-1" }, + { 1000, "1000" }, + { 077, "077" }, + { -01000, "-01000" }, + { 0xFFFFFFFFFFFFFFFF, "0xFFFFFFFFFFFFFFFF" }, + { -0xFFFFFFFFFFFFFFFF, "-0xFFFFFFFFFFFFFFFF" }, + { 0x4242, "0x4242" }, + { 0, NULL} /* must be last */ + }; + const char *bad_val[] = { + "", + "notanumber", + "0x", + "k2000", + " ", + "0xG1" + }; + /* NULL test */ + CuAssertUInt64Equals(tc, -42, iniparser_getuint64(NULL, NULL, -42)); + CuAssertUInt64Equals(tc, -42, iniparser_getuint64(NULL, "dummy", -42)); + + /* Check the def return element */ + dic = dictionary_new(10); + CuAssertUInt64Equals(tc, 42, iniparser_getuint64(dic, "dummy", 42)); + CuAssertUInt64Equals(tc, 0xFFFFFFFFFFFFFFFF, iniparser_getuint64(dic, NULL, 0xFFFFFFFFFFFFFFFF)); + CuAssertUInt64Equals(tc, -0xFFFFFFFFFFFFFFFF, iniparser_getuint64(dic, "dummy", -0xFFFFFFFFFFFFFFFF)); + dictionary_del(dic); + + /* Generic dictionary */ + dic = dictionary_new(10); + for (i = 0; good_val[i].value != NULL; ++i) { + sprintf(key_name, "longint:value%d", i); + dictionary_set(dic, key_name, good_val[i].value); + } + for (i = 0; good_val[i].value != NULL; ++i) { + sprintf(key_name, "longint:value%d", i); + CuAssertUInt64Equals(tc, good_val[i].num, + iniparser_getuint64(dic, key_name, 0)); + } + dictionary_del(dic); + + /* Test bad names */ + dic = dictionary_new(10); + for (i = 0; i < sizeof (bad_val) / sizeof (char *); ++i) { + sprintf(key_name, "longint:bad%d", i); + dictionary_set(dic, key_name, bad_val[i]); + } + for (i = 0; i < sizeof (bad_val) / sizeof (char *); ++i) { + sprintf(key_name, "longint:bad%d", i); + CuAssertUInt64Equals(tc, 0, + iniparser_getuint64(dic, key_name, 0)); + } + dictionary_del(dic); +} + void Test_iniparser_getdouble(CuTest *tc) { dictionary *dic; From 87e94902938301bc03187fda08a1c882331fb6f8 Mon Sep 17 00:00:00 2001 From: ashamedbit Date: Mon, 5 Feb 2024 23:56:10 -0500 Subject: [PATCH 24/42] Free dictionaries in test_dictionary.c --- test/test_dictionary.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test_dictionary.c b/test/test_dictionary.c index f89f1c1..a525152 100644 --- a/test/test_dictionary.c +++ b/test/test_dictionary.c @@ -53,6 +53,7 @@ void Test_dictionary_grow(CuTest *tc) CuAssertIntEquals(tc, 0, dic->n); CuAssertIntEquals(tc, (1 << i) * DICTMINSZ, dic->size); } + dictionary_del(dic); } void Test_dictionary_hash(CuTest *tc) @@ -184,6 +185,8 @@ void Test_dictionary_unset(CuTest *tc) CuAssertStrEquals(tc, dic1_dump, dic2_dump); free(dic1_dump); free(dic2_dump); + dictionary_del(dic1); + dictionary_del(dic2); } void Test_dictionary_dump(CuTest *tc) From ece374b112d2c1d6bd5aac97a93d1db662ef3a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Sun, 11 Feb 2024 14:49:18 +0100 Subject: [PATCH 25/42] Add link to iniparser-meta --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index db3c5dd..c565f0b 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,8 @@ You should consider trying the following rules too : - `make check` : run unit tests - `make example` : compile the example, run it with `./example/iniexample` +For installation and packaging see [iniparser-meta](https://gitlab.com/iniparser/iniparser-meta). + ## III - License This software is released under MIT License. From 867c90eb15d15fc2de80bb183be1b17ebb090bfe Mon Sep 17 00:00:00 2001 From: Nicolas D Date: Sun, 11 Feb 2024 15:35:47 +0100 Subject: [PATCH 26/42] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 5a3a80b..2c66fc1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2000-2011 by Nicolas Devillard. +Copyright (c) 2000-2024 by Nicolas Devillard and many contributors MIT License Permission is hereby granted, free of charge, to any person obtaining a From 6c96869e6208a913d74359ef22323546a007afd7 Mon Sep 17 00:00:00 2001 From: dofuuz Date: Wed, 3 Mar 2021 22:13:56 +0900 Subject: [PATCH 27/42] Replace POSIX ssize_t with C standard size_t --- src/dictionary.c | 11 +++++------ src/dictionary.h | 3 +-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/dictionary.c b/src/dictionary.c index 1bc8ffc..fc42819 100644 --- a/src/dictionary.c +++ b/src/dictionary.c @@ -18,7 +18,6 @@ #include #include #include -#include /** Minimal allocated number of entries in a dictionary */ #define DICTMINSZ 128 @@ -170,7 +169,7 @@ dictionary * dictionary_new(size_t size) /*--------------------------------------------------------------------------*/ void dictionary_del(dictionary * d) { - ssize_t i ; + size_t i ; if (d==NULL) return ; for (i=0 ; isize ; i++) { @@ -203,7 +202,7 @@ void dictionary_del(dictionary * d) const char * dictionary_get(const dictionary * d, const char * key, const char * def) { unsigned hash ; - ssize_t i ; + size_t i ; hash = dictionary_hash(key); for (i=0 ; isize ; i++) { @@ -248,7 +247,7 @@ const char * dictionary_get(const dictionary * d, const char * key, const char * /*--------------------------------------------------------------------------*/ int dictionary_set(dictionary * d, const char * key, const char * val) { - ssize_t i ; + size_t i ; unsigned hash ; if (d==NULL || key==NULL) return -1 ; @@ -308,7 +307,7 @@ int dictionary_set(dictionary * d, const char * key, const char * val) void dictionary_unset(dictionary * d, const char * key) { unsigned hash ; - ssize_t i ; + size_t i ; if (key == NULL || d == NULL) { return; @@ -356,7 +355,7 @@ void dictionary_unset(dictionary * d, const char * key) /*--------------------------------------------------------------------------*/ void dictionary_dump(const dictionary * d, FILE * out) { - ssize_t i ; + size_t i ; if (d==NULL || out==NULL) return ; if (d->n<1) { diff --git a/src/dictionary.h b/src/dictionary.h index f0fd540..4e1efa0 100644 --- a/src/dictionary.h +++ b/src/dictionary.h @@ -21,7 +21,6 @@ #include #include #include -#include #ifdef __cplusplus extern "C" { @@ -44,7 +43,7 @@ extern "C" { /*-------------------------------------------------------------------------*/ typedef struct _dictionary_ { int n ; /** Number of entries in dictionary */ - ssize_t size ; /** Storage size */ + size_t size ; /** Storage size */ char ** val ; /** List of string values */ char ** key ; /** List of string keys */ unsigned * hash ; /** List of hash values for keys */ From 637866710788c4a01fbcf2473dbe66d2f72cdd6b Mon Sep 17 00:00:00 2001 From: dofuuz Date: Thu, 4 Mar 2021 22:55:45 +0900 Subject: [PATCH 28/42] Remove warnings --- src/dictionary.h | 2 +- src/iniparser.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dictionary.h b/src/dictionary.h index 4e1efa0..7b2585f 100644 --- a/src/dictionary.h +++ b/src/dictionary.h @@ -42,7 +42,7 @@ extern "C" { */ /*-------------------------------------------------------------------------*/ typedef struct _dictionary_ { - int n ; /** Number of entries in dictionary */ + unsigned n ; /** Number of entries in dictionary */ size_t size ; /** Storage size */ char ** val ; /** List of string values */ char ** key ; /** List of string keys */ diff --git a/src/iniparser.c b/src/iniparser.c index 725ab11..386686c 100644 --- a/src/iniparser.c +++ b/src/iniparser.c @@ -164,7 +164,7 @@ void iniparser_set_error_callback(int (*errback)(const char *, ...)) /*--------------------------------------------------------------------------*/ int iniparser_getnsec(const dictionary * d) { - int i ; + size_t i ; int nsec ; if (d==NULL) return -1 ; @@ -195,7 +195,7 @@ int iniparser_getnsec(const dictionary * d) /*--------------------------------------------------------------------------*/ const char * iniparser_getsecname(const dictionary * d, int n) { - int i ; + size_t i ; int foundsec ; if (d==NULL || n<0) return NULL ; @@ -230,7 +230,7 @@ const char * iniparser_getsecname(const dictionary * d, int n) /*--------------------------------------------------------------------------*/ void iniparser_dump(const dictionary * d, FILE * f) { - int i ; + size_t i ; if (d==NULL || f==NULL) return ; for (i=0 ; isize ; i++) { @@ -258,8 +258,8 @@ void iniparser_dump(const dictionary * d, FILE * f) /*--------------------------------------------------------------------------*/ void iniparser_dump_ini(const dictionary * d, FILE * f) { - int i ; - int nsec ; + size_t i ; + size_t nsec ; const char * secname ; if (d==NULL || f==NULL) return ; @@ -296,7 +296,7 @@ void iniparser_dump_ini(const dictionary * d, FILE * f) /*--------------------------------------------------------------------------*/ void iniparser_dumpsection_ini(const dictionary * d, const char * s, FILE * f) { - int j ; + size_t j ; char keym[ASCIILINESZ+1]; int seclen ; @@ -332,7 +332,7 @@ int iniparser_getsecnkeys(const dictionary * d, const char * s) { int seclen, nkeys ; char keym[ASCIILINESZ+1]; - int j ; + size_t j ; nkeys = 0; @@ -372,13 +372,13 @@ int iniparser_getsecnkeys(const dictionary * d, const char * s) /*--------------------------------------------------------------------------*/ const char ** iniparser_getseckeys(const dictionary * d, const char * s, const char ** keys) { - int i, j, seclen ; + size_t i, j, seclen ; char keym[ASCIILINESZ+1]; if (d==NULL || keys==NULL) return NULL; if (! iniparser_find_entry(d, s)) return NULL; - seclen = (int)strlen(s); + seclen = strlen(s); strlwc(s, keym, sizeof(keym)); keym[seclen] = ':'; From ae417e100740a4fab19159e3113950a4032fa7a6 Mon Sep 17 00:00:00 2001 From: dofuuz <8174871+dofuuz@users.noreply.github.com> Date: Wed, 22 Jun 2022 15:39:23 +0900 Subject: [PATCH 29/42] Remove more unnecessary includes (especially unistd.h) --- example/iniexample.c | 1 - example/parse.c | 1 - src/dictionary.h | 2 -- src/iniparser.c | 2 ++ src/iniparser.h | 12 ------------ test/test_iniparser.c | 1 - 6 files changed, 2 insertions(+), 17 deletions(-) diff --git a/example/iniexample.c b/example/iniexample.c index 81013f0..f43fab4 100644 --- a/example/iniexample.c +++ b/example/iniexample.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "iniparser.h" diff --git a/example/parse.c b/example/parse.c index 37d07aa..85f8efc 100644 --- a/example/parse.c +++ b/example/parse.c @@ -1,7 +1,6 @@ #include #include #include -#include #include "iniparser.h" diff --git a/src/dictionary.h b/src/dictionary.h index 7b2585f..f459cfe 100644 --- a/src/dictionary.h +++ b/src/dictionary.h @@ -19,8 +19,6 @@ ---------------------------------------------------------------------------*/ #include -#include -#include #ifdef __cplusplus extern "C" { diff --git a/src/iniparser.c b/src/iniparser.c index 386686c..354b673 100644 --- a/src/iniparser.c +++ b/src/iniparser.c @@ -9,6 +9,8 @@ /*---------------------------- Includes ------------------------------------*/ #include #include +#include +#include #include #include "iniparser.h" diff --git a/src/iniparser.h b/src/iniparser.h index 84b92a3..b574078 100644 --- a/src/iniparser.h +++ b/src/iniparser.h @@ -14,18 +14,6 @@ Includes ---------------------------------------------------------------------------*/ -#include -#include -#include -#include - -/* - * The following #include is necessary on many Unixes but not Linux. - * It is not needed for Windows platforms. - * Uncomment it if needed. - */ -/* #include */ - #include "dictionary.h" #ifdef __cplusplus diff --git a/test/test_iniparser.c b/test/test_iniparser.c index a949af2..e2bad69 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include From 7e14b40207bc45ca3d10981747d26279adce0500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Thu, 15 Feb 2024 23:04:46 +0100 Subject: [PATCH 30/42] Add Github workflow to trigger Gitlab CI on pushes --- .github/workflows/trigger-gitlab-ci.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/workflows/trigger-gitlab-ci.yml diff --git a/.github/workflows/trigger-gitlab-ci.yml b/.github/workflows/trigger-gitlab-ci.yml new file mode 100644 index 0000000..3c8fcbf --- /dev/null +++ b/.github/workflows/trigger-gitlab-ci.yml @@ -0,0 +1,11 @@ +name: trigger-gitlab-ci +run-name: ${{ github.event_name }} triggered by ${{ github.actor }} + +on: [push] + +jobs: + trigger-gitlab-ci: + runs-on: ubuntu-latest + steps: + - name: Trigger CI + run: curl -X POST --fail -F token=${{ secrets.trigger_gitlab_ci }} -F ref=main https://gitlab.com/api/v4/projects/54782732/trigger/pipeline From fa33d283674d356011d46e454909639351540261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Thu, 15 Feb 2024 23:17:08 +0100 Subject: [PATCH 31/42] Set the secret as an environment variable in the workflow file --- .github/workflows/trigger-gitlab-ci.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/trigger-gitlab-ci.yml b/.github/workflows/trigger-gitlab-ci.yml index 3c8fcbf..c05fc3e 100644 --- a/.github/workflows/trigger-gitlab-ci.yml +++ b/.github/workflows/trigger-gitlab-ci.yml @@ -5,7 +5,9 @@ on: [push] jobs: trigger-gitlab-ci: - runs-on: ubuntu-latest - steps: - - name: Trigger CI - run: curl -X POST --fail -F token=${{ secrets.trigger_gitlab_ci }} -F ref=main https://gitlab.com/api/v4/projects/54782732/trigger/pipeline + runs-on: ubuntu-latest + steps: + - name: Trigger CI + env: + TRIGGER_GITLAB_CI: ${{ secrets.trigger_gitlab_ci }} + run: curl -X POST --fail -F token=${{ TRIGGER_GITLAB_CI }} -F ref=main https://gitlab.com/api/v4/projects/54782732/trigger/pipeline From 38a8b992b07d4d639f439e3ba320721af17ef4c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Thu, 15 Feb 2024 23:21:25 +0100 Subject: [PATCH 32/42] Revert "Set the secret as an environment variable in the workflow file" This reverts commit fa33d283674d356011d46e454909639351540261. --- .github/workflows/trigger-gitlab-ci.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/trigger-gitlab-ci.yml b/.github/workflows/trigger-gitlab-ci.yml index c05fc3e..3c8fcbf 100644 --- a/.github/workflows/trigger-gitlab-ci.yml +++ b/.github/workflows/trigger-gitlab-ci.yml @@ -5,9 +5,7 @@ on: [push] jobs: trigger-gitlab-ci: - runs-on: ubuntu-latest - steps: - - name: Trigger CI - env: - TRIGGER_GITLAB_CI: ${{ secrets.trigger_gitlab_ci }} - run: curl -X POST --fail -F token=${{ TRIGGER_GITLAB_CI }} -F ref=main https://gitlab.com/api/v4/projects/54782732/trigger/pipeline + runs-on: ubuntu-latest + steps: + - name: Trigger CI + run: curl -X POST --fail -F token=${{ secrets.trigger_gitlab_ci }} -F ref=main https://gitlab.com/api/v4/projects/54782732/trigger/pipeline From c7d01b0d9a2cbcf3b00b7ee1be3a9d4b60825b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Mon, 19 Feb 2024 18:43:12 +0100 Subject: [PATCH 33/42] Include header defining int64_t which is used in the API --- src/iniparser.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/iniparser.h b/src/iniparser.h index b574078..a242cd6 100644 --- a/src/iniparser.h +++ b/src/iniparser.h @@ -15,6 +15,7 @@ ---------------------------------------------------------------------------*/ #include "dictionary.h" +#include #ifdef __cplusplus extern "C" { From 70b21d01add30ae8dcd09f370bb4d85b56d3786c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Sat, 2 Mar 2024 12:10:12 +0100 Subject: [PATCH 34/42] Give macros a descriptive name --- test/test_iniparser.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/test_iniparser.c b/test/test_iniparser.c index 3807ea8..8df9f4f 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -14,10 +14,10 @@ #define GOOD_INI_PATH "ressources/good_ini" #define BAD_INI_PATH "ressources/bad_ini" -#define INI_PATH "ressources/old.ini" -#define INI_PATH_1 "ressources/new.ini" -#define INI_PATH_2 "ressources/test.ini" -#define INI_PATH_3 "ressources/test.txt" +#define OLD_INI_PATH "ressources/old.ini" +#define NEW_INI_PATH "ressources/new.ini" +#define TEST_INI_PATH "ressources/test.ini" +#define TEST_TXT_PATH "ressources/test.txt" #define stringify_2(x) #x #define stringify(x) stringify_2(x) @@ -836,7 +836,7 @@ void Test_iniparser_dump(CuTest *tc) char buff[255]; /*loading old.ini*/ - dic = iniparser_load(INI_PATH); + dic = iniparser_load(OLD_INI_PATH); if(dic ==NULL) { printf("error: old.ini is not exist"); @@ -846,7 +846,7 @@ void Test_iniparser_dump(CuTest *tc) CuAssertStrEquals(tc,"hello world",iniparser_getstring(dic,"section:key_01",NULL)); CuAssertStrEquals(tc,"321abc",iniparser_getstring(dic,"section:key1",NULL)); /*open test.txt*/ - fp = fopen(INI_PATH_3,"w"); + fp = fopen(TEST_TXT_PATH,"w"); if(fp == NULL) { printf("error: test.txt is not exist"); @@ -857,7 +857,7 @@ void Test_iniparser_dump(CuTest *tc) fclose(fp); iniparser_freedict(dic); /*read the data of test.txt*/ - fp = fopen(INI_PATH_3,"r"); + fp = fopen(TEST_TXT_PATH,"r"); if(fp == NULL) { printf("error: test.txt is not exist"); @@ -891,7 +891,7 @@ void Test_iniparser_dump_ini(CuTest *tc) FILE *fp = NULL; /*loading old.ini*/ - dic = iniparser_load(INI_PATH); + dic = iniparser_load(OLD_INI_PATH); if(dic ==NULL) { printf("error: old.ini is not exist"); @@ -901,7 +901,7 @@ void Test_iniparser_dump_ini(CuTest *tc) CuAssertStrEquals(tc,"hello world",iniparser_getstring(dic,"section:key_01",NULL)); CuAssertStrEquals(tc,"321abc",iniparser_getstring(dic,"section:key1",NULL)); /*open new.ini*/ - fp = fopen(INI_PATH_1,"w"); + fp = fopen(NEW_INI_PATH,"w"); if(fp == NULL) { printf("error: new.ini is not exist"); @@ -912,7 +912,7 @@ void Test_iniparser_dump_ini(CuTest *tc) fclose(fp); iniparser_freedict(dic); /*loading new.ini*/ - dic = iniparser_load(INI_PATH_1); + dic = iniparser_load(NEW_INI_PATH); if(dic ==NULL) { printf("error: new.ini is not exist"); @@ -930,7 +930,7 @@ void Test_iniparser_dumpsection_ini(CuTest *tc) FILE *fp = NULL; /*loading old.ini*/ - dic = iniparser_load(INI_PATH); + dic = iniparser_load(OLD_INI_PATH); if(dic ==NULL) { printf("error: old.ini is not exist"); @@ -940,7 +940,7 @@ void Test_iniparser_dumpsection_ini(CuTest *tc) CuAssertStrEquals(tc,"hello world",iniparser_getstring(dic,"section:key_01",NULL)); CuAssertStrEquals(tc,"321abc",iniparser_getstring(dic,"section:key1",NULL)); /*open test.ini*/ - fp = fopen(INI_PATH_2,"w"); + fp = fopen(TEST_INI_PATH,"w"); if(fp == NULL) { printf("error: test.ini is not exist"); @@ -951,7 +951,7 @@ void Test_iniparser_dumpsection_ini(CuTest *tc) fclose(fp); iniparser_freedict(dic); /*loading test.ini*/ - dic = iniparser_load(INI_PATH_2); + dic = iniparser_load(TEST_INI_PATH); if(dic ==NULL) { printf("error: test.ini is not exist"); From b0f58ed1101199c8c0b144295d6c7ac021adcc19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Sat, 2 Mar 2024 17:52:13 +0100 Subject: [PATCH 35/42] Adjust formatting --- test/test_iniparser.c | 51 +++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/test/test_iniparser.c b/test/test_iniparser.c index 8df9f4f..a4c59bc 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -837,21 +837,21 @@ void Test_iniparser_dump(CuTest *tc) /*loading old.ini*/ dic = iniparser_load(OLD_INI_PATH); - if(dic ==NULL) - { + if(dic == NULL) + { printf("error: old.ini is not exist"); exit(-1); - } + } /*check the data of old.ini*/ CuAssertStrEquals(tc,"hello world",iniparser_getstring(dic,"section:key_01",NULL)); CuAssertStrEquals(tc,"321abc",iniparser_getstring(dic,"section:key1",NULL)); /*open test.txt*/ fp = fopen(TEST_TXT_PATH,"w"); if(fp == NULL) - { + { printf("error: test.txt is not exist"); exit(-1); - } + } /*dump the data of old.ini to new.ini*/ iniparser_dump(dic,fp); fclose(fp); @@ -859,28 +859,28 @@ void Test_iniparser_dump(CuTest *tc) /*read the data of test.txt*/ fp = fopen(TEST_TXT_PATH,"r"); if(fp == NULL) - { + { printf("error: test.txt is not exist"); exit(-1); - } + } fgets(buff,100,fp); /*remove '\n'*/ if(buff[strlen(buff)-1] == '\n') - { + { buff[strlen(buff)-1] = '\0'; - } + } CuAssertStrEquals(tc,"[section]=UNDEF",buff); fgets(buff,100,fp); if(buff[strlen(buff)-1] == '\n') - { + { buff[strlen(buff)-1] = '\0'; - } + } CuAssertStrEquals(tc,"[section:key_01]=[hello world]",buff); fgets(buff,100,fp); if(buff[strlen(buff)-1] == '\n') - { + { buff[strlen(buff)-1] = '\0'; - } + } CuAssertStrEquals(tc,"[section:key1]=[321abc]",buff); fclose(fp); } @@ -893,20 +893,20 @@ void Test_iniparser_dump_ini(CuTest *tc) /*loading old.ini*/ dic = iniparser_load(OLD_INI_PATH); if(dic ==NULL) - { + { printf("error: old.ini is not exist"); exit(-1); - } + } /*check the data of old.ini*/ CuAssertStrEquals(tc,"hello world",iniparser_getstring(dic,"section:key_01",NULL)); CuAssertStrEquals(tc,"321abc",iniparser_getstring(dic,"section:key1",NULL)); /*open new.ini*/ fp = fopen(NEW_INI_PATH,"w"); if(fp == NULL) - { + { printf("error: new.ini is not exist"); exit(-1); - } + } /*dump the data of old.ini to new.ini*/ iniparser_dump_ini(dic,fp); fclose(fp); @@ -914,10 +914,10 @@ void Test_iniparser_dump_ini(CuTest *tc) /*loading new.ini*/ dic = iniparser_load(NEW_INI_PATH); if(dic ==NULL) - { + { printf("error: new.ini is not exist"); exit(-1); - } + } /*check the data of new.ini*/ CuAssertStrEquals(tc,"hello world",iniparser_getstring(dic,"section:key_01",NULL)); CuAssertStrEquals(tc,"321abc",iniparser_getstring(dic,"section:key1",NULL)); @@ -932,20 +932,20 @@ void Test_iniparser_dumpsection_ini(CuTest *tc) /*loading old.ini*/ dic = iniparser_load(OLD_INI_PATH); if(dic ==NULL) - { + { printf("error: old.ini is not exist"); exit(-1); - } + } /*check the data of old.ini*/ CuAssertStrEquals(tc,"hello world",iniparser_getstring(dic,"section:key_01",NULL)); CuAssertStrEquals(tc,"321abc",iniparser_getstring(dic,"section:key1",NULL)); /*open test.ini*/ fp = fopen(TEST_INI_PATH,"w"); if(fp == NULL) - { + { printf("error: test.ini is not exist"); exit(-1); - } + } /*dump the data of old.ini to test.ini*/ iniparser_dumpsection_ini(dic,"section",fp); fclose(fp); @@ -953,13 +953,12 @@ void Test_iniparser_dumpsection_ini(CuTest *tc) /*loading test.ini*/ dic = iniparser_load(TEST_INI_PATH); if(dic ==NULL) - { + { printf("error: test.ini is not exist"); exit(-1); - } + } /*check the data of test.ini*/ CuAssertStrEquals(tc,"hello world",iniparser_getstring(dic,"section:key_01",NULL)); CuAssertStrEquals(tc,"321abc",iniparser_getstring(dic,"section:key1",NULL)); iniparser_freedict(dic); } - From 9dfa7feca0807b8f476ed22b000a7c7689ea14af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Sat, 2 Mar 2024 11:03:31 +0100 Subject: [PATCH 36/42] Ignore CMake related files generated by iniparser-meta or cmake --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 8fc7b85..06f9b45 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,8 @@ # Autogenerate source file /test/AllTests.c /test/testrun +# Files generated by iniparser-meta +CMakeLists.txt +config.cmake.in +# CMake build directories +build*/ From 80c9d6f9e0664f508a874226fb48ca9ec3f5ca32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Sat, 2 Mar 2024 21:29:00 +0100 Subject: [PATCH 37/42] Add example showing how to write INI files refs #143 --- example/Makefile | 5 ++- example/iniwrite.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 example/iniwrite.c diff --git a/example/Makefile b/example/Makefile index f09a94e..3bfdb73 100644 --- a/example/Makefile +++ b/example/Makefile @@ -12,11 +12,14 @@ RM ?= rm -f default: all -all: iniexample parse +all: iniexample iniwrite parse iniexample: iniexample.c $(CC) $(CFLAGS) -o iniexample iniexample.c -I../src -L.. -liniparser +iniwrite: iniwrite.c + $(CC) $(CFLAGS) -o iniwrite iniwrite.c -I../src -L.. -liniparser + parse: parse.c $(CC) $(CFLAGS) -o parse parse.c -I../src -L.. -liniparser diff --git a/example/iniwrite.c b/example/iniwrite.c new file mode 100644 index 0000000..e70a14c --- /dev/null +++ b/example/iniwrite.c @@ -0,0 +1,77 @@ +#include "iniparser.h" + +void create_empty_ini_file(void) +{ + FILE *ini; + + if ((ini = fopen("example.ini", "w")) == NULL) { + fprintf(stderr, "iniparser: cannot create example.ini\n"); + return; + } + + fclose(ini); +} + +int write_to_ini(const char *ini_name) +{ + void *dictionary; + FILE *ini_file; + int ret = 0; + + if (!ini_name || !dictionary) { + fprintf(stderr, "Invalid argurment\n"); + return -1; + } + + dictionary = iniparser_load(ini_name); + + if (!dictionary) { + fprintf(stderr, "cannot parse file: %s\n", ini_name); + return -1; + } + + /* set section */ + ret = iniparser_set(dictionary, "Pizza", NULL); + + if (ret < 0) { + fprintf(stderr, "cannot set section in: %s\n", ini_name); + ret = -1; + goto free_dict; + } + + /* set key/value pair */ + ret = iniparser_set(dictionary, "Pizza:Cheese", "TRUE"); + + if (ret < 0) { + fprintf(stderr, "cannot set key/value in: %s\n", ini_name); + ret = -1; + goto free_dict; + } + + ini_file = fopen(ini_name, "w+"); + + if (!ini_file) { + fprintf(stderr, "iniparser: cannot create example.ini\n"); + ret = -1; + goto free_dict; + } + + iniparser_dump_ini(dictionary, ini_file); + fclose(ini_file); +free_dict: + iniparser_freedict(dictionary); + return ret; +} + +int main(int argc, char *argv[]) +{ + int ret; + + if (argc < 2) { + create_empty_ini_file(); + ret = write_to_ini("example.ini"); + } else + ret = write_to_ini(argv[1]); + + return ret ; +} From 5ea02a8338d515301baa946d45a636fd55d3a1e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Sat, 2 Mar 2024 22:05:35 +0100 Subject: [PATCH 38/42] Fix INI write example --- example/iniwrite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/iniwrite.c b/example/iniwrite.c index e70a14c..e9de55a 100644 --- a/example/iniwrite.c +++ b/example/iniwrite.c @@ -18,7 +18,7 @@ int write_to_ini(const char *ini_name) FILE *ini_file; int ret = 0; - if (!ini_name || !dictionary) { + if (!ini_name) { fprintf(stderr, "Invalid argurment\n"); return -1; } From 644b925f91f75d9bd5339de1bbef3013f88c812c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Sat, 2 Mar 2024 23:57:54 +0100 Subject: [PATCH 39/42] Ignore built write example and file it generates --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 06f9b45..5a1e274 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ *.so.* /example/iniexample /example/parse +/example/iniwrite +/example/example.ini # Autogenerate source file /test/AllTests.c /test/testrun From 5a5ff19382bbd69010ce0702067136923c12093c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Sun, 3 Mar 2024 00:00:24 +0100 Subject: [PATCH 40/42] Test UTF-8 and dots in keys refs #67 refs #103 refs #43 --- test/ressources/gruezi.ini | 8 ++++++++ test/ressources/utf8.ini | 10 ++++++++++ test/test_iniparser.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 test/ressources/gruezi.ini create mode 100644 test/ressources/utf8.ini diff --git a/test/ressources/gruezi.ini b/test/ressources/gruezi.ini new file mode 100644 index 0000000..71f5422 --- /dev/null +++ b/test/ressources/gruezi.ini @@ -0,0 +1,8 @@ +# +# Das isch en Biispiel INI Datei +# + +[Chuchichäschtli] + +10.123=example +Gruss=Grüzi diff --git a/test/ressources/utf8.ini b/test/ressources/utf8.ini new file mode 100644 index 0000000..b8e09c7 --- /dev/null +++ b/test/ressources/utf8.ini @@ -0,0 +1,10 @@ +# +# これはiniファイルの例です。 +# + +[拉麺] + +叉焼 = no ; +味噌 = TRUE ; +海苔 = 0 ; +メンマ = そうだね ; diff --git a/test/test_iniparser.c b/test/test_iniparser.c index 3fec87e..dfcad8c 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -18,6 +18,8 @@ #define NEW_INI_PATH "ressources/new.ini" #define TEST_INI_PATH "ressources/test.ini" #define TEST_TXT_PATH "ressources/test.txt" +#define GRUEZI_INI_PATH "ressources/gruezi.ini" +#define UTF8_INI_PATH "ressources/utf8.ini" #define stringify_2(x) #x #define stringify(x) stringify_2(x) @@ -989,3 +991,36 @@ void Test_iniparser_find_entry(CuTest *tc) iniparser_freedict(dic); } + +void Test_iniparser_utf8(CuTest *tc) +{ + dictionary *dic; + + dic = iniparser_load(GRUEZI_INI_PATH); + + if (!dic) { + fprintf(stderr, "cannot parse file: %s\n", GRUEZI_INI_PATH); + return; + } + + /* Generic dictionary */ + CuAssertStrEquals(tc, "example", + iniparser_getstring(dic, "Chuchichäschtli:10.123", NULL)); + CuAssertStrEquals(tc, "Grüzi", + iniparser_getstring(dic, "Chuchichäschtli:Gruss", NULL)); + dictionary_del(dic); + dic = iniparser_load(UTF8_INI_PATH); + + if (!dic) { + fprintf(stderr, "cannot parse file: %s\n", UTF8_INI_PATH); + return; + } + + /* Generic dictionary */ + CuAssertIntEquals(tc, 0, iniparser_getboolean(dic, "拉麺:叉焼", -1)); + CuAssertIntEquals(tc, 1, iniparser_getboolean(dic, "拉麺:味噌", -1)); + CuAssertIntEquals(tc, 0, iniparser_getboolean(dic, "拉麺:海苔", -1)); + CuAssertStrEquals(tc, "そうだね", + iniparser_getstring(dic, "拉麺:メンマ", NULL)); + dictionary_del(dic); +} From 0783d748aec60a5cb27773810e565592137f949b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Sun, 3 Mar 2024 20:44:30 +0100 Subject: [PATCH 41/42] Only run when pushing on master --- .github/workflows/trigger-gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/trigger-gitlab-ci.yml b/.github/workflows/trigger-gitlab-ci.yml index 3c8fcbf..dfd5144 100644 --- a/.github/workflows/trigger-gitlab-ci.yml +++ b/.github/workflows/trigger-gitlab-ci.yml @@ -2,6 +2,8 @@ name: trigger-gitlab-ci run-name: ${{ github.event_name }} triggered by ${{ github.actor }} on: [push] + branches: + - master jobs: trigger-gitlab-ci: From ac87cc7f05cdad46d270add3b21828aa446400ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=B6llendorf?= Date: Sun, 3 Mar 2024 20:47:27 +0100 Subject: [PATCH 42/42] Fix Github action --- .github/workflows/trigger-gitlab-ci.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/trigger-gitlab-ci.yml b/.github/workflows/trigger-gitlab-ci.yml index dfd5144..8cd4d11 100644 --- a/.github/workflows/trigger-gitlab-ci.yml +++ b/.github/workflows/trigger-gitlab-ci.yml @@ -1,9 +1,10 @@ name: trigger-gitlab-ci run-name: ${{ github.event_name }} triggered by ${{ github.actor }} -on: [push] - branches: - - master +on: + push: + branches: + - master jobs: trigger-gitlab-ci: