1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------------
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//  Little Color Management System
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//  Copyright (c) 1998-2012 Marti Maria Saguer
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Permission is hereby granted, free of charge, to any person obtaining
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// a copy of this software and associated documentation files (the "Software"),
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// to deal in the Software without restriction, including without limitation
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// the rights to use, copy, modify, merge, publish, distribute, sublicense,
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// and/or sell copies of the Software, and to permit persons to whom the Software
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// is furnished to do so, subject to the following conditions:
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The above copyright notice and this permission notice shall be included in
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// all copies or substantial portions of the Software.
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------------
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "lcms2_internal.h"
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// IT8.7 / CGATS.17-200x handling -----------------------------------------------------------------------------
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MAXID        128     // Max length of identifier
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MAXSTR      1024     // Max length of string
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MAXTABLES    255     // Max Number of tables in a single stream
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MAXINCLUDE    20     // Max number of nested includes
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define DEFAULT_DBL_FORMAT  "%.10g" // Double formatting
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef CMS_IS_WINDOWS_
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//sunliang.liu modified 2010426 for wince error
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#	ifndef _WIN32_WCE
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#		include <io.h>
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#	endif
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#    define DIR_CHAR    '\\'
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#    define DIR_CHAR    '/'
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Symbols
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef enum {
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SNONE,
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SINUM,      // Integer
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SDNUM,      // Real
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SIDENT,     // Identifier
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SSTRING,    // string
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SCOMMENT,   // comment
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SEOLN,      // End of line
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SEOF,       // End of stream
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SSYNERROR,  // Syntax error found on stream
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // Keywords
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SBEGIN_DATA,
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SBEGIN_DATA_FORMAT,
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SEND_DATA,
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SEND_DATA_FORMAT,
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SKEYWORD,
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SDATA_FORMAT_ID,
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SINCLUDE
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } SYMBOL;
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// How to write the value
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef enum {
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        WRITE_UNCOOKED,
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        WRITE_STRINGIFY,
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        WRITE_HEXADECIMAL,
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        WRITE_BINARY,
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        WRITE_PAIR
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } WRITEMODE;
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Linked list of variable names
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct _KeyVal {
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        struct _KeyVal*  Next;
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        char*            Keyword;       // Name of variable
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        struct _KeyVal*  NextSubkey;    // If key is a dictionary, points to the next item
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        char*            Subkey;        // If key is a dictionary, points to the subkey name
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        char*            Value;         // Points to value
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        WRITEMODE        WriteAs;       // How to write the value
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   } KEYVALUE;
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Linked list of memory chunks (Memory sink)
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct _OwnedMem {
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        struct _OwnedMem* Next;
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        void *            Ptr;          // Point to value
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   } OWNEDMEM;
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Suballocator
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct _SubAllocator {
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         cmsUInt8Number* Block;
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         cmsUInt32Number BlockSize;
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         cmsUInt32Number Used;
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } SUBALLOCATOR;
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Table. Each individual table can hold properties and rows & cols
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct _Table {
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        char SheetType[MAXSTR];               // The first row of the IT8 (the type)
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int            nSamples, nPatches;    // Cols, Rows
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int            SampleID;              // Pos of ID
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        KEYVALUE*      HeaderList;            // The properties
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        char**         DataFormat;            // The binary stream descriptor
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        char**         Data;                  // The binary stream
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } TABLE;
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// File stream being parsed
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct _FileContext {
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        char           FileName[cmsMAX_PATH];    // File name if being readed from file
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FILE*          Stream;                   // File stream or NULL if holded in memory
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } FILECTX;
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This struct hold all information about an open IT8 handler.
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct {
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsUInt32Number  TablesCount;                     // How many tables in this stream
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsUInt32Number  nTable;                          // The actual table
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        TABLE Tab[MAXTABLES];
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // Memory management
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        OWNEDMEM*      MemorySink;            // The storage backend
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SUBALLOCATOR   Allocator;             // String suballocator -- just to keep it fast
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // Parser state machine
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SYMBOL         sy;                    // Current symbol
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int            ch;                    // Current character
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int            inum;                  // integer value
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsFloat64Number         dnum;                  // real value
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        char           id[MAXID];             // identifier
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        char           str[MAXSTR];           // string
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // Allowed keywords & datasets. They have visibility on whole stream
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        KEYVALUE*     ValidKeywords;
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        KEYVALUE*     ValidSampleID;
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        char*          Source;                // Points to loc. being parsed
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int            lineno;                // line counter for error reporting
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FILECTX*       FileStack[MAXINCLUDE]; // Stack of files being parsed
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int            IncludeSP;             // Include Stack Pointer
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        char*          MemoryBlock;           // The stream if holded in memory
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        char           DoubleFormatter[MAXID];// Printf-like 'cmsFloat64Number' formatter
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsContext    ContextID;              // The threading context
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   } cmsIT8;
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The stream for save operations
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct {
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FILE* stream;   // For save-to-file behaviour
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsUInt8Number* Base;
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsUInt8Number* Ptr;        // For save-to-mem behaviour
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsUInt32Number Used;
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsUInt32Number Max;
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } SAVESTREAM;
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ------------------------------------------------------ cmsIT8 parsing routines
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// A keyword
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct {
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        const char *id;
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SYMBOL sy;
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   } KEYWORD;
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The keyword->symbol translation table. Sorting is required.
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const KEYWORD TabKeys[] = {
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"$INCLUDE",               SINCLUDE},   // This is an extension!
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {".INCLUDE",               SINCLUDE},   // This is an extension!
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"BEGIN_DATA",             SBEGIN_DATA },
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"BEGIN_DATA_FORMAT",      SBEGIN_DATA_FORMAT },
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"DATA_FORMAT_IDENTIFIER", SDATA_FORMAT_ID},
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"END_DATA",               SEND_DATA},
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"END_DATA_FORMAT",        SEND_DATA_FORMAT},
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"KEYWORD",                SKEYWORD}
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        };
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define NUMKEYS (sizeof(TabKeys)/sizeof(KEYWORD))
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Predefined properties
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// A property
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct {
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        const char *id;    // The identifier
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        WRITEMODE as;      // How is supposed to be written
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } PROPERTY;
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic PROPERTY PredefinedProperties[] = {
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"NUMBER_OF_FIELDS", WRITE_UNCOOKED},    // Required - NUMBER OF FIELDS
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"NUMBER_OF_SETS",   WRITE_UNCOOKED},    // Required - NUMBER OF SETS
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"ORIGINATOR",       WRITE_STRINGIFY},   // Required - Identifies the specific system, organization or individual that created the data file.
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"FILE_DESCRIPTOR",  WRITE_STRINGIFY},   // Required - Describes the purpose or contents of the data file.
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"CREATED",          WRITE_STRINGIFY},   // Required - Indicates date of creation of the data file.
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"DESCRIPTOR",       WRITE_STRINGIFY},   // Required  - Describes the purpose or contents of the data file.
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"DIFFUSE_GEOMETRY", WRITE_STRINGIFY},   // The diffuse geometry used. Allowed values are "sphere" or "opal".
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"MANUFACTURER",     WRITE_STRINGIFY},
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"MANUFACTURE",      WRITE_STRINGIFY},   // Some broken Fuji targets does store this value
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"PROD_DATE",        WRITE_STRINGIFY},   // Identifies year and month of production of the target in the form yyyy:mm.
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"SERIAL",           WRITE_STRINGIFY},   // Uniquely identifies individual physical target.
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"MATERIAL",         WRITE_STRINGIFY},   // Identifies the material on which the target was produced using a code
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // uniquely identifying th e material. This is intend ed to be used for IT8.7
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // physical targets only (i.e . IT8.7/1 a nd IT8.7/2).
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"INSTRUMENTATION",  WRITE_STRINGIFY},   // Used to report the specific instrumentation used (manufacturer and
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // model number) to generate the data reported. This data will often
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // provide more information about the particular data collected than an
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // extensive list of specific details. This is particularly important for
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // spectral data or data derived from spectrophotometry.
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"MEASUREMENT_SOURCE", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // a guide to the potential for issues of paper fluorescence, etc.
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"PRINT_CONDITIONS", WRITE_STRINGIFY},   // Used to define the characteristics of the printed sheet being reported.
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // Where standard conditions have been defined (e.g., SWOP at nominal)
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // named conditions may suffice. Otherwise, detailed information is
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // needed.
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"SAMPLE_BACKING",   WRITE_STRINGIFY},   // Identifies the backing material used behind the sample during
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // measurement. Allowed values are �black? �white? or {"na".
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"CHISQ_DOF",        WRITE_STRINGIFY},   // Degrees of freedom associated with the Chi squared statistic
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       // below properties are new in recent specs:
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {"MEASUREMENT_GEOMETRY", WRITE_STRINGIFY}, // The type of measurement, either reflection or transmission, should be indicated
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // along with details of the geometry and the aperture size and shape. For example,
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // for transmission measurements it is important to identify 0/diffuse, diffuse/0,
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // opal or integrating sphere, etc. For reflection it is important to identify 0/45,
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // 45/0, sphere (specular included or excluded), etc.
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       {"FILTER",            WRITE_STRINGIFY},   // Identifies the use of physical filter(s) during measurement. Typically used to
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // denote the use of filters such as none, D65, Red, Green or Blue.
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       {"POLARIZATION",      WRITE_STRINGIFY},   // Identifies the use of a physical polarization filter during measurement. Allowed
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // values are {"yes? �white? �none?or �na?
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       {"WEIGHTING_FUNCTION", WRITE_PAIR},   // Indicates such functions as: the CIE standard observer functions used in the
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // calculation of various data parameters (2 degree and 10 degree), CIE standard
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // illuminant functions used in the calculation of various data parameters (e.g., D50,
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // D65, etc.), density status response, etc. If used there shall be at least one
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // name-value pair following the WEIGHTING_FUNCTION tag/keyword. The first attribute
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // in the set shall be {"name" and shall identify the particular parameter used.
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // The second shall be {"value" and shall provide the value associated with that name.
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // For ASCII data, a string containing the Name and Value attribute pairs shall follow
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // the weighting function keyword. A semi-colon separates attribute pairs from each
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // other and within the attribute the name and value are separated by a comma.
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       {"COMPUTATIONAL_PARAMETER", WRITE_PAIR}, // Parameter that is used in computing a value from measured data. Name is the name
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // of the calculation, parameter is the name of the parameter used in the calculation
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               // and value is the value of the parameter.
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       {"TARGET_TYPE",        WRITE_STRINGIFY},  // The type of target being measured, e.g. IT8.7/1, IT8.7/3, user defined, etc.
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       {"COLORANT",           WRITE_STRINGIFY},  // Identifies the colorant(s) used in creating the target.
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       {"TABLE_DESCRIPTOR",   WRITE_STRINGIFY},  // Describes the purpose or contents of a data table.
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       {"TABLE_NAME",         WRITE_STRINGIFY}   // Provides a short name for a data table.
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define NUMPREDEFINEDPROPS (sizeof(PredefinedProperties)/sizeof(PROPERTY))
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Predefined sample types on dataset
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const char* PredefinedSampleID[] = {
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "SAMPLE_ID",      // Identifies sample that data represents
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "STRING",         // Identifies label, or other non-machine readable value.
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          // Value must begin and end with a " symbol
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "CMYK_C",         // Cyan component of CMYK data expressed as a percentage
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "CMYK_M",         // Magenta component of CMYK data expressed as a percentage
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "CMYK_Y",         // Yellow component of CMYK data expressed as a percentage
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "CMYK_K",         // Black component of CMYK data expressed as a percentage
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "D_RED",          // Red filter density
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "D_GREEN",        // Green filter density
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "D_BLUE",         // Blue filter density
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "D_VIS",          // Visual filter density
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "D_MAJOR_FILTER", // Major filter d ensity
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "RGB_R",          // Red component of RGB data
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "RGB_G",          // Green component of RGB data
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "RGB_B",          // Blue com ponent of RGB data
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "SPECTRAL_NM",    // Wavelength of measurement expressed in nanometers
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "SPECTRAL_PCT",   // Percentage reflectance/transmittance
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "SPECTRAL_DEC",   // Reflectance/transmittance
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "XYZ_X",          // X component of tristimulus data
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "XYZ_Y",          // Y component of tristimulus data
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "XYZ_Z",          // Z component of tristimulus data
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "XYY_X"           // x component of chromaticity data
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "XYY_Y",          // y component of chromaticity data
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "XYY_CAPY",       // Y component of tristimulus data
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "LAB_L",          // L* component of Lab data
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "LAB_A",          // a* component of Lab data
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "LAB_B",          // b* component of Lab data
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "LAB_C",          // C*ab component of Lab data
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "LAB_H",          // hab component of Lab data
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "LAB_DE",         // CIE dE
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "LAB_DE_94",      // CIE dE using CIE 94
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "LAB_DE_CMC",     // dE using CMC
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "LAB_DE_2000",    // CIE dE using CIE DE 2000
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "MEAN_DE",        // Mean Delta E (LAB_DE) of samples compared to batch average
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          // (Used for data files for ANSI IT8.7/1 and IT8.7/2 targets)
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "STDEV_X",        // Standard deviation of X (tristimulus data)
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "STDEV_Y",        // Standard deviation of Y (tristimulus data)
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "STDEV_Z",        // Standard deviation of Z (tristimulus data)
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "STDEV_L",        // Standard deviation of L*
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "STDEV_A",        // Standard deviation of a*
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "STDEV_B",        // Standard deviation of b*
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "STDEV_DE",       // Standard deviation of CIE dE
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        "CHI_SQD_PAR"};   // The average of the standard deviations of L*, a* and b*. It is
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          // used to derive an estimate of the chi-squared parameter which is
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          // recommended as the predictor of the variability of dE
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define NUMPREDEFINEDSAMPLEID (sizeof(PredefinedSampleID)/sizeof(char *))
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//Forward declaration of some internal functions
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void* AllocChunk(cmsIT8* it8, cmsUInt32Number size);
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Checks whatever c is a separator
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool isseparator(int c)
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (c == ' ') || (c == '\t') ;
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Checks whatever c is a valid identifier char
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool ismiddle(int c)
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   return (!isseparator(c) && (c != '#') && (c !='\"') && (c != '\'') && (c > 32) && (c < 127));
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Checks whatsever c is a valid identifier middle char.
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool isidchar(int c)
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   return isalnum(c) || ismiddle(c);
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Checks whatsever c is a valid identifier first char.
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool isfirstidchar(int c)
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     return !isdigit(c) && ismiddle(c);
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Guess whether the supplied path looks like an absolute path
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool isabsolutepath(const char *path)
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char ThreeChars[4];
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(path == NULL)
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (path[0] == 0)
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strncpy(ThreeChars, path, 3);
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ThreeChars[3] = 0;
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(ThreeChars[0] == DIR_CHAR)
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef  CMS_IS_WINDOWS_
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (isalpha((int) ThreeChars[0]) && ThreeChars[1] == ':')
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Makes a file path based on a given reference path
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// NOTE: this function doesn't check if the path exists or even if it's legal
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool BuildAbsolutePath(const char *relPath, const char *basePath, char *buffer, cmsUInt32Number MaxLen)
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char *tail;
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number len;
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Already absolute?
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (isabsolutepath(relPath)) {
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strncpy(buffer, relPath, MaxLen);
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        buffer[MaxLen-1] = 0;
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // No, search for last
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strncpy(buffer, basePath, MaxLen);
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    buffer[MaxLen-1] = 0;
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    tail = strrchr(buffer, DIR_CHAR);
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (tail == NULL) return FALSE;    // Is not absolute and has no separators??
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    len = (cmsUInt32Number) (tail - buffer);
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (len >= MaxLen) return FALSE;
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // No need to assure zero terminator over here
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strncpy(tail + 1, relPath, MaxLen - len);
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Make sure no exploit is being even tried
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst char* NoMeta(const char* str)
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strchr(str, '%') != NULL)
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return "**** CORRUPTED FORMAT STRING ***";
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return str;
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Syntax error
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool SynError(cmsIT8* it8, const char *Txt, ...)
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char Buffer[256], ErrMsg[1024];
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    va_list args;
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    va_start(args, Txt);
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    vsnprintf(Buffer, 255, Txt, args);
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Buffer[255] = 0;
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    va_end(args);
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    snprintf(ErrMsg, 1023, "%s: Line %d, %s", it8->FileStack[it8 ->IncludeSP]->FileName, it8->lineno, Buffer);
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ErrMsg[1023] = 0;
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->sy = SSYNERROR;
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsSignalError(it8 ->ContextID, cmsERROR_CORRUPTION_DETECTED, "%s", ErrMsg);
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Check if current symbol is same as specified. issue an error else.
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Check(cmsIT8* it8, SYMBOL sy, const char* Err)
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (it8 -> sy != sy)
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return SynError(it8, NoMeta(Err));
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Read Next character from stream
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid NextCh(cmsIT8* it8)
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (it8 -> FileStack[it8 ->IncludeSP]->Stream) {
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        it8 ->ch = fgetc(it8 ->FileStack[it8 ->IncludeSP]->Stream);
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (feof(it8 -> FileStack[it8 ->IncludeSP]->Stream))  {
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (it8 ->IncludeSP > 0) {
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                fclose(it8 ->FileStack[it8->IncludeSP--]->Stream);
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                it8 -> ch = ' ';                            // Whitespace to be ignored
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                it8 ->ch = 0;   // EOF
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else {
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        it8->ch = *it8->Source;
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (it8->ch) it8->Source++;
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Try to see if current identifier is a keyword, if so return the referred symbol
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovSYMBOL BinSrchKey(const char *id)
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int l = 1;
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int r = NUMKEYS;
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int x, res;
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (r >= l)
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        x = (l+r)/2;
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        res = cmsstrcasecmp(id, TabKeys[x-1].id);
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (res == 0) return TabKeys[x-1].sy;
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (res < 0) r = x - 1;
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else l = x + 1;
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return SNONE;
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 10 ^n
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsFloat64Number xpow10(int n)
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pow(10, (cmsFloat64Number) n);
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//  Reads a Real number, tries to follow from integer number
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid ReadReal(cmsIT8* it8, int inum)
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->dnum = (cmsFloat64Number) inum;
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (isdigit(it8->ch)) {
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        it8->dnum = it8->dnum * 10.0 + (it8->ch - '0');
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        NextCh(it8);
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (it8->ch == '.') {        // Decimal point
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsFloat64Number frac = 0.0;      // fraction
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int prec = 0;                     // precision
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        NextCh(it8);               // Eats dec. point
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (isdigit(it8->ch)) {
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            frac = frac * 10.0 + (it8->ch - '0');
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            prec++;
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NextCh(it8);
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        it8->dnum = it8->dnum + (frac / xpow10(prec));
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Exponent, example 34.00E+20
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (toupper(it8->ch) == 'E') {
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int e;
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int sgn;
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        NextCh(it8); sgn = 1;
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (it8->ch == '-') {
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            sgn = -1; NextCh(it8);
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (it8->ch == '+') {
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                sgn = +1;
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NextCh(it8);
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            e = 0;
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            while (isdigit(it8->ch)) {
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if ((cmsFloat64Number) e * 10L < INT_MAX)
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    e = e * 10 + (it8->ch - '0');
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NextCh(it8);
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            e = sgn*e;
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            it8 -> dnum = it8 -> dnum * xpow10(e);
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Parses a float number
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This can not call directly atof because it uses locale dependant
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// parsing, while CCMX files always use . as decimal separator
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsFloat64Number ParseFloatNumber(const char *Buffer)
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsFloat64Number dnum = 0.0;
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int sign = 1;
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // keep safe
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (Buffer == NULL) return 0.0;
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (*Buffer == '-' || *Buffer == '+') {
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         sign = (*Buffer == '-') ? -1 : 1;
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         Buffer++;
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (*Buffer && isdigit((int) *Buffer)) {
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dnum = dnum * 10.0 + (*Buffer - '0');
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (*Buffer) Buffer++;
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (*Buffer == '.') {
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsFloat64Number frac = 0.0;      // fraction
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int prec = 0;                     // precission
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (*Buffer) Buffer++;
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (*Buffer && isdigit((int) *Buffer)) {
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            frac = frac * 10.0 + (*Buffer - '0');
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            prec++;
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (*Buffer) Buffer++;
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dnum = dnum + (frac / xpow10(prec));
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Exponent, example 34.00E+20
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (*Buffer && toupper(*Buffer) == 'E') {
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int e;
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int sgn;
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (*Buffer) Buffer++;
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        sgn = 1;
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (*Buffer == '-') {
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            sgn = -1;
655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (*Buffer) Buffer++;
656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else
658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (*Buffer == '+') {
659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                sgn = +1;
661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (*Buffer) Buffer++;
662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            e = 0;
665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            while (*Buffer && isdigit((int) *Buffer)) {
666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if ((cmsFloat64Number) e * 10L < INT_MAX)
668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    e = e * 10 + (*Buffer - '0');
669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (*Buffer) Buffer++;
671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            e = sgn*e;
674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dnum = dnum * xpow10(e);
675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return sign * dnum;
678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Reads next symbol
682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid InSymbol(cmsIT8* it8)
684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    register char *idptr;
686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    register int k;
687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    SYMBOL key;
688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int sng;
689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    do {
691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (isseparator(it8->ch))
693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NextCh(it8);
694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (isfirstidchar(it8->ch)) {          // Identifier
696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            k = 0;
698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            idptr = it8->id;
699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            do {
701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (++k < MAXID) *idptr++ = (char) it8->ch;
703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NextCh(it8);
705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } while (isidchar(it8->ch));
707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *idptr = '\0';
709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            key = BinSrchKey(it8->id);
712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (key == SNONE) it8->sy = SIDENT;
713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            else it8->sy = key;
714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else                         // Is a number?
717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (isdigit(it8->ch) || it8->ch == '.' || it8->ch == '-' || it8->ch == '+')
718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            {
719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int sign = 1;
720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (it8->ch == '-') {
722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    sign = -1;
723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    NextCh(it8);
724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                it8->inum = 0;
727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                it8->sy   = SINUM;
728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (it8->ch == '0') {          // 0xnnnn (Hexa) or 0bnnnn (Binary)
730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    NextCh(it8);
732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (toupper(it8->ch) == 'X') {
733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        int j;
735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        NextCh(it8);
737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        while (isxdigit(it8->ch))
738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        {
739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            it8->ch = toupper(it8->ch);
740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            if (it8->ch >= 'A' && it8->ch <= 'F')  j = it8->ch -'A'+10;
741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            else j = it8->ch - '0';
742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            if ((long) it8->inum * 16L > (long) INT_MAX)
744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            {
745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                SynError(it8, "Invalid hexadecimal number");
746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                return;
747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            }
748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            it8->inum = it8->inum * 16 + j;
750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            NextCh(it8);
751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        }
752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return;
753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (toupper(it8->ch) == 'B') {  // Binary
756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        int j;
758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        NextCh(it8);
760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        while (it8->ch == '0' || it8->ch == '1')
761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        {
762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            j = it8->ch - '0';
763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            if ((long) it8->inum * 2L > (long) INT_MAX)
765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            {
766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                SynError(it8, "Invalid binary number");
767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                return;
768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            }
769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            it8->inum = it8->inum * 2 + j;
771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            NextCh(it8);
772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        }
773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return;
774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                while (isdigit(it8->ch)) {
779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if ((long) it8->inum * 10L > (long) INT_MAX) {
781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        ReadReal(it8, it8->inum);
782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        it8->sy = SDNUM;
783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        it8->dnum *= sign;
784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return;
785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    it8->inum = it8->inum * 10 + (it8->ch - '0');
788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    NextCh(it8);
789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (it8->ch == '.') {
792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    ReadReal(it8, it8->inum);
794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    it8->sy = SDNUM;
795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    it8->dnum *= sign;
796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return;
797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                it8 -> inum *= sign;
800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                // Special case. Numbers followed by letters are taken as identifiers
802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (isidchar(it8 ->ch)) {
804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (it8 ->sy == SINUM) {
806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        sprintf(it8->id, "%d", it8->inum);
808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    else {
810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        sprintf(it8->id, it8 ->DoubleFormatter, it8->dnum);
812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    k = (int) strlen(it8 ->id);
815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    idptr = it8 ->id + k;
816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    do {
817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        if (++k < MAXID) *idptr++ = (char) it8->ch;
819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        NextCh(it8);
821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } while (isidchar(it8->ch));
823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *idptr = '\0';
825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    it8->sy = SIDENT;
826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return;
828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            else
831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                switch ((int) it8->ch) {
832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // EOF marker -- ignore it
834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case '\x1a':
835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NextCh(it8);
836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // Eof stream markers
839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case 0:
840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case -1:
841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            it8->sy = SEOF;
842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // Next line
846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case '\r':
847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NextCh(it8);
848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (it8 ->ch == '\n')
849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NextCh(it8);
850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            it8->sy = SEOLN;
851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            it8->lineno++;
852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case '\n':
855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NextCh(it8);
856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            it8->sy = SEOLN;
857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            it8->lineno++;
858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // Comment
861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case '#':
862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NextCh(it8);
863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            while (it8->ch && it8->ch != '\n' && it8->ch != '\r')
864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NextCh(it8);
865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            it8->sy = SCOMMENT;
867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // String.
870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case '\'':
871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case '\"':
872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            idptr = it8->str;
873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            sng = it8->ch;
874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            k = 0;
875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NextCh(it8);
876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            while (k < MAXSTR && it8->ch != sng) {
878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (it8->ch == '\n'|| it8->ch == '\r') k = MAXSTR+1;
880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                else {
881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *idptr++ = (char) it8->ch;
882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    NextCh(it8);
883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    k++;
884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            it8->sy = SSTRING;
888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *idptr = '\0';
889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NextCh(it8);
890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        default:
894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            SynError(it8, "Unrecognized character: 0x%x", it8 ->ch);
895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } while (it8->sy == SCOMMENT);
899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Handle the include special token
901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (it8 -> sy == SINCLUDE) {
903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FILECTX* FileNest;
905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if(it8 -> IncludeSP >= (MAXINCLUDE-1)) {
907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    SynError(it8, "Too many recursion levels");
909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return;
910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                InSymbol(it8);
913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!Check(it8, SSTRING, "Filename expected")) return;
914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FileNest = it8 -> FileStack[it8 -> IncludeSP + 1];
916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if(FileNest == NULL) {
917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FileNest = it8 ->FileStack[it8 -> IncludeSP + 1] = (FILECTX*)AllocChunk(it8, sizeof(FILECTX));
919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    //if(FileNest == NULL)
920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    //  TODO: how to manage out-of-memory conditions?
921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (BuildAbsolutePath(it8->str,
924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      it8->FileStack[it8->IncludeSP]->FileName,
925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      FileNest->FileName, cmsMAX_PATH-1) == FALSE) {
926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    SynError(it8, "File path too long");
927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return;
928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FileNest->Stream = fopen(FileNest->FileName, "rt");
931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (FileNest->Stream == NULL) {
932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        SynError(it8, "File %s not found", FileNest->FileName);
934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return;
935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                it8->IncludeSP++;
937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                it8 ->ch = ' ';
939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                InSymbol(it8);
940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Checks end of line separator
945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
946ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CheckEOLN(cmsIT8* it8)
947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!Check(it8, SEOLN, "Expected separator")) return FALSE;
949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (it8 -> sy == SEOLN)
950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        InSymbol(it8);
951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Skip a symbol
956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Skip(cmsIT8* it8, SYMBOL sy)
959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (it8->sy == sy && it8->sy != SEOF)
961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        InSymbol(it8);
962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Skip multiple EOLN
966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid SkipEOLN(cmsIT8* it8)
968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (it8->sy == SEOLN) {
970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov             InSymbol(it8);
971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Returns a string holding current value
976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
977ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool GetVal(cmsIT8* it8, char* Buffer, cmsUInt32Number max, const char* ErrorTitle)
978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    switch (it8->sy) {
980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    case SEOLN:   // Empty value
982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  Buffer[0]=0;
983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  break;
984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    case SIDENT:  strncpy(Buffer, it8->id, max);
985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  Buffer[max-1]=0;
986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  break;
987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    case SINUM:   snprintf(Buffer, max, "%d", it8 -> inum); break;
988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    case SDNUM:   snprintf(Buffer, max, it8->DoubleFormatter, it8 -> dnum); break;
989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    case SSTRING: strncpy(Buffer, it8->str, max);
990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  Buffer[max-1] = 0;
991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  break;
992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    default:
995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         return SynError(it8, "%s", ErrorTitle);
996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Buffer[max] = 0;
999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ---------------------------------------------------------- Table
1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovTABLE* GetTable(cmsIT8* it8)
1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   if ((it8 -> nTable >= it8 ->TablesCount)) {
1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov           SynError(it8, "Table %d out of sequence", it8 -> nTable);
1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov           return it8 -> Tab;
1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   }
1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   return it8 ->Tab + it8 ->nTable;
1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ---------------------------------------------------------- Memory management
1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Frees an allocator and owned memory
1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT cmsIT8Free(cmsHANDLE hIT8)
1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   cmsIT8* it8 = (cmsIT8*) hIT8;
1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (it8 == NULL)
1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (it8->MemorySink) {
1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        OWNEDMEM* p;
1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        OWNEDMEM* n;
1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (p = it8->MemorySink; p != NULL; p = n) {
1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            n = p->Next;
1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (p->Ptr) _cmsFree(it8 ->ContextID, p->Ptr);
1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _cmsFree(it8 ->ContextID, p);
1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (it8->MemoryBlock)
1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _cmsFree(it8 ->ContextID, it8->MemoryBlock);
1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsFree(it8 ->ContextID, it8);
1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Allocates a chunk of data, keep linked list
1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* AllocBigBlock(cmsIT8* it8, cmsUInt32Number size)
1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    OWNEDMEM* ptr1;
1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void* ptr = _cmsMallocZero(it8->ContextID, size);
1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ptr != NULL) {
1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ptr1 = (OWNEDMEM*) _cmsMallocZero(it8 ->ContextID, sizeof(OWNEDMEM));
1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (ptr1 == NULL) {
1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _cmsFree(it8 ->ContextID, ptr);
1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return NULL;
1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ptr1-> Ptr        = ptr;
1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ptr1-> Next       = it8 -> MemorySink;
1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        it8 -> MemorySink = ptr1;
1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ptr;
1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Suballocator.
1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* AllocChunk(cmsIT8* it8, cmsUInt32Number size)
1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number Free = it8 ->Allocator.BlockSize - it8 ->Allocator.Used;
1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt8Number* ptr;
1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    size = _cmsALIGNMEM(size);
1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (size > Free) {
1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (it8 -> Allocator.BlockSize == 0)
1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                it8 -> Allocator.BlockSize = 20*1024;
1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else
1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                it8 ->Allocator.BlockSize *= 2;
1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (it8 ->Allocator.BlockSize < size)
1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                it8 ->Allocator.BlockSize = size;
1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        it8 ->Allocator.Used = 0;
1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        it8 ->Allocator.Block = (cmsUInt8Number*)  AllocBigBlock(it8, it8 ->Allocator.BlockSize);
1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ptr = it8 ->Allocator.Block + it8 ->Allocator.Used;
1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 ->Allocator.Used += size;
1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (void*) ptr;
1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Allocates a string
1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovchar *AllocString(cmsIT8* it8, const char* str)
1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number Size = (cmsUInt32Number) strlen(str)+1;
1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char *ptr;
1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ptr = (char *) AllocChunk(it8, Size);
1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ptr) strncpy (ptr, str, Size-1);
1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ptr;
1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Searches through linked list
1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool IsAvailableOnList(KEYVALUE* p, const char* Key, const char* Subkey, KEYVALUE** LastPtr)
1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (LastPtr) *LastPtr = p;
1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (;  p != NULL; p = p->Next) {
1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (LastPtr) *LastPtr = p;
1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (*Key != '#') { // Comments are ignored
1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (cmsstrcasecmp(Key, p->Keyword) == 0)
1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (p == NULL)
1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (Subkey == 0)
1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (; p != NULL; p = p->NextSubkey) {
1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (p ->Subkey == NULL) continue;
1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (LastPtr) *LastPtr = p;
1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (cmsstrcasecmp(Subkey, p->Subkey) == 0)
1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return TRUE;
1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Add a property into a linked list
1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovKEYVALUE* AddToList(cmsIT8* it8, KEYVALUE** Head, const char *Key, const char *Subkey, const char* xValue, WRITEMODE WriteAs)
1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    KEYVALUE* p;
1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    KEYVALUE* last;
1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Check if property is already in list
1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (IsAvailableOnList(*Head, Key, Subkey, &p)) {
1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // This may work for editing properties
1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        //     return SynError(it8, "duplicate key <%s>", Key);
1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else {
1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        last = p;
1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // Allocate the container
1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        p = (KEYVALUE*) AllocChunk(it8, sizeof(KEYVALUE));
1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (p == NULL)
1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {
1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            SynError(it8, "AddToList: out of memory");
1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return NULL;
1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // Store name and value
1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        p->Keyword = AllocString(it8, Key);
1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        p->Subkey = (Subkey == NULL) ? NULL : AllocString(it8, Subkey);
1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // Keep the container in our list
1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (*Head == NULL) {
1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *Head = p;
1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else
1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {
1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (Subkey != NULL && last != NULL) {
1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                last->NextSubkey = p;
1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                // If Subkey is not null, then last is the last property with the same key,
1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                // but not necessarily is the last property in the list, so we need to move
1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                // to the actual list end
1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                while (last->Next != NULL)
1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         last = last->Next;
1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (last != NULL) last->Next = p;
1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        p->Next    = NULL;
1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        p->NextSubkey = NULL;
1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    p->WriteAs = WriteAs;
1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (xValue != NULL) {
1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        p->Value   = AllocString(it8, xValue);
1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else {
1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        p->Value   = NULL;
1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return p;
1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovKEYVALUE* AddAvailableProperty(cmsIT8* it8, const char* Key, WRITEMODE as)
1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return AddToList(it8, &it8->ValidKeywords, Key, NULL, NULL, as);
1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovKEYVALUE* AddAvailableSampleID(cmsIT8* it8, const char* Key)
1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return AddToList(it8, &it8->ValidSampleID, Key, NULL, NULL, WRITE_UNCOOKED);
1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid AllocTable(cmsIT8* it8)
1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t;
1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t = it8 ->Tab + it8 ->TablesCount;
1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t->HeaderList = NULL;
1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t->DataFormat = NULL;
1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t->Data       = NULL;
1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 ->TablesCount++;
1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsInt32Number CMSEXPORT cmsIT8SetTable(cmsHANDLE  IT8, cmsUInt32Number nTable)
1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     cmsIT8* it8 = (cmsIT8*) IT8;
1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     if (nTable >= it8 ->TablesCount) {
1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         if (nTable == it8 ->TablesCount) {
1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov             AllocTable(it8);
1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         }
1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         else {
1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov             SynError(it8, "Table %d is out of sequence", nTable);
1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov             return -1;
1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         }
1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     }
1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     it8 ->nTable = nTable;
1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     return (cmsInt32Number) nTable;
1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Init an empty container
1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsHANDLE  CMSEXPORT cmsIT8Alloc(cmsContext ContextID)
1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8;
1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number i;
1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 = (cmsIT8*) _cmsMallocZero(ContextID, sizeof(cmsIT8));
1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (it8 == NULL) return NULL;
1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AllocTable(it8);
1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->MemoryBlock = NULL;
1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->MemorySink  = NULL;
1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 ->nTable = 0;
1294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->ContextID = ContextID;
1296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->Allocator.Used = 0;
1297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->Allocator.Block = NULL;
1298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->Allocator.BlockSize = 0;
1299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->ValidKeywords = NULL;
1301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->ValidSampleID = NULL;
1302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 -> sy = SNONE;
1304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 -> ch = ' ';
1305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 -> Source = NULL;
1306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 -> inum = 0;
1307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 -> dnum = 0.0;
1308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->FileStack[0] = (FILECTX*)AllocChunk(it8, sizeof(FILECTX));
1310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->IncludeSP   = 0;
1311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 -> lineno = 1;
1312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT);
1314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8SetSheetType((cmsHANDLE) it8, "CGATS.17");
1315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Initialize predefined properties & data
1317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i=0; i < NUMPREDEFINEDPROPS; i++)
1319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            AddAvailableProperty(it8, PredefinedProperties[i].id, PredefinedProperties[i].as);
1320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i=0; i < NUMPREDEFINEDSAMPLEID; i++)
1322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            AddAvailableSampleID(it8, PredefinedSampleID[i]);
1323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   return (cmsHANDLE) it8;
1326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst char* CMSEXPORT cmsIT8GetSheetType(cmsHANDLE hIT8)
1330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return GetTable((cmsIT8*) hIT8)->SheetType;
1332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1334ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SetSheetType(cmsHANDLE hIT8, const char* Type)
1335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        TABLE* t = GetTable((cmsIT8*) hIT8);
1337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strncpy(t ->SheetType, Type, MAXSTR-1);
1339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        t ->SheetType[MAXSTR-1] = 0;
1340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
1341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1343ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SetComment(cmsHANDLE hIT8, const char* Val)
1344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
1346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!Val) return FALSE;
1348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!*Val) return FALSE;
1349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return AddToList(it8, &GetTable(it8)->HeaderList, "# ", NULL, Val, WRITE_UNCOOKED) != NULL;
1351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Sets a property
1354ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SetPropertyStr(cmsHANDLE hIT8, const char* Key, const char *Val)
1355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
1357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!Val) return FALSE;
1359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!*Val) return FALSE;
1360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Val, WRITE_STRINGIFY) != NULL;
1362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1364ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SetPropertyDbl(cmsHANDLE hIT8, const char* cProp, cmsFloat64Number Val)
1365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
1367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char Buffer[1024];
1368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sprintf(Buffer, it8->DoubleFormatter, Val);
1370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_UNCOOKED) != NULL;
1372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1374ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SetPropertyHex(cmsHANDLE hIT8, const char* cProp, cmsUInt32Number Val)
1375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
1377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char Buffer[1024];
1378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sprintf(Buffer, "%u", Val);
1380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return AddToList(it8, &GetTable(it8)->HeaderList, cProp, NULL, Buffer, WRITE_HEXADECIMAL) != NULL;
1382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1384ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SetPropertyUncooked(cmsHANDLE hIT8, const char* Key, const char* Buffer)
1385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
1387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Buffer, WRITE_UNCOOKED) != NULL;
1389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1391ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char* SubKey, const char *Buffer)
1392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
1394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return AddToList(it8, &GetTable(it8)->HeaderList, Key, SubKey, Buffer, WRITE_PAIR) != NULL;
1396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Gets a property
1399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst char* CMSEXPORT cmsIT8GetProperty(cmsHANDLE hIT8, const char* Key)
1400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
1402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    KEYVALUE* p;
1403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, NULL, &p))
1405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
1406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return p -> Value;
1407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return NULL;
1409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1412ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsFloat64Number CMSEXPORT cmsIT8GetPropertyDbl(cmsHANDLE hIT8, const char* cProp)
1413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const char *v = cmsIT8GetProperty(hIT8, cProp);
1415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (v == NULL) return 0.0;
1417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ParseFloatNumber(v);
1419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst char* CMSEXPORT cmsIT8GetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char *SubKey)
1422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
1424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    KEYVALUE* p;
1425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (IsAvailableOnList(GetTable(it8) -> HeaderList, Key, SubKey, &p)) {
1427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return p -> Value;
1428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return NULL;
1430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ----------------------------------------------------------------- Datasets
1433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid AllocateDataFormat(cmsIT8* it8)
1437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = GetTable(it8);
1439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (t -> DataFormat) return;    // Already allocated
1441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t -> nSamples  = (int) cmsIT8GetPropertyDbl(it8, "NUMBER_OF_FIELDS");
1443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (t -> nSamples <= 0) {
1445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SynError(it8, "AllocateDataFormat: Unknown NUMBER_OF_FIELDS");
1447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        t -> nSamples = 10;
1448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t -> DataFormat = (char**) AllocChunk (it8, ((cmsUInt32Number) t->nSamples + 1) * sizeof(char *));
1451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (t->DataFormat == NULL) {
1452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SynError(it8, "AllocateDataFormat: Unable to allocate dataFormat array");
1454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst char *GetDataFormat(cmsIT8* it8, int n)
1460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = GetTable(it8);
1462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (t->DataFormat)
1464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return t->DataFormat[n];
1465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return NULL;
1467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1470ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool SetDataFormat(cmsIT8* it8, int n, const char *label)
1471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = GetTable(it8);
1473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!t->DataFormat)
1475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        AllocateDataFormat(it8);
1476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (n > t -> nSamples) {
1478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SynError(it8, "More than NUMBER_OF_FIELDS fields.");
1479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (t->DataFormat) {
1483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        t->DataFormat[n] = AllocString(it8, label);
1484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1490ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE  h, int n, const char *Sample)
1491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsIT8* it8 = (cmsIT8*) h;
1493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return SetDataFormat(it8, n, Sample);
1494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid AllocateDataSet(cmsIT8* it8)
1498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = GetTable(it8);
1500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (t -> Data) return;    // Already allocated
1502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t-> nSamples   = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
1504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t-> nPatches   = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
1505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t-> Data = (char**)AllocChunk (it8, ((cmsUInt32Number) t->nSamples + 1) * ((cmsUInt32Number) t->nPatches + 1) *sizeof (char*));
1507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (t->Data == NULL) {
1508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        SynError(it8, "AllocateDataSet: Unable to allocate data array");
1510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovchar* GetData(cmsIT8* it8, int nSet, int nField)
1516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = GetTable(it8);
1518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int  nSamples   = t -> nSamples;
1519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int  nPatches   = t -> nPatches;
1520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (nSet >= nPatches || nField >= nSamples)
1522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!t->Data) return NULL;
1525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return t->Data [nSet * nSamples + nField];
1526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1529ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool SetData(cmsIT8* it8, int nSet, int nField, const char *Val)
1530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = GetTable(it8);
1532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!t->Data)
1534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        AllocateDataSet(it8);
1535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!t->Data) return FALSE;
1537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (nSet > t -> nPatches || nSet < 0) {
1539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return SynError(it8, "Patch %d out of range, there are %d patches", nSet, t -> nPatches);
1541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (nField > t ->nSamples || nField < 0) {
1544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return SynError(it8, "Sample %d out of range, there are %d samples", nField, t ->nSamples);
1545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t->Data [nSet * t -> nSamples + nField] = AllocString(it8, Val);
1549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// --------------------------------------------------------------- File I/O
1554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Writes a string to file
1557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid WriteStr(SAVESTREAM* f, const char *str)
1559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number len;
1561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (str == NULL)
1563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        str = " ";
1564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Length to write
1566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    len = (cmsUInt32Number) strlen(str);
1567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    f ->Used += len;
1568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (f ->stream) {   // Should I write it to a file?
1571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (fwrite(str, 1, len, f->stream) != len) {
1573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            cmsSignalError(0, cmsERROR_WRITE, "Write to file error in CGATS parser");
1574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
1575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else {  // Or to a memory block?
1579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (f ->Base) {   // Am I just counting the bytes?
1581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (f ->Used > f ->Max) {
1583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 cmsSignalError(0, cmsERROR_WRITE, "Write to memory overflows in CGATS parser");
1585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 return;
1586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            memmove(f ->Ptr, str, len);
1589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            f->Ptr += len;
1590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Write formatted
1597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Writef(SAVESTREAM* f, const char* frm, ...)
1600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char Buffer[4096];
1602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    va_list args;
1603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    va_start(args, frm);
1605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    vsnprintf(Buffer, 4095, frm, args);
1606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Buffer[4095] = 0;
1607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    WriteStr(f, Buffer);
1608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    va_end(args);
1609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Writes full header
1613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid WriteHeader(cmsIT8* it8, SAVESTREAM* fp)
1615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    KEYVALUE* p;
1617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = GetTable(it8);
1618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Writes the type
1620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    WriteStr(fp, t->SheetType);
1621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    WriteStr(fp, "\n");
1622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (p = t->HeaderList; (p != NULL); p = p->Next)
1624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
1625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (*p ->Keyword == '#') {
1626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            char* Pt;
1628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            WriteStr(fp, "#\n# ");
1630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (Pt = p ->Value; *Pt; Pt++) {
1631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                Writef(fp, "%c", *Pt);
1634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (*Pt == '\n') {
1636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    WriteStr(fp, "# ");
1637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            WriteStr(fp, "\n#\n");
1641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
1642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!IsAvailableOnList(it8-> ValidKeywords, p->Keyword, NULL, NULL)) {
1646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef CMS_STRICT_CGATS
1648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            WriteStr(fp, "KEYWORD\t\"");
1649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            WriteStr(fp, p->Keyword);
1650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            WriteStr(fp, "\"\n");
1651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            AddAvailableProperty(it8, p->Keyword, WRITE_UNCOOKED);
1654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        WriteStr(fp, p->Keyword);
1657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (p->Value) {
1658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            switch (p ->WriteAs) {
1660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case WRITE_UNCOOKED:
1662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    Writef(fp, "\t%s", p ->Value);
1663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
1664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case WRITE_STRINGIFY:
1666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    Writef(fp, "\t\"%s\"", p->Value );
1667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
1668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case WRITE_HEXADECIMAL:
1670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    Writef(fp, "\t0x%X", atoi(p ->Value));
1671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
1672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case WRITE_BINARY:
1674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    Writef(fp, "\t0x%B", atoi(p ->Value));
1675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
1676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case WRITE_PAIR:
1678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    Writef(fp, "\t\"%s,%s\"", p->Subkey, p->Value);
1679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
1680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            default: SynError(it8, "Unknown write mode %d", p ->WriteAs);
1682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     return;
1683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        WriteStr (fp, "\n");
1687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Writes the data format
1693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid WriteDataFormat(SAVESTREAM* fp, cmsIT8* it8)
1695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i, nSamples;
1697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = GetTable(it8);
1698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!t -> DataFormat) return;
1700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       WriteStr(fp, "BEGIN_DATA_FORMAT\n");
1702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       WriteStr(fp, " ");
1703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       nSamples = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
1704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       for (i = 0; i < nSamples; i++) {
1706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov              WriteStr(fp, t->DataFormat[i]);
1708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov              WriteStr(fp, ((i == (nSamples-1)) ? "\n" : "\t"));
1709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          }
1710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       WriteStr (fp, "END_DATA_FORMAT\n");
1712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Writes data array
1716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid WriteData(SAVESTREAM* fp, cmsIT8* it8)
1718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       int  i, j;
1720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       TABLE* t = GetTable(it8);
1721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       if (!t->Data) return;
1723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       WriteStr (fp, "BEGIN_DATA\n");
1725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       t->nPatches = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
1727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       for (i = 0; i < t-> nPatches; i++) {
1729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov              WriteStr(fp, " ");
1731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov              for (j = 0; j < t->nSamples; j++) {
1733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     char *ptr = t->Data[i*t->nSamples+j];
1735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     if (ptr == NULL) WriteStr(fp, "\"\"");
1737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     else {
1738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         // If value contains whitespace, enclose within quote
1739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         if (strchr(ptr, ' ') != NULL) {
1741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                             WriteStr(fp, "\"");
1743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                             WriteStr(fp, ptr);
1744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                             WriteStr(fp, "\"");
1745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         }
1746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                         else
1747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            WriteStr(fp, ptr);
1748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     }
1749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     WriteStr(fp, ((j == (t->nSamples-1)) ? "\n" : "\t"));
1751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov              }
1752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       }
1753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       WriteStr (fp, "END_DATA\n");
1754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Saves whole file
1759ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SaveToFile(cmsHANDLE hIT8, const char* cFileName)
1760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    SAVESTREAM sd;
1762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number i;
1763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
1764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    memset(&sd, 0, sizeof(sd));
1766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sd.stream = fopen(cFileName, "wt");
1768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!sd.stream) return FALSE;
1769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i=0; i < it8 ->TablesCount; i++) {
1771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            cmsIT8SetTable(hIT8, i);
1773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            WriteHeader(it8, &sd);
1774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            WriteDataFormat(&sd, it8);
1775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            WriteData(&sd, it8);
1776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (fclose(sd.stream) != 0) return FALSE;
1779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Saves to memory
1785ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SaveToMem(cmsHANDLE hIT8, void *MemPtr, cmsUInt32Number* BytesNeeded)
1786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    SAVESTREAM sd;
1788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number i;
1789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
1790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    memset(&sd, 0, sizeof(sd));
1792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sd.stream = NULL;
1794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sd.Base   = (cmsUInt8Number*)  MemPtr;
1795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sd.Ptr    = sd.Base;
1796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sd.Used = 0;
1798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (sd.Base)
1800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        sd.Max  = *BytesNeeded;     // Write to memory?
1801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else
1802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        sd.Max  = 0;                // Just counting the needed bytes
1803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i=0; i < it8 ->TablesCount; i++) {
1805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsIT8SetTable(hIT8, i);
1807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        WriteHeader(it8, &sd);
1808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        WriteDataFormat(&sd, it8);
1809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        WriteData(&sd, it8);
1810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sd.Used++;  // The \0 at the very end
1813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (sd.Base)
1815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *sd.Ptr = 0;
1816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *BytesNeeded = sd.Used;
1818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// -------------------------------------------------------------- Higer level parsing
1824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1826ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool DataFormatSection(cmsIT8* it8)
1827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int iField = 0;
1829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = GetTable(it8);
1830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    InSymbol(it8);   // Eats "BEGIN_DATA_FORMAT"
1832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CheckEOLN(it8);
1833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (it8->sy != SEND_DATA_FORMAT &&
1835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        it8->sy != SEOLN &&
1836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        it8->sy != SEOF &&
1837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        it8->sy != SSYNERROR)  {
1838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (it8->sy != SIDENT) {
1840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return SynError(it8, "Sample type expected");
1842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!SetDataFormat(it8, iField, it8->id)) return FALSE;
1845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iField++;
1846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            InSymbol(it8);
1848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            SkipEOLN(it8);
1849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       }
1850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       SkipEOLN(it8);
1852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       Skip(it8, SEND_DATA_FORMAT);
1853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       SkipEOLN(it8);
1854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       if (iField != t ->nSamples) {
1856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov           SynError(it8, "Count mismatch. NUMBER_OF_FIELDS was %d, found %d\n", t ->nSamples, iField);
1857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       }
1860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       return TRUE;
1862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1867ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool DataSection (cmsIT8* it8)
1868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int  iField = 0;
1870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int  iSet   = 0;
1871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char Buffer[256];
1872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = GetTable(it8);
1873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    InSymbol(it8);   // Eats "BEGIN_DATA"
1875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CheckEOLN(it8);
1876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!t->Data)
1878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        AllocateDataSet(it8);
1879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (it8->sy != SEND_DATA && it8->sy != SEOF)
1881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
1882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (iField >= t -> nSamples) {
1883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iField = 0;
1884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iSet++;
1885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (it8->sy != SEND_DATA && it8->sy != SEOF) {
1889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!GetVal(it8, Buffer, 255, "Sample data expected"))
1891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
1892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!SetData(it8, iSet, iField, Buffer))
1894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
1895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iField++;
1897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            InSymbol(it8);
1899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            SkipEOLN(it8);
1900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    SkipEOLN(it8);
1904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Skip(it8, SEND_DATA);
1905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    SkipEOLN(it8);
1906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Check for data completion.
1908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((iSet+1) != t -> nPatches)
1910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return SynError(it8, "Count mismatch. NUMBER_OF_SETS was %d, found %d\n", t ->nPatches, iSet+1);
1911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
1919ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool HeaderSection(cmsIT8* it8)
1920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char VarName[MAXID];
1922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char Buffer[MAXSTR];
1923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    KEYVALUE* Key;
1924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (it8->sy != SEOF &&
1926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               it8->sy != SSYNERROR &&
1927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               it8->sy != SBEGIN_DATA_FORMAT &&
1928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               it8->sy != SBEGIN_DATA) {
1929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        switch (it8 -> sy) {
1932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case SKEYWORD:
1934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                InSymbol(it8);
1935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!GetVal(it8, Buffer, MAXSTR-1, "Keyword expected")) return FALSE;
1936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!AddAvailableProperty(it8, Buffer, WRITE_UNCOOKED)) return FALSE;
1937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                InSymbol(it8);
1938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case SDATA_FORMAT_ID:
1942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                InSymbol(it8);
1943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!GetVal(it8, Buffer, MAXSTR-1, "Keyword expected")) return FALSE;
1944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!AddAvailableSampleID(it8, Buffer)) return FALSE;
1945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                InSymbol(it8);
1946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case SIDENT:
1950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strncpy(VarName, it8->id, MAXID-1);
1951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                VarName[MAXID-1] = 0;
1952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!IsAvailableOnList(it8-> ValidKeywords, VarName, NULL, &Key)) {
1954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef CMS_STRICT_CGATS
1956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 return SynError(it8, "Undefined keyword '%s'", VarName);
1957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
1958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED);
1959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (Key == NULL) return FALSE;
1960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                InSymbol(it8);
1964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!GetVal(it8, Buffer, MAXSTR-1, "Property data expected")) return FALSE;
1965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if(Key->WriteAs != WRITE_PAIR) {
1967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer,
1968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED);
1969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                else {
1971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    const char *Subkey;
1972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    char *Nextkey;
1973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (it8->sy != SSTRING)
1974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return SynError(it8, "Invalid value '%s' for property '%s'.", Buffer, VarName);
1975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    // chop the string as a list of "subkey, value" pairs, using ';' as a separator
1977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    for (Subkey = Buffer; Subkey != NULL; Subkey = Nextkey)
1978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    {
1979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        char *Value, *temp;
1980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        //  identify token pair boundary
1982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        Nextkey = (char*) strchr(Subkey, ';');
1983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        if(Nextkey)
1984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            *Nextkey++ = '\0';
1985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        // for each pair, split the subkey and the value
1987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        Value = (char*) strrchr(Subkey, ',');
1988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        if(Value == NULL)
1989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            return SynError(it8, "Invalid value for property '%s'.", VarName);
1990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        // gobble the spaces before the coma, and the coma itself
1992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        temp = Value++;
1993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        do *temp-- = '\0'; while(temp >= Subkey && *temp == ' ');
1994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        // gobble any space at the right
1996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        temp = Value + strlen(Value) - 1;
1997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        while(*temp == ' ') *temp-- = '\0';
1998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        // trim the strings from the left
2000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        Subkey += strspn(Subkey, " ");
2001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        Value += strspn(Value, " ");
2002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        if(Subkey[0] == 0 || Value[0] == 0)
2004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            return SynError(it8, "Invalid value for property '%s'.", VarName);
2005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR);
2006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
2007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
2008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                InSymbol(it8);
2010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
2011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case SEOLN: break;
2014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        default:
2016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return SynError(it8, "expected keyword or identifier");
2017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    SkipEOLN(it8);
2020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
2023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
2028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid ReadType(cmsIT8* it8, char* SheetTypePtr)
2029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // First line is a very special case.
2031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (isseparator(it8->ch))
2033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NextCh(it8);
2034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != -1) {
2036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *SheetTypePtr++= (char) it8 ->ch;
2038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        NextCh(it8);
2039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *SheetTypePtr = 0;
2042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
2046ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool ParseIT8(cmsIT8* it8, cmsBool nosheet)
2047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char* SheetTypePtr = it8 ->Tab[0].SheetType;
2049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (nosheet == 0) {
2051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ReadType(it8, SheetTypePtr);
2052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    InSymbol(it8);
2055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    SkipEOLN(it8);
2057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (it8-> sy != SEOF &&
2059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov           it8-> sy != SSYNERROR) {
2060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            switch (it8 -> sy) {
2062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case SBEGIN_DATA_FORMAT:
2064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!DataFormatSection(it8)) return FALSE;
2065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
2066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case SBEGIN_DATA:
2068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!DataSection(it8)) return FALSE;
2070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (it8 -> sy != SEOF) {
2072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            AllocTable(it8);
2074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            it8 ->nTable = it8 ->TablesCount - 1;
2075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            // Read sheet type if present. We only support identifier and string.
2077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            // <ident> <eoln> is a type string
2078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            // anything else, is not a type string
2079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            if (nosheet == 0) {
2080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                if (it8 ->sy == SIDENT) {
2082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    // May be a type sheet or may be a prop value statement. We cannot use insymbol in
2084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    // this special case...
2085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     while (isseparator(it8->ch))
2086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                         NextCh(it8);
2087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     // If a newline is found, then this is a type string
2089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    if (it8 ->ch == '\n' || it8->ch == '\r') {
2090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                         cmsIT8SetSheetType(it8, it8 ->id);
2092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                         InSymbol(it8);
2093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    }
2094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    else
2095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    {
2096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        // It is not. Just continue
2097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        cmsIT8SetSheetType(it8, "");
2098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    }
2099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                }
2100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                else
2101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    // Validate quoted strings
2102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    if (it8 ->sy == SSTRING) {
2103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        cmsIT8SetSheetType(it8, it8 ->str);
2104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        InSymbol(it8);
2105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    }
2106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                           }
2107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
2109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
2110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case SEOLN:
2112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    SkipEOLN(it8);
2113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
2114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            default:
2116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!HeaderSection(it8)) return FALSE;
2117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov           }
2118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (it8 -> sy != SSYNERROR);
2122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Init usefull pointers
2127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
2129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CookPointers(cmsIT8* it8)
2130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int idField, i;
2132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char* Fld;
2133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number j;
2134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number nOldTable = it8 ->nTable;
2135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (j=0; j < it8 ->TablesCount; j++) {
2137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = it8 ->Tab + j;
2139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t -> SampleID = 0;
2141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 ->nTable = j;
2142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (idField = 0; idField < t -> nSamples; idField++)
2144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
2145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (t ->DataFormat == NULL){
2146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            SynError(it8, "Undefined DATA_FORMAT");
2147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
2148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Fld = t->DataFormat[idField];
2151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!Fld) continue;
2152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (cmsstrcasecmp(Fld, "SAMPLE_ID") == 0) {
2155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            t -> SampleID = idField;
2157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (i=0; i < t -> nPatches; i++) {
2159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                char *Data = GetData(it8, i, idField);
2161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (Data) {
2162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    char Buffer[256];
2163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    strncpy(Buffer, Data, 255);
2165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    Buffer[255] = 0;
2166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (strlen(Buffer) <= strlen(Data))
2168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        strcpy(Data, Buffer);
2169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    else
2170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        SetData(it8, i, idField, Buffer);
2171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
2173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
2174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // "LABEL" is an extension. It keeps references to forward tables
2178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ((cmsstrcasecmp(Fld, "LABEL") == 0) || Fld[0] == '$' ) {
2180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    // Search for table references...
2182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    for (i=0; i < t -> nPatches; i++) {
2183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            char *Label = GetData(it8, i, idField);
2185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            if (Label) {
2187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                cmsUInt32Number k;
2189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                // This is the label, search for a table containing
2191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                // this property
2192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                for (k=0; k < it8 ->TablesCount; k++) {
2194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    TABLE* Table = it8 ->Tab + k;
2196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    KEYVALUE* p;
2197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    if (IsAvailableOnList(Table->HeaderList, Label, NULL, &p)) {
2199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        // Available, keep type and table
2201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        char Buffer[256];
2202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        char *Type  = p ->Value;
2204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        int  nTable = (int) k;
2205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        snprintf(Buffer, 255, "%s %d %s", Label, nTable, Type );
2207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        SetData(it8, i, idField, Buffer);
2209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    }
2210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                }
2211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            }
2214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
2216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 ->nTable = nOldTable;
2224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Try to infere if the file is a CGATS/IT8 file at all. Read first line
2227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// that should be something like some printable characters plus a \n
2228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// returns 0 if this is not like a CGATS, or an integer otherwise. This integer is the number of words in first line?
2229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
2230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint IsMyBlock(cmsUInt8Number* Buffer, int n)
2231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int words = 1, space = 0, quot = 0;
2233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
2234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (n < 10) return 0;   // Too small
2236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (n > 132)
2238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        n = 132;
2239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 1; i < n; i++) {
2241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        switch(Buffer[i])
2243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {
2244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case '\n':
2245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case '\r':
2246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return ((quot == 1) || (words > 2)) ? 0 : words;
2247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case '\t':
2248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case ' ':
2249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if(!quot && !space)
2250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                space = 1;
2251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
2252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case '\"':
2253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            quot = !quot;
2254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
2255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        default:
2256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (Buffer[i] < 32) return 0;
2257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (Buffer[i] > 127) return 0;
2258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            words += space;
2259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            space = 0;
2260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
2261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
2265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
2269ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool IsMyFile(const char* FileName)
2270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   FILE *fp;
2272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   cmsUInt32Number Size;
2273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   cmsUInt8Number Ptr[133];
2274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   fp = fopen(FileName, "rt");
2276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   if (!fp) {
2277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       cmsSignalError(0, cmsERROR_FILE, "File '%s' not found", FileName);
2278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       return FALSE;
2279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   }
2280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   Size = (cmsUInt32Number) fread(Ptr, 1, 132, fp);
2282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   if (fclose(fp) != 0)
2284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       return FALSE;
2285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   Ptr[Size] = '\0';
2287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   return IsMyBlock(Ptr, Size);
2289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ---------------------------------------------------------- Exported routines
2292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2294ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsHANDLE  CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, void *Ptr, cmsUInt32Number len)
2295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsHANDLE hIT8;
2297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8*  it8;
2298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int type;
2299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(Ptr != NULL);
2301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(len != 0);
2302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    type = IsMyBlock((cmsUInt8Number*)Ptr, len);
2304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (type == 0) return NULL;
2305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    hIT8 = cmsIT8Alloc(ContextID);
2307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!hIT8) return NULL;
2308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 = (cmsIT8*) hIT8;
2310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 ->MemoryBlock = (char*) _cmsMalloc(ContextID, len + 1);
2311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strncpy(it8 ->MemoryBlock, (const char*) Ptr, len);
2313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 ->MemoryBlock[len] = 0;
2314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strncpy(it8->FileStack[0]->FileName, "", cmsMAX_PATH-1);
2316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8-> Source = it8 -> MemoryBlock;
2317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!ParseIT8(it8, type-1)) {
2319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsIT8Free(hIT8);
2321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
2322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CookPointers(it8);
2325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 ->nTable = 0;
2326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsFree(ContextID, it8->MemoryBlock);
2328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 -> MemoryBlock = NULL;
2329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return hIT8;
2331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2336ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsHANDLE  CMSEXPORT cmsIT8LoadFromFile(cmsContext ContextID, const char* cFileName)
2337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     cmsHANDLE hIT8;
2340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     cmsIT8*  it8;
2341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     int type;
2342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     _cmsAssert(cFileName != NULL);
2344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     type = IsMyFile(cFileName);
2346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     if (type == 0) return NULL;
2347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     hIT8 = cmsIT8Alloc(ContextID);
2349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     it8 = (cmsIT8*) hIT8;
2350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     if (!hIT8) return NULL;
2351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     it8 ->FileStack[0]->Stream = fopen(cFileName, "rt");
2354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     if (!it8 ->FileStack[0]->Stream) {
2356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         cmsIT8Free(hIT8);
2357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         return NULL;
2358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     }
2359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strncpy(it8->FileStack[0]->FileName, cFileName, cmsMAX_PATH-1);
2362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->FileStack[0]->FileName[cmsMAX_PATH-1] = 0;
2363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!ParseIT8(it8, type-1)) {
2365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            fclose(it8 ->FileStack[0]->Stream);
2367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            cmsIT8Free(hIT8);
2368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return NULL;
2369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CookPointers(it8);
2372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 ->nTable = 0;
2373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (fclose(it8 ->FileStack[0]->Stream)!= 0) {
2375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            cmsIT8Free(hIT8);
2376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return NULL;
2377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return hIT8;
2380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CMSEXPORT cmsIT8EnumDataFormat(cmsHANDLE hIT8, char ***SampleNames)
2384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t;
2387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t = GetTable(it8);
2391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (SampleNames)
2393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *SampleNames = t -> DataFormat;
2394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return t -> nSamples;
2395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2398ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsUInt32Number CMSEXPORT cmsIT8EnumProperties(cmsHANDLE hIT8, char ***PropertyNames)
2399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    KEYVALUE* p;
2402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number n;
2403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char **Props;
2404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t;
2405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t = GetTable(it8);
2409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Pass#1 - count properties
2411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    n = 0;
2413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (p = t -> HeaderList;  p != NULL; p = p->Next) {
2414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        n++;
2415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Props = (char **) AllocChunk(it8, sizeof(char *) * n);
2419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Pass#2 - Fill pointers
2421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    n = 0;
2422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (p = t -> HeaderList;  p != NULL; p = p->Next) {
2423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Props[n++] = p -> Keyword;
2424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *PropertyNames = Props;
2427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return n;
2428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2430ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsUInt32Number CMSEXPORT cmsIT8EnumPropertyMulti(cmsHANDLE hIT8, const char* cProp, const char ***SubpropertyNames)
2431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    KEYVALUE *p, *tmp;
2434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number n;
2435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const char **Props;
2436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t;
2437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t = GetTable(it8);
2442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(!IsAvailableOnList(t->HeaderList, cProp, NULL, &p)) {
2444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *SubpropertyNames = 0;
2445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
2446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Pass#1 - count properties
2449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    n = 0;
2451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (tmp = p;  tmp != NULL; tmp = tmp->NextSubkey) {
2452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if(tmp->Subkey != NULL)
2453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            n++;
2454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Props = (const char **) AllocChunk(it8, sizeof(char *) * n);
2458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Pass#2 - Fill pointers
2460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    n = 0;
2461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (tmp = p;  tmp != NULL; tmp = tmp->NextSubkey) {
2462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if(tmp->Subkey != NULL)
2463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            Props[n++] = p ->Subkey;
2464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *SubpropertyNames = Props;
2467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return n;
2468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
2471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint LocatePatch(cmsIT8* it8, const char* cPatch)
2472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
2474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const char *data;
2475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = GetTable(it8);
2476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i=0; i < t-> nPatches; i++) {
2478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        data = GetData(it8, i, t->SampleID);
2480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (data != NULL) {
2482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (cmsstrcasecmp(data, cPatch) == 0)
2484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return i;
2485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
2486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // SynError(it8, "Couldn't find patch '%s'\n", cPatch);
2489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return -1;
2490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
2494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint LocateEmptyPatch(cmsIT8* it8)
2495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
2497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const char *data;
2498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = GetTable(it8);
2499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i=0; i < t-> nPatches; i++) {
2501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        data = GetData(it8, i, t->SampleID);
2503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (data == NULL)
2505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return i;
2506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return -1;
2510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
2513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint LocateSample(cmsIT8* it8, const char* cSample)
2514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
2516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const char *fld;
2517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t = GetTable(it8);
2518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i=0; i < t->nSamples; i++) {
2520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        fld = GetDataFormat(it8, i);
2522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (cmsstrcasecmp(fld, cSample) == 0)
2523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return i;
2524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return -1;
2527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CMSEXPORT cmsIT8FindDataFormat(cmsHANDLE hIT8, const char* cSample)
2532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return LocateSample(it8, cSample);
2538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst char* CMSEXPORT cmsIT8GetDataRowCol(cmsHANDLE hIT8, int row, int col)
2543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return GetData(it8, row, col);
2549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2552ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsFloat64Number CMSEXPORT cmsIT8GetDataRowColDbl(cmsHANDLE hIT8, int row, int col)
2553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const char* Buffer;
2555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Buffer = cmsIT8GetDataRowCol(hIT8, row, col);
2557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (Buffer == NULL) return 0.0;
2559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ParseFloatNumber(Buffer);
2561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2564ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SetDataRowCol(cmsHANDLE hIT8, int row, int col, const char* Val)
2565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return SetData(it8, row, col, Val);
2571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2574ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SetDataRowColDbl(cmsHANDLE hIT8, int row, int col, cmsFloat64Number Val)
2575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char Buff[256];
2578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sprintf(Buff, it8->DoubleFormatter, Val);
2582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return SetData(it8, row, col, Buff);
2584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst char* CMSEXPORT cmsIT8GetData(cmsHANDLE hIT8, const char* cPatch, const char* cSample)
2589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int iField, iSet;
2592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    iField = LocateSample(it8, cSample);
2596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (iField < 0) {
2597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
2598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    iSet = LocatePatch(it8, cPatch);
2601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (iSet < 0) {
2602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return NULL;
2603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return GetData(it8, iSet, iField);
2606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2609ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsFloat64Number CMSEXPORT cmsIT8GetDataDbl(cmsHANDLE  it8, const char* cPatch, const char* cSample)
2610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const char* Buffer;
2612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Buffer = cmsIT8GetData(it8, cPatch, cSample);
2614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ParseFloatNumber(Buffer);
2616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2620ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SetData(cmsHANDLE hIT8, const char* cPatch, const char* cSample, const char *Val)
2621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int iField, iSet;
2624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t;
2625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t = GetTable(it8);
2629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    iField = LocateSample(it8, cSample);
2631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (iField < 0)
2633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
2634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (t-> nPatches == 0) {
2636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        AllocateDataFormat(it8);
2638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        AllocateDataSet(it8);
2639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CookPointers(it8);
2640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (cmsstrcasecmp(cSample, "SAMPLE_ID") == 0) {
2643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        iSet   = LocateEmptyPatch(it8);
2645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (iSet < 0) {
2646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return SynError(it8, "Couldn't add more patches '%s'\n", cPatch);
2647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        iField = t -> SampleID;
2650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else {
2652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        iSet = LocatePatch(it8, cPatch);
2653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (iSet < 0) {
2654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
2655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
2656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return SetData(it8, iSet, iField, Val);
2659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2662ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SetDataDbl(cmsHANDLE hIT8, const char* cPatch,
2663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   const char* cSample,
2664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                   cmsFloat64Number Val)
2665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char Buff[256];
2668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    snprintf(Buff, 255, it8->DoubleFormatter, Val);
2672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return cmsIT8SetData(hIT8, cPatch, cSample, Buff);
2673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Buffer should get MAXSTR at least
2676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst char* CMSEXPORT cmsIT8GetPatchName(cmsHANDLE hIT8, int nPatch, char* buffer)
2678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    TABLE* t;
2681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char* Data;
2682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    t = GetTable(it8);
2686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Data = GetData(it8, nPatch, t->SampleID);
2687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!Data) return NULL;
2689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!buffer) return Data;
2690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strncpy(buffer, Data, MAXSTR-1);
2692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    buffer[MAXSTR-1] = 0;
2693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return buffer;
2694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CMSEXPORT cmsIT8GetPatchByName(cmsHANDLE hIT8, const char *cPatch)
2697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return LocatePatch((cmsIT8*)hIT8, cPatch);
2701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2703ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsUInt32Number CMSEXPORT cmsIT8TableCount(cmsHANDLE hIT8)
2704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return it8 ->TablesCount;
2710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This handles the "LABEL" extension.
2713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Label, nTable, Type
2714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType)
2716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const char* cLabelFld;
2718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    char Type[256], Label[256];
2719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nTable;
2720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (cField != NULL && *cField == 0)
2724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            cField = "LABEL";
2725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (cField == NULL)
2727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            cField = "LABEL";
2728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cLabelFld = cmsIT8GetData(hIT8, cSet, cField);
2730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!cLabelFld) return -1;
2731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (sscanf(cLabelFld, "%255s %d %255s", Label, &nTable, Type) != 3)
2733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return -1;
2734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ExpectedType != NULL && *ExpectedType == 0)
2736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ExpectedType = NULL;
2737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ExpectedType) {
2739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (cmsstrcasecmp(Type, ExpectedType) != 0) return -1;
2741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
2742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return cmsIT8SetTable(hIT8, nTable);
2744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2747ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsIT8SetIndexColumn(cmsHANDLE hIT8, const char* cSample)
2748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int pos;
2751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pos = LocateSample(it8, cSample);
2755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if(pos == -1)
2756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
2757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8->Tab[it8->nTable].SampleID = pos;
2759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
2760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT cmsIT8DefineDblFormat(cmsHANDLE hIT8, const char* Formatter)
2764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
2765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsIT8* it8 = (cmsIT8*) hIT8;
2766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(hIT8 != NULL);
2768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (Formatter == NULL)
2770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT);
2771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else
2772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strncpy(it8->DoubleFormatter, Formatter, sizeof(it8->DoubleFormatter));
2773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
2774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    it8 ->DoubleFormatter[sizeof(it8 ->DoubleFormatter)-1] = 0;
2775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
2776