/* Title: symtab.c 
 * Author: Jed Marti KI7NNP
 * Description: Read the range and increment values for parameter optimization.
 * Revision History: (Created Mon Jan 22 20:35:52 2024)
 */


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "arrl.h"

// The symbol table and default values.
symtab S[] = {
              {.name = "lownum", .value = 0.0},
              {.name = "highnum", .value = 1000.0},
              {.name = "incnum", .value = 1.0},
              {.name = "lowdia", .value = 0.0},
              {.name = "highdia", .value = 1000.0},
              {.name = "incdia", .value = 1.0},
              {.name = "lowlen", .value = 0.0},
              {.name = "highlen", .value = 1000.0},
              {.name = "inclen", .value = 1.0} };


void readVariables(char *fn)
/*     Read the limits and increment of the interations from a file. The format is:
 *          variable-name numeric-value
 *   Blank lines and those starting with # are ignored.
 * Parameters:
 *   fn: File name to read.
 * External References:
 *   S[]: The known symbols and their default values.
 * Returned values: none
 * Errors Detected: Couldn't open file for input, unknown variable name.
 */
{
  FILE    *fh;
  char    ibuf[80];
  char    *tok;
  int32_t i;

  // Open or fail.
  if ((fh = fopen(fn, "rb")) == NULL)
  {
    fprintf(stderr, "Couldn't open %s for input\n", fn);
    exit(-1);
  }

  // Quit on EOF or file error.
 loop:
  if (feof(fh))
  {
    fclose(fh);
    return;
  }
  if (fgets(ibuf, 80, fh) == NULL)
  {
    fclose(fh);
    return;
  }

  // Name or comment.
  tok = strtok(ibuf, " \n");
  if (tok == NULL || tok[0] == '#') goto loop;

  // Search for name.
  for (i = 0; i < sizeof(S) / sizeof(symtab); ++i)
    if (strcasecmp(S[i].name, tok) == 0) break;

  // Unknown variable fails.
  if (i == sizeof(S) / sizeof(symtab))
  {
    fprintf(stderr, "Variable %s unknown\n", tok);
    fclose(fh);
    exit(-1);
  }

  // Store the value.
  S[i].value = atof(strtok(NULL, " \n"));
  goto loop;
}



double lookup(char *vname)
/*     Look for a symbol in the table and return its value. Case insensitive.
 * Parameters:
 *   vname: Variable name to lookup.
 * External References:
 *   S[]: The known symbols and their values.
 * Returned values: the symbol value.
 * Errors detected: Unknown symbol causes halt.
 */
{
  int32_t i;
  for (i = 0; i < sizeof(S) / sizeof(symtab); ++i)
    if (strcasecmp(S[i].name, vname) == 0) return S[i].value;
  fprintf(stderr, "%s unknown\n", vname);
  exit(-1);
}



// EOF
