Mercurial > hg > th-libs
comparison th_config.c @ 129:aa2d608fb3f3
Cosmetics.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 22 Jun 2014 07:23:54 +0300 |
parents | 0ac59c798773 |
children | 51eec969b07a |
comparison
equal
deleted
inserted
replaced
128:c22caa6e3fcb | 129:aa2d608fb3f3 |
---|---|
42 th_cfgitem_t *node; | 42 th_cfgitem_t *node; |
43 | 43 |
44 if (cfg == NULL) | 44 if (cfg == NULL) |
45 return NULL; | 45 return NULL; |
46 | 46 |
47 /* Allocate new item */ | 47 // Allocate new item |
48 node = (th_cfgitem_t *) th_malloc0(sizeof(th_cfgitem_t)); | 48 node = (th_cfgitem_t *) th_malloc0(sizeof(th_cfgitem_t)); |
49 if (node == NULL) | 49 if (node == NULL) |
50 return NULL; | 50 return NULL; |
51 | 51 |
52 /* Set values */ | 52 // Set values |
53 node->type = type; | 53 node->type = type; |
54 node->v.data = data; | 54 node->v.data = data; |
55 node->name = th_strdup(name); | 55 node->name = th_strdup(name); |
56 | 56 |
57 /* Insert into linked list */ | 57 // Insert into linked list |
58 if (*cfg != NULL) | 58 if (*cfg != NULL) |
59 { | 59 { |
60 node->prev = (*cfg)->prev; | 60 node->prev = (*cfg)->prev; |
61 (*cfg)->prev->next = node; | 61 (*cfg)->prev->next = node; |
62 (*cfg)->prev = node; | 62 (*cfg)->prev = node; |
224 char *tmpStr = NULL; | 224 char *tmpStr = NULL; |
225 size_t strPos; | 225 size_t strPos; |
226 int c, parseMode, prevMode, nextMode, tmpCh; | 226 int c, parseMode, prevMode, nextMode, tmpCh; |
227 BOOL isFound, isStart, isError, validError; | 227 BOOL isFound, isStart, isError, validError; |
228 | 228 |
229 /* Initialize values */ | 229 // Initialize values |
230 tmpCh = 0; | 230 tmpCh = 0; |
231 strPos = 0; | 231 strPos = 0; |
232 c = -1; | 232 c = -1; |
233 isFound = isStart = isError = validError = FALSE; | 233 isFound = isStart = isError = validError = FALSE; |
234 nextMode = prevMode = parseMode = PM_NORMAL; | 234 nextMode = prevMode = parseMode = PM_NORMAL; |
235 | 235 |
236 if ((tmpStr = th_malloc(SET_MAX_BUF + 1)) == NULL) | 236 if ((tmpStr = th_malloc(SET_MAX_BUF + 1)) == NULL) |
237 goto out; | 237 goto out; |
238 | 238 |
239 /* Parse the configuration */ | 239 // Parse the configuration |
240 while (parseMode != PM_EOF && parseMode != PM_ERROR) | 240 while (parseMode != PM_EOF && parseMode != PM_ERROR) |
241 { | 241 { |
242 if (c == -1) | 242 if (c == -1) |
243 { | 243 { |
244 /* Get next character */ | 244 // Get next character |
245 switch (c = fgetc(ctx->fp)) | 245 switch (c = fgetc(ctx->fp)) |
246 { | 246 { |
247 case EOF: | 247 case EOF: |
248 if (parseMode != PM_NORMAL) | 248 if (parseMode != PM_NORMAL) |
249 { | 249 { |
260 } | 260 } |
261 | 261 |
262 switch (parseMode) | 262 switch (parseMode) |
263 { | 263 { |
264 case PM_COMMENT: | 264 case PM_COMMENT: |
265 /* Comment parsing mode */ | 265 // Comment parsing mode |
266 if (c == '\n') | 266 if (c == '\n') |
267 { | 267 { |
268 /* End of line, end of comment */ | 268 // End of line, end of comment |
269 parseMode = prevMode; | 269 parseMode = prevMode; |
270 prevMode = PM_COMMENT; | 270 prevMode = PM_COMMENT; |
271 } | 271 } |
272 c = -1; | 272 c = -1; |
273 break; | 273 break; |
274 | 274 |
275 case PM_NORMAL: | 275 case PM_NORMAL: |
276 /* Normal parsing mode */ | 276 // Normal parsing mode |
277 if (c == '#') | 277 if (c == '#') |
278 { | 278 { |
279 prevMode = parseMode; | 279 prevMode = parseMode; |
280 parseMode = PM_COMMENT; | 280 parseMode = PM_COMMENT; |
281 c = -1; | 281 c = -1; |
285 c = -1; | 285 c = -1; |
286 } | 286 } |
287 else if (c == '}') | 287 else if (c == '}') |
288 { | 288 { |
289 if (nesting > 0) | 289 if (nesting > 0) |
290 /* Check for validation errors */ | 290 // Check for validation errors |
291 goto out; | 291 goto out; |
292 else | 292 else |
293 { | 293 { |
294 th_ioctx_error(ctx, -1, | 294 th_ioctx_error(ctx, -1, |
295 "Invalid nesting sequence encountered.\n"); | 295 "Invalid nesting sequence encountered.\n"); |
296 parseMode = PM_ERROR; | 296 parseMode = PM_ERROR; |
297 } | 297 } |
298 } | 298 } |
299 else if (th_isalpha(c)) | 299 else if (th_isalpha(c)) |
300 { | 300 { |
301 /* Start of key name found */ | 301 // Start of key name found |
302 prevMode = parseMode; | 302 prevMode = parseMode; |
303 parseMode = PM_KEYNAME; | 303 parseMode = PM_KEYNAME; |
304 strPos = 0; | 304 strPos = 0; |
305 } | 305 } |
306 else | 306 else |
307 { | 307 { |
308 /* Error! Invalid character found */ | 308 // Error! Invalid character found |
309 th_ioctx_error(ctx, -1, "Unexpected character '%c'.\n", c); | 309 th_ioctx_error(ctx, -1, "Unexpected character '%c'.\n", c); |
310 parseMode = PM_ERROR; | 310 parseMode = PM_ERROR; |
311 } | 311 } |
312 break; | 312 break; |
313 | 313 |
314 case PM_KEYNAME: | 314 case PM_KEYNAME: |
315 /* Configuration KEY name parsing mode */ | 315 // Configuration KEY name parsing mode |
316 if (c == '#') | 316 if (c == '#') |
317 { | 317 { |
318 /* Start of comment */ | 318 // Start of comment |
319 prevMode = parseMode; | 319 prevMode = parseMode; |
320 parseMode = PM_COMMENT; | 320 parseMode = PM_COMMENT; |
321 c = -1; | 321 c = -1; |
322 } | 322 } |
323 else if (th_iscrlf(c) || th_isspace(c) || c == '=') | 323 else if (th_iscrlf(c) || th_isspace(c) || c == '=') |
324 { | 324 { |
325 /* End of key name */ | 325 // End of key name |
326 prevMode = parseMode; | 326 prevMode = parseMode; |
327 parseMode = PM_NEXT; | 327 parseMode = PM_NEXT; |
328 nextMode = PM_KEYSET; | 328 nextMode = PM_KEYSET; |
329 } | 329 } |
330 else if (th_isalnum(c) || c == '_') | 330 else if (th_isalnum(c) || c == '_') |
331 { | 331 { |
332 /* Add to key name string */ | 332 // Add to key name string |
333 VADDCH(c) | 333 VADDCH(c) |
334 else | 334 else |
335 { | 335 { |
336 /* Error! Key name string too long! */ | 336 // Error! Key name string too long! |
337 th_ioctx_error(ctx, -1, "Config key name too long!"); | 337 th_ioctx_error(ctx, -1, "Config key name too long!"); |
338 parseMode = PM_ERROR; | 338 parseMode = PM_ERROR; |
339 } | 339 } |
340 c = -1; | 340 c = -1; |
341 } | 341 } |
342 else | 342 else |
343 { | 343 { |
344 /* Error! Invalid character found */ | 344 // Error! Invalid character found |
345 tmpStr[strPos] = 0; | 345 tmpStr[strPos] = 0; |
346 th_ioctx_error(ctx, -1, | 346 th_ioctx_error(ctx, -1, |
347 "Unexpected character '%c' in key name '%s'.\n", | 347 "Unexpected character '%c' in key name '%s'.\n", |
348 c, tmpStr); | 348 c, tmpStr); |
349 parseMode = PM_ERROR; | 349 parseMode = PM_ERROR; |
351 break; | 351 break; |
352 | 352 |
353 case PM_KEYSET: | 353 case PM_KEYSET: |
354 if (c == '=') | 354 if (c == '=') |
355 { | 355 { |
356 /* Find key from configuration */ | 356 // Find key from configuration |
357 tmpStr[strPos] = 0; | 357 tmpStr[strPos] = 0; |
358 isFound = FALSE; | 358 isFound = FALSE; |
359 item = cfg; | 359 item = cfg; |
360 while (item != NULL && !isFound) | 360 while (item != NULL && !isFound) |
361 { | 361 { |
363 isFound = TRUE; | 363 isFound = TRUE; |
364 else | 364 else |
365 item = item->next; | 365 item = item->next; |
366 } | 366 } |
367 | 367 |
368 /* Check if key was found */ | 368 // Check if key was found |
369 if (isFound) | 369 if (isFound) |
370 { | 370 { |
371 /* Okay, set next mode */ | 371 // Okay, set next mode |
372 switch (item->type) | 372 switch (item->type) |
373 { | 373 { |
374 case ITEM_HEX_TRIPLET: | 374 case ITEM_HEX_TRIPLET: |
375 case ITEM_STRING: | 375 case ITEM_STRING: |
376 nextMode = PM_STRING; | 376 nextMode = PM_STRING; |
399 isStart = TRUE; | 399 isStart = TRUE; |
400 strPos = 0; | 400 strPos = 0; |
401 } | 401 } |
402 else | 402 else |
403 { | 403 { |
404 /* Error! No configuration key by this name found */ | 404 // Error! No configuration key by this name found |
405 th_ioctx_error(ctx, -1, | 405 th_ioctx_error(ctx, -1, |
406 "No such configuration setting ('%s')\n", | 406 "No such configuration setting ('%s')\n", |
407 tmpStr); | 407 tmpStr); |
408 parseMode = PM_ERROR; | 408 parseMode = PM_ERROR; |
409 } | 409 } |
410 | 410 |
411 c = -1; | 411 c = -1; |
412 } | 412 } |
413 else | 413 else |
414 { | 414 { |
415 /* Error! '=' expected! */ | 415 // Error! '=' expected! |
416 th_ioctx_error(ctx, -1, | 416 th_ioctx_error(ctx, -1, |
417 "Unexpected character '%c', assignation '=' was expected.\n", | 417 "Unexpected character '%c', assignation '=' was expected.\n", |
418 c); | 418 c); |
419 parseMode = PM_ERROR; | 419 parseMode = PM_ERROR; |
420 } | 420 } |
421 break; | 421 break; |
422 | 422 |
423 case PM_NEXT: | 423 case PM_NEXT: |
424 /* Search next item parsing mode */ | 424 // Search next item parsing mode |
425 if (c == '#') | 425 if (c == '#') |
426 { | 426 { |
427 /* Start of comment */ | 427 // Start of comment |
428 prevMode = parseMode; | 428 prevMode = parseMode; |
429 parseMode = PM_COMMENT; | 429 parseMode = PM_COMMENT; |
430 } | 430 } |
431 else if (th_isspace(c) || th_iscrlf(c)) | 431 else if (th_isspace(c) || th_iscrlf(c)) |
432 { | 432 { |
433 /* Ignore whitespaces and linechanges */ | 433 // Ignore whitespaces and linechanges |
434 c = -1; | 434 c = -1; |
435 } | 435 } |
436 else | 436 else |
437 { | 437 { |
438 /* Next item found */ | 438 // Next item found |
439 prevMode = parseMode; | 439 prevMode = parseMode; |
440 parseMode = nextMode; | 440 parseMode = nextMode; |
441 } | 441 } |
442 break; | 442 break; |
443 | 443 |
471 parseMode = PM_NORMAL; | 471 parseMode = PM_NORMAL; |
472 } | 472 } |
473 break; | 473 break; |
474 | 474 |
475 case PM_SECTION: | 475 case PM_SECTION: |
476 /* Section parsing mode */ | 476 // Section parsing mode |
477 if (c != '{') | 477 if (c != '{') |
478 { | 478 { |
479 /* Error! Section start '{' expected! */ | 479 // Error! Section start '{' expected! |
480 th_ioctx_error(ctx, -1, | 480 th_ioctx_error(ctx, -1, |
481 "Unexpected character '%c', section start '{' was expected.\n", | 481 "Unexpected character '%c', section start '{' was expected.\n", |
482 c); | 482 c); |
483 parseMode = PM_ERROR; | 483 parseMode = PM_ERROR; |
484 } | 484 } |
497 } | 497 } |
498 } | 498 } |
499 break; | 499 break; |
500 | 500 |
501 case PM_STRING: | 501 case PM_STRING: |
502 /* String parsing mode */ | 502 // String parsing mode |
503 if (isStart) | 503 if (isStart) |
504 { | 504 { |
505 /* Start of string, get delimiter */ | 505 // Start of string, get delimiter |
506 tmpCh = c; | 506 tmpCh = c; |
507 isStart = FALSE; | 507 isStart = FALSE; |
508 strPos = 0; | 508 strPos = 0; |
509 } | 509 } |
510 else if (c == tmpCh) | 510 else if (c == tmpCh) |
511 { | 511 { |
512 /* End of string, set the value */ | 512 // End of string, set the value |
513 tmpStr[strPos] = 0; | 513 tmpStr[strPos] = 0; |
514 | 514 |
515 switch (item->type) | 515 switch (item->type) |
516 { | 516 { |
517 case ITEM_HEX_TRIPLET: | 517 case ITEM_HEX_TRIPLET: |
533 } | 533 } |
534 | 534 |
535 } | 535 } |
536 else | 536 else |
537 { | 537 { |
538 /* Add character to string */ | 538 // Add character to string |
539 VADDCH(c) | 539 VADDCH(c) |
540 else | 540 else |
541 { | 541 { |
542 /* Error! String too long! */ | 542 // Error! String too long! |
543 th_ioctx_error(ctx, -1, | 543 th_ioctx_error(ctx, -1, |
544 "String too long! Maximum is %d characters.", | 544 "String too long! Maximum is %d characters.", |
545 SET_MAX_BUF); | 545 SET_MAX_BUF); |
546 parseMode = PM_ERROR; | 546 parseMode = PM_ERROR; |
547 } | 547 } |
549 | 549 |
550 c = -1; | 550 c = -1; |
551 break; | 551 break; |
552 | 552 |
553 case PM_INT: | 553 case PM_INT: |
554 /* Integer parsing mode */ | 554 // Integer parsing mode |
555 if (isStart && item->type == ITEM_UINT && c == '-') | 555 if (isStart && item->type == ITEM_UINT && c == '-') |
556 { | 556 { |
557 /* Error! Negative values not allowed for unsigned ints */ | 557 // Error! Negative values not allowed for unsigned ints |
558 th_ioctx_error(ctx, -1, | 558 th_ioctx_error(ctx, -1, |
559 "Negative value specified for %s, unsigned value expected.", | 559 "Negative value specified for %s, unsigned value expected.", |
560 item->name); | 560 item->name); |
561 parseMode = PM_ERROR; | 561 parseMode = PM_ERROR; |
562 } | 562 } |
572 else | 572 else |
573 isError = TRUE; | 573 isError = TRUE; |
574 } | 574 } |
575 else if (VISEND(c)) | 575 else if (VISEND(c)) |
576 { | 576 { |
577 /* End of integer parsing mode */ | 577 // End of integer parsing mode |
578 tmpStr[strPos] = 0; | 578 tmpStr[strPos] = 0; |
579 switch (item->type) | 579 switch (item->type) |
580 { | 580 { |
581 case ITEM_INT: | 581 case ITEM_INT: |
582 *(item->v.val_int) = atoi(tmpStr); | 582 *(item->v.val_int) = atoi(tmpStr); |
590 prevMode = parseMode; | 590 prevMode = parseMode; |
591 parseMode = PM_NORMAL; | 591 parseMode = PM_NORMAL; |
592 } | 592 } |
593 else | 593 else |
594 { | 594 { |
595 /* Error! Unexpected character. */ | 595 // Error! Unexpected character. |
596 th_ioctx_error(ctx, -1, | 596 th_ioctx_error(ctx, -1, |
597 "Unexpected character '%c' for integer setting '%s'.", | 597 "Unexpected character '%c' for integer setting '%s'.", |
598 c, item->name); | 598 c, item->name); |
599 parseMode = PM_ERROR; | 599 parseMode = PM_ERROR; |
600 } | 600 } |
601 | 601 |
602 if (isError) | 602 if (isError) |
603 { | 603 { |
604 /* Error! String too long! */ | 604 // Error! String too long! |
605 th_ioctx_error(ctx, -1, | 605 th_ioctx_error(ctx, -1, |
606 "String too long! Maximum is %d characters.", | 606 "String too long! Maximum is %d characters.", |
607 SET_MAX_BUF); | 607 SET_MAX_BUF); |
608 parseMode = PM_ERROR; | 608 parseMode = PM_ERROR; |
609 } | 609 } |
611 isStart = FALSE; | 611 isStart = FALSE; |
612 c = -1; | 612 c = -1; |
613 break; | 613 break; |
614 | 614 |
615 case PM_BOOL: | 615 case PM_BOOL: |
616 /* Boolean parsing mode */ | 616 // Boolean parsing mode |
617 if (isStart) | 617 if (isStart) |
618 { | 618 { |
619 tmpCh = c; | 619 tmpCh = c; |
620 isStart = FALSE; | 620 isStart = FALSE; |
621 } | 621 } |
622 else if (VISEND(c)) | 622 else if (VISEND(c)) |
623 { | 623 { |
624 BOOL tmpBool = FALSE; | 624 BOOL tmpBool = FALSE; |
625 | 625 |
626 /* End of boolean parsing */ | 626 // End of boolean parsing |
627 switch (tmpCh) | 627 switch (tmpCh) |
628 { | 628 { |
629 case 'Y': | 629 case 'Y': |
630 case 'y': | 630 case 'y': |
631 case 'T': | 631 case 'T': |
667 } | 667 } |
668 | 668 |
669 out: | 669 out: |
670 th_free(tmpStr); | 670 th_free(tmpStr); |
671 | 671 |
672 /* Check for validation errors */ | 672 // Check for validation errors |
673 if (validError) | 673 if (validError) |
674 return 1; | 674 return 1; |
675 | 675 |
676 /* Return result */ | 676 // Return result |
677 if (parseMode == PM_ERROR) | 677 if (parseMode == PM_ERROR) |
678 return -2; | 678 return -2; |
679 else | 679 else |
680 return 0; | 680 return 0; |
681 } | 681 } |