insert code for reading double numbers from ini-file
Fork of IniFileLib by
IniFile.cpp@3:1f40bfa093d0, 2015-01-07 (annotated)
- Committer:
- kokisan2000
- Date:
- Wed Jan 07 21:52:20 2015 +0000
- Revision:
- 3:1f40bfa093d0
- Parent:
- 2:4ae80a05f6ea
insert code for double numbers in ini-file
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rinosh2 | 0:995403221573 | 1 | /////////////////////////////////////////////////////////////////////////////// |
rinosh2 | 0:995403221573 | 2 | // IniFile: .ini file parser by rinos 2010 |
rinosh2 | 0:995403221573 | 3 | /////////////////////////////////////////////////////////////////////////////// |
kokisan2000 | 3:1f40bfa093d0 | 4 | // 07.01.2015: by DS - insert code for double format |
kokisan2000 | 3:1f40bfa093d0 | 5 | /////////////////////////////////////////////////////////////////////////////// |
rinosh2 | 0:995403221573 | 6 | |
rinosh2 | 0:995403221573 | 7 | #include "IniFile.h" |
rinosh2 | 0:995403221573 | 8 | #include <string.h> |
rinosh2 | 0:995403221573 | 9 | #include <stdlib.h> |
rinosh2 | 0:995403221573 | 10 | |
rinosh2 | 0:995403221573 | 11 | //////////////////////////////////////////////////////////////////////////////// |
rinosh2 | 0:995403221573 | 12 | // defines |
rinosh2 | 0:995403221573 | 13 | const char INI_DELIM[] = " \t\r\n"; |
rinosh2 | 0:995403221573 | 14 | const int INI_LINE_BUF= 256; |
rinosh2 | 0:995403221573 | 15 | |
rinosh2 | 0:995403221573 | 16 | //////////////////////////////////////////////////////////////////////////////// |
rinosh2 | 0:995403221573 | 17 | // IniFile |
rinosh2 | 0:995403221573 | 18 | IniFile::IniFile(const char* file): m_fp(0) { |
rinosh2 | 0:995403221573 | 19 | if(file) open(file); |
rinosh2 | 0:995403221573 | 20 | } |
rinosh2 | 0:995403221573 | 21 | IniFile::~IniFile(){ |
rinosh2 | 0:995403221573 | 22 | close(); |
rinosh2 | 0:995403221573 | 23 | } |
rinosh2 | 0:995403221573 | 24 | |
rinosh2 | 0:995403221573 | 25 | //////////////////////////////////////////////////////////////////////////////// |
rinosh2 | 0:995403221573 | 26 | // internal funcs |
rinosh2 | 0:995403221573 | 27 | IniFile::Status IniFile::strtrim(char* dst, const char* src, int dst_size){ |
rinosh2 | 0:995403221573 | 28 | if(!dst_size) return S_BUFFER_TOO_SHORT; // myStrcpy needs more than 1 byte for '\0'. |
rinosh2 | 0:995403221573 | 29 | |
rinosh2 | 0:995403221573 | 30 | // Find valid string area |
rinosh2 | 0:995403221573 | 31 | const char* p1 = strchr (src, '"'); |
rinosh2 | 0:995403221573 | 32 | const char* p2 = p1? strrchr(++p1, '"') : 0; |
rinosh2 | 0:995403221573 | 33 | if(!p2){ |
rinosh2 | 0:995403221573 | 34 | // trim space or tab |
rinosh2 | 0:995403221573 | 35 | for(p1 = src ; *p1 && strchr(INI_DELIM, *p1) ; p1++); |
rinosh2 | 0:995403221573 | 36 | if(!*p1){ // all char is space or tab |
rinosh2 | 0:995403221573 | 37 | *dst = 0; |
rinosh2 | 0:995403221573 | 38 | return S_SUCCESS; |
rinosh2 | 0:995403221573 | 39 | } |
rinosh2 | 0:995403221573 | 40 | for(p2 = p1 + strlen(p1) ; strchr(INI_DELIM, p2[-1]) ; --p2); |
rinosh2 | 0:995403221573 | 41 | } |
rinosh2 | 0:995403221573 | 42 | |
rinosh2 | 0:995403221573 | 43 | // Check copy size |
rinosh2 | 0:995403221573 | 44 | Status ret; |
rinosh2 | 0:995403221573 | 45 | if(dst_size > p2 - p1){ |
rinosh2 | 0:995403221573 | 46 | dst_size = p2 - p1; |
rinosh2 | 0:995403221573 | 47 | ret = S_SUCCESS; |
rinosh2 | 0:995403221573 | 48 | } else { |
rinosh2 | 0:995403221573 | 49 | dst_size--; |
rinosh2 | 0:995403221573 | 50 | ret = S_BUFFER_TOO_SHORT; |
rinosh2 | 0:995403221573 | 51 | } |
rinosh2 | 0:995403221573 | 52 | |
rinosh2 | 0:995403221573 | 53 | // copy buffer |
rinosh2 | 0:995403221573 | 54 | if(dst != p1) memmove(dst, p1, dst_size); |
rinosh2 | 0:995403221573 | 55 | dst[dst_size] = 0; |
rinosh2 | 0:995403221573 | 56 | return ret; |
rinosh2 | 0:995403221573 | 57 | } |
rinosh2 | 0:995403221573 | 58 | |
rinosh2 | 0:995403221573 | 59 | //////////////////////////////////////////////////////////////////////////////// |
rinosh2 | 0:995403221573 | 60 | // Access methods |
rinosh2 | 0:995403221573 | 61 | IniFile::Status IniFile::open(const char* file){ |
rinosh2 | 0:995403221573 | 62 | close(); |
rinosh2 | 0:995403221573 | 63 | m_fp = fopen(file, "r"); |
rinosh2 | 0:995403221573 | 64 | if(m_fp) return S_SUCCESS; |
rinosh2 | 0:995403221573 | 65 | |
rinosh2 | 0:995403221573 | 66 | //printf("IniFile: Can't open %s\n", file); |
rinosh2 | 0:995403221573 | 67 | return S_OPEN_ERROR; |
rinosh2 | 0:995403221573 | 68 | } |
rinosh2 | 0:995403221573 | 69 | |
rinosh2 | 0:995403221573 | 70 | IniFile::Status IniFile::close(){ |
rinosh2 | 0:995403221573 | 71 | if(!m_fp) return S_NOT_OPENED; |
rinosh2 | 0:995403221573 | 72 | |
rinosh2 | 0:995403221573 | 73 | fclose(m_fp); |
rinosh2 | 0:995403221573 | 74 | m_fp = 0; |
rinosh2 | 0:995403221573 | 75 | return S_SUCCESS; |
rinosh2 | 0:995403221573 | 76 | } |
rinosh2 | 0:995403221573 | 77 | |
rinosh2 | 0:995403221573 | 78 | IniFile::Status IniFile::get(const char* key, char* ret, int ret_size){ |
rinosh2 | 2:4ae80a05f6ea | 79 | if(!m_fp){ |
rinosh2 | 2:4ae80a05f6ea | 80 | printf("IniFile::get %s S_OPEN_ERROR\n", key); |
rinosh2 | 2:4ae80a05f6ea | 81 | return S_OPEN_ERROR; |
rinosh2 | 2:4ae80a05f6ea | 82 | } |
rinosh2 | 0:995403221573 | 83 | |
rinosh2 | 0:995403221573 | 84 | rewind(m_fp); |
rinosh2 | 0:995403221573 | 85 | char line[INI_LINE_BUF]; |
rinosh2 | 0:995403221573 | 86 | while(fgets(line, sizeof(line), m_fp)){ |
rinosh2 | 0:995403221573 | 87 | if(*line == '#') continue; // comment line |
rinosh2 | 0:995403221573 | 88 | |
rinosh2 | 0:995403221573 | 89 | char* p = strchr(line, '='); |
rinosh2 | 0:995403221573 | 90 | if(!p || line == p) continue; // invalid line |
rinosh2 | 0:995403221573 | 91 | |
rinosh2 | 0:995403221573 | 92 | *p++ = 0; |
rinosh2 | 0:995403221573 | 93 | strtrim(line, line, p - line); |
rinosh2 | 2:4ae80a05f6ea | 94 | if(strcmp(line, key)) continue; // different key // stricmp? |
rinosh2 | 0:995403221573 | 95 | |
rinosh2 | 0:995403221573 | 96 | // check data type |
rinosh2 | 0:995403221573 | 97 | switch(ret_size){ |
rinosh2 | 0:995403221573 | 98 | case DTYPE_INT: |
rinosh2 | 0:995403221573 | 99 | strtrim(line, p, INI_LINE_BUF); |
rinosh2 | 0:995403221573 | 100 | *(int*)ret = strtoul(line, &p, 0); |
rinosh2 | 0:995403221573 | 101 | //return p[0]? S_FORMAT_ERROR : S_SUCCESS; // check end |
rinosh2 | 2:4ae80a05f6ea | 102 | printf("IniFile::get %s INT %d\n", key, *(int*)ret); |
rinosh2 | 0:995403221573 | 103 | return S_SUCCESS; // always success |
rinosh2 | 0:995403221573 | 104 | |
rinosh2 | 0:995403221573 | 105 | case DTYPE_BOOL: |
rinosh2 | 0:995403221573 | 106 | strtrim(line, p, INI_LINE_BUF); |
rinosh2 | 0:995403221573 | 107 | switch(line[0]){ |
rinosh2 | 0:995403221573 | 108 | case 'T': |
rinosh2 | 0:995403221573 | 109 | case 't': *(bool*)ret = true; break; |
rinosh2 | 0:995403221573 | 110 | case 'F': |
rinosh2 | 0:995403221573 | 111 | case 'f': *(bool*)ret = false; break; |
rinosh2 | 0:995403221573 | 112 | default: *(bool*)ret = strtoul(line, &p, 0)? true : false; |
rinosh2 | 0:995403221573 | 113 | } |
rinosh2 | 2:4ae80a05f6ea | 114 | printf("IniFile::get %s BOOL %d\n", key, *(bool*)ret); |
rinosh2 | 0:995403221573 | 115 | return S_SUCCESS; |
rinosh2 | 0:995403221573 | 116 | |
kokisan2000 | 3:1f40bfa093d0 | 117 | case DTYPE_DOUBLE: |
kokisan2000 | 3:1f40bfa093d0 | 118 | strtrim(line, p, INI_LINE_BUF); |
kokisan2000 | 3:1f40bfa093d0 | 119 | *(double*)ret = strtod(line, &p); |
kokisan2000 | 3:1f40bfa093d0 | 120 | |
kokisan2000 | 3:1f40bfa093d0 | 121 | printf("IniFile::get %s DOUBLE %f\n", key, *(double*)ret); |
kokisan2000 | 3:1f40bfa093d0 | 122 | return S_SUCCESS; // always success |
kokisan2000 | 3:1f40bfa093d0 | 123 | |
rinosh2 | 0:995403221573 | 124 | default: // string |
rinosh2 | 2:4ae80a05f6ea | 125 | { |
rinosh2 | 2:4ae80a05f6ea | 126 | Status sts = strtrim(ret, p, ret_size); |
rinosh2 | 2:4ae80a05f6ea | 127 | printf("IniFile::get %s = '%s'\n", key, ret_size? ret : "E"); |
rinosh2 | 2:4ae80a05f6ea | 128 | return sts; |
rinosh2 | 2:4ae80a05f6ea | 129 | } |
rinosh2 | 0:995403221573 | 130 | } |
rinosh2 | 0:995403221573 | 131 | } |
rinosh2 | 2:4ae80a05f6ea | 132 | printf("IniFile::get S_NO_KEY'%s'\n", key); |
rinosh2 | 0:995403221573 | 133 | return S_NO_KEY; // No key |
rinosh2 | 0:995403221573 | 134 | } |
rinosh2 | 0:995403221573 | 135 | IniFile::Status IniFile::get(const char* key, int& ret){ |
rinosh2 | 0:995403221573 | 136 | return get(key, (char*)&ret, DTYPE_INT); |
rinosh2 | 0:995403221573 | 137 | } |
rinosh2 | 0:995403221573 | 138 | IniFile::Status IniFile::get(const char* key, bool& ret){ |
rinosh2 | 0:995403221573 | 139 | return get(key, (char*)&ret, DTYPE_BOOL); |
rinosh2 | 0:995403221573 | 140 | } |
kokisan2000 | 3:1f40bfa093d0 | 141 | IniFile::Status IniFile::get(const char* key, double& ret){ |
kokisan2000 | 3:1f40bfa093d0 | 142 | return get(key, (char*)&ret, DTYPE_DOUBLE); |
kokisan2000 | 3:1f40bfa093d0 | 143 | } |
rinosh2 | 1:3601c7feb547 | 144 | IniFile::Status IniFile::get(const IniFile::IniList* inilist){ |
rinosh2 | 0:995403221573 | 145 | Status ret = S_SUCCESS; |
rinosh2 | 0:995403221573 | 146 | for(; inilist->key ; ++inilist){ |
rinosh2 | 0:995403221573 | 147 | Status sts = get(inilist->key, (char*)inilist->buf, inilist->typelen); |
rinosh2 | 0:995403221573 | 148 | switch(sts){ |
rinosh2 | 0:995403221573 | 149 | case S_SUCCESS: |
rinosh2 | 0:995403221573 | 150 | break; |
rinosh2 | 0:995403221573 | 151 | case S_NO_KEY: |
rinosh2 | 0:995403221573 | 152 | ret = sts; // continue |
rinosh2 | 0:995403221573 | 153 | break; |
rinosh2 | 0:995403221573 | 154 | default: |
rinosh2 | 0:995403221573 | 155 | return sts; // fatal error |
rinosh2 | 0:995403221573 | 156 | } |
rinosh2 | 0:995403221573 | 157 | } |
rinosh2 | 0:995403221573 | 158 | return ret; |
rinosh2 | 0:995403221573 | 159 | } |