38 #include <sys/types.h>
50 #define PAF_HDR_START "PAF.HDR.START"
51 #define PAF_TYPE "PAF.TYPE"
52 #define PAF_ID "PAF.ID"
53 #define PAF_NAME "PAF.NAME"
54 #define PAF_DESC "PAF.DESC"
55 #define PAF_CRTE_NAME "PAF.CRTE.NAME"
56 #define PAF_CRTE_TIME "PAF.CRTE.DAYTIM"
57 #define PAF_LCHG_NAME "PAF.LCHG.NAME"
58 #define PAF_LCHG_TIME "PAF.LCHG.DAYTIM"
59 #define PAF_CHCK_NAME "PAF.CHCK.NAME"
60 #define PAF_CHCK_TIME "PAF.CHCK.DAYTIM"
61 #define PAF_CHCK_CHECKSUM "PAF.CHCK.CHECKSUM"
62 #define PAF_HDR_END "PAF.HDR.END"
69 #define PAF_FIELD_OFFSET_VALUE 20
70 #define PAF_FIELD_OFFSET_COMMENT 45
124 #define TIME_ISO8601_LENGTH (20)
126 static char *getTimeISO8601(
void)
129 static char timeISO8601[TIME_ISO8601_LENGTH];
130 time_t seconds = time((time_t *)0);
132 if (strftime(timeISO8601, TIME_ISO8601_LENGTH,
133 "%Y-%m-%dT%T", localtime(&seconds)) == 0)
134 strcpy(timeISO8601,
"0000-00-00T00:00:00");
146 _forsPAFValueSize(ForsPAFType type,
const void *value)
159 case PAF_TYPE_DOUBLE:
163 case PAF_TYPE_STRING:
164 sz = (strlen((
char *)value) + 1) *
sizeof(
char);
186 cpl_free(record->name);
187 cpl_free((
void *)record->data.sval);
188 cpl_free(record->comment);
202 _forsPAFRecordCreate(
const char *name, ForsPAFType type,
const void *value,
211 record->name = cpl_strdup(name);
212 record->comment = comment ? cpl_strdup(comment) : NULL;
215 sz = _forsPAFValueSize(type, value);
218 record->data.sval = NULL;
221 record->data.sval = (
char *)cpl_malloc(sz);
224 memcpy(record->data.sval, value, sz);
235 _forsPAFRecordSet(
ForsPAFRecord *record,
const char *name, ForsPAFType type,
236 const void *value,
const char *comment)
240 cpl_free(record->name);
241 record->name = cpl_strdup(name);
245 cpl_free(record->comment);
246 record->comment = cpl_strdup(comment);
250 size_t sz = _forsPAFValueSize(type, value);
252 if (record->data.sval) {
253 size_t size = _forsPAFValueSize(record->type, record->data.sval);
256 record->data.sval = (
char *)cpl_realloc(record->data.sval, sz);
259 record->data.sval = (
char *)cpl_malloc(sz);
261 memcpy(record->data.sval, value, sz);
277 ForsPAFType type,
const void *value,
const char *comment)
283 record = _forsPAFRecordCreate(name, type, value, comment);
291 *list = cpl_realloc(*list, (pos[0]+1) *
sizeof(
ForsPAFRecord *));
294 (*list)[pos[0]] = record;
307 _forsPAFHeaderCreate(
const char *name,
const char *type,
const char *
id,
308 const char *desc,
int *pos)
312 const char *user, *timestamp;
313 #if defined HAVE_GETUID && defined HAVE_GETPWUID
319 #if defined HAVE_GETUID && defined HAVE_GETPWUID
320 pw = getpwuid(getuid());
327 user = getenv(
"USER");
328 user = user == NULL ? getenv(
"LOGNAME") : user;
338 timestamp = getTimeISO8601();
342 _forsPAFAppend(&hdr, pos, PAF_HDR_START, PAF_TYPE_NONE, NULL, NULL);
343 _forsPAFAppend(&hdr, pos, PAF_TYPE, PAF_TYPE_STRING, type,
344 "Type of parameter file");
347 _forsPAFAppend(&hdr, pos, PAF_ID, PAF_TYPE_STRING,
id, NULL);
350 _forsPAFAppend(&hdr, pos, PAF_ID, PAF_TYPE_STRING,
"", NULL);
353 _forsPAFAppend(&hdr, pos, PAF_NAME, PAF_TYPE_STRING, name,
"Name of PAF");
356 _forsPAFAppend(&hdr, pos, PAF_DESC, PAF_TYPE_STRING, desc,
357 "Short description of PAF");
359 _forsPAFAppend(&hdr, pos, PAF_DESC, PAF_TYPE_STRING,
"",
360 "Short description of PAF");
362 _forsPAFAppend(&hdr, pos, PAF_CRTE_NAME, PAF_TYPE_STRING, user,
364 _forsPAFAppend(&hdr, pos, PAF_CRTE_TIME, PAF_TYPE_STRING, timestamp,
365 "Civil time for creation");
366 _forsPAFAppend(&hdr, pos, PAF_LCHG_NAME, PAF_TYPE_STRING, user,
367 "Author of par. file");
368 _forsPAFAppend(&hdr, pos, PAF_LCHG_TIME, PAF_TYPE_STRING, timestamp,
369 "Timestamp for last change");
370 _forsPAFAppend(&hdr, pos, PAF_CHCK_NAME, PAF_TYPE_STRING,
"",
371 "Name of appl. checking");
372 _forsPAFAppend(&hdr, pos, PAF_CHCK_TIME, PAF_TYPE_STRING,
"",
373 "Time for checking");
374 _forsPAFAppend(&hdr, pos, PAF_CHCK_CHECKSUM, PAF_TYPE_STRING,
"",
375 "Checksum for the PAF");
376 _forsPAFAppend(&hdr, pos, PAF_HDR_END, PAF_TYPE_NONE, NULL, NULL);
388 inline static const char *
392 static char buffer[PAF_RECORD_MAX + 1];
393 char value[PAF_RECORD_MAX + 1];
398 memset(buffer,
' ', PAF_RECORD_MAX);
406 if (strlen(record->name) + 1 > PAF_RECORD_MAX)
414 sz = strlen(record->name);
415 strncpy(buffer, record->name, sz);
418 if (record->data.sval) {
419 if (pos < PAF_FIELD_OFFSET_VALUE)
420 pos = PAF_FIELD_OFFSET_VALUE;
424 switch (record->type) {
426 snprintf(value, PAF_RECORD_MAX,
"%c",
427 *record->data.bval ?
'T' :
'F');
431 snprintf(value, PAF_RECORD_MAX,
"%d", *record->data.ival);
434 case PAF_TYPE_DOUBLE:
435 snprintf(value, PAF_RECORD_MAX,
"%.15G", *record->data.dval);
436 if (!strchr(value,
'.')) {
437 if (strchr(value,
'E'))
438 snprintf(value, PAF_RECORD_MAX,
"%.1E",
445 case PAF_TYPE_STRING:
446 snprintf(value, PAF_RECORD_MAX,
"\"%s\"", record->data.sval);
465 if (sz > PAF_RECORD_MAX - pos + 1)
468 strncpy(&buffer[pos], value, sz);
481 if (record->comment && (PAF_RECORD_MAX - pos) >= 2) {
482 if (pos < PAF_FIELD_OFFSET_COMMENT)
483 pos = PAF_FIELD_OFFSET_COMMENT;
487 strncpy(&buffer[pos],
"# ", 2);
489 sz = strlen(record->comment);
490 strncpy(&buffer[pos], record->comment, sz);
517 for (i = 0; i < paf->nh; i++)
518 _forsPAFRecordDestroy(paf->header[i]);
519 for (i = 0; i < paf->nr; i++)
520 _forsPAFRecordDestroy(paf->records[i]);
521 cpl_free(paf->header);
522 cpl_free(paf->records);
563 paf->header = _forsPAFHeaderCreate(name, type,
id, desc, &pos);
564 if(paf->header == NULL)
572 paf->name = cpl_strdup(name);
599 return paf->nr == 0 ? 1 : 0;
622 return (
size_t)paf->nr;
645 register size_t i, sz;
648 assert(name != NULL);
650 if (strchr(name,
' '))
654 for (i = 0; i <sz; i++) {
669 if (!(isupper)(c) && !(isdigit)(c) && c !=
'.' && c !=
'_' && c !=
'-')
698 assert(name != NULL);
703 if (_forsPAFAppend(&(paf->records), &(paf->nr), name, PAF_TYPE_BOOL,
733 assert(name != NULL);
738 if (_forsPAFAppend(&(paf->records), &(paf->nr), name, PAF_TYPE_INT,
769 assert(name != NULL);
774 if (_forsPAFAppend(&(paf->records), &(paf->nr), name, PAF_TYPE_DOUBLE,
805 assert(name != NULL);
810 if (_forsPAFAppend(&(paf->records), &(paf->nr), name, PAF_TYPE_STRING,
845 assert(paf->header != NULL);
852 stream = fopen(paf->name,
"wb");
857 for (i = 0; i < paf->nh; i++) {
858 record = _forsPAFFormatRecord(paf->header[i]);
864 fprintf(stream,
"%s\n", record);
869 char buffer[PAF_RECORD_MAX];
872 memset(&buffer[1],
'-', 78);
874 fprintf(stream,
"%s\n", buffer);
877 for (i = 0; i < paf->nr; i++) {
878 record = _forsPAFFormatRecord(paf->records[i]);
884 fprintf(stream,
"%s\n", record);
int forsPAFAppendInt(ForsPAF *paf, const char *name, int value, const char *comment)
Append a integer value to a PAF object.
int forsPAFIsEmpty(const ForsPAF *paf)
Check whether a PAF object is empty.
int forsPAFIsValidName(const char *name)
Verify that the given string is a valid PAF keyword.
void deleteForsPAF(ForsPAF *paf)
Destroy a PAF object.
int forsPAFAppendDouble(ForsPAF *paf, const char *name, double value, const char *comment)
Append a double value to a PAF object.
int forsPAFWrite(ForsPAF *paf)
Write a PAF object to a disk file.
int forsPAFAppendBool(ForsPAF *paf, const char *name, int value, const char *comment)
Append a boolean value to a PAF object.
int forsPAFAppendString(ForsPAF *paf, const char *name, const char *value, const char *comment)
Append a string value to a PAF object.
size_t forsPAFGetSize(const ForsPAF *paf)
Get the actual size of the given PAF object.
ForsPAF * newForsPAF(const char *name, const char *type, const char *id, const char *desc)
Create a new PAF object.