lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Maybe this is a trivial question, but I have spent quit a lot of
time trying to solve the following seemingly uncomplicated task:
I have a LUA program that looks like this:

------ Start of pasted file ------

IDENTIFIER_TXT = 'RX-EEPROM_DESCRIPTION';
NR_OF_BLOCKS   = 3;

BLOCK_0 =
{
  specific_length ={'Length', '1082', 'UINT16', 2, 0},
  kalle           ={'allan',  '100',  'UINT16', 2, 0}
}

BLOCK_1 =
{
  Code          = {'Code'      , '10'  , 'UINT16', 2, 0},
  Length        = {'Length'    , '1084', 'UINT16', 2, 0},
  No_of_entries = {'No_entries', '12'  , 'UINT8' , 1, 0}
}

BLOCK_2 =
{
  id                 = {'Id'                , 'RT'  , 'ASC'   , 2, 0},
  bcd                = {'-'                 , '0101', 'BCD'   , 2, 0},
  length             = {'Length'            , '0007', 'UINT16', 2, 1},
  son_re             = {'SON RE'            , '80'  , 'UINT16', 2, 2},
  son_fe             = {'SON FE'            , '01'  , 'UINT16', 2, 3},
  sof_re             = {'SOF RE'            , '80'  , 'UINT16', 2, 4},
  sof_fe             = {'SOF RE'            , '01'  , 'UINT16', 2, 5},
  pll_clock_polarity = {'Pll Clock Polarity', '00'  , 'UINT16', 2, 6},
  pll_latch_polarity = {'Pll latch Polarity', '00'  , 'UINT16', 2, 7},
  prescale           = {'Prescale'          , '02'  , 'UINT16', 2, 8}
}
---- End of pasted file ---

My aim is to scan these variables from the C-api (at this moment I
am only interested in traversing the variables from C (eg. I use
Lua as a clean easy way of storing configurable data for my c
aplication. I would like to simply associate (for example) 'kalle' with
a list of values easily accessible from C (like a linked list or array).
If someone could give me some pointers to an example doing this from C or
point out any obvious mistake I have done I would be gratefull.

I use the recommended way (from the manual) of traversing tables and
manage to traverse the first BLOCK_0 table and get
the names of the two tables 'specific_length' and 'kalle'. When I try
to traverse these tables the program crashes. I use the same technique
in both cases (and yes, I am a newbee when it comes to LUA):

----- C - source code (this is test code, and it shows) follows ----
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

#include "lua.h"

typedef struct keyval_s
{
  char *key;
  char *val;
}KEYVAL_T;

typedef struct block_s
{
  char      *name;
  KEYVAL_T **keyVal;
}BLOCK_T;

int readTable (lua_State *lua, int noBlocks, KEYVAL_T **keyval)
{
  int t;
  int r;

  t = lua_gettop (lua);
  if (t == 0)
    {
      printf ("gettop returned 0!\n");
      return -1;
    }
  lua_pushnil    (lua);

  noBlocks = 0;
  r = 0;
  printf ("readTable: Top of stack: %d\n", t);
  printf ("--------------------------------------\n");
  while (lua_next (lua, t)!= 0)
    {

      keyval[r] = (KEYVAL_T *)malloc (sizeof(KEYVAL_T));
      memset (keyval[r], 0, sizeof (KEYVAL_T));

      printf ("%d:  %s (%s) - %s\n", t,
              lua_typename (lua, lua_type(lua, -2)),
              lua_tostring (lua, -2),
              lua_typename (lua, lua_type(lua, -1)));

      keyval[r]->key = strdup (lua_tostring (lua, -2));
      lua_pop (lua, 1);
      r++;
    }
  printf ("--------------------------------------\n");
  keyval[r] = (KEYVAL_T *)malloc (sizeof(KEYVAL_T));
  memset (keyval[r], 0, sizeof (KEYVAL_T));

  t = lua_gettop (lua);
  printf ("readTable: Top of stack (After): %d\n", t);

  return 1;
}

char *getVal (lua_State *lua, char *key, int t)
{
  char *str;
  const char *st;
  /** **/
  printf ("getVal: Getting '%s'!\n", key);

  lua_getglobal (lua, key);
  t = lua_gettop (lua);
  printf ("getVal: Top index: %d\n", t);

  st = lua_tostring (lua, t);

  if (st != NULL)
    {
      str = strdup (st);
      printf ("getVal: id string val: %s\n", str);
    }
  else printf ("getVal: st = NULL\n");

  /** **/
  return str;
}

int findKey (KEYVAL_T **keyval, char *name)
{
  int t;

  t = 0;
  while (keyval[t]->key != NULL)
    {
      printf ("keyval[%d]->key = %s\n", t, keyval[t]->key);
      if (strcmp (keyval[t]->key, name) == 0)
          {
            return t;
          }
      t++;
    }

  return -1;
}

int setVal (lua_State *lua, char *key)
{
  int t;

  printf ("setVal: Setting: %s!\n", key);

  lua_getglobal (lua, key);
  t = lua_gettop (lua);

  printf ("setVal:  %s (%s) - %s\n",
          lua_typename (lua, lua_type(lua, -2)),
          lua_tostring (lua, -2),
          lua_typename (lua, lua_type(lua, -1)));

  printf ("setVal: Top index: %d\n", t);

  return t;
}

int getTable (lua_State *lua, int t)
{

  printf ("getTable: Getting   %d!\n", t);

  lua_gettable (lua, t);
  t = lua_gettop (lua);
  printf ("getTable: Top index %d!\n", t);

  return t;
}

int main (int argc, char **argv)
{
  char       *str;
  char        st[32];
  KEYVAL_T  **keyValTop;
  KEYVAL_T    keyVal;
  BLOCK_T   **block;
  int         t;
  int         r;
  int         noBlocks;
  lua_State  *lua;

  keyValTop = (KEYVAL_T **)malloc (sizeof (KEYVAL_T *)*128);
  memset (keyValTop, 0, sizeof (KEYVAL_T *)*128);

  block = (BLOCK_T **)malloc (sizeof (BLOCK_T *)*128);
  memset (block, 0, sizeof (BLOCK_T *)*128);

  printf ("Creating the LUA environment...\n");

  lua = lua_open (1024*10);

  /** Doing something in between! **/
  t = lua_dofile (lua, "example.lua");
  if (t == LUA_ERRRUN)
    {
      printf ("Error when running LUA script.\n");
    }
  else if (t == LUA_ERRSYNTAX)
    {
      printf ("Error when precompiling program...\n");
    }
  else if (t == LUA_ERRMEM)
    {
      printf ("Memory allocation error!\n");
    }
  else if (t == LUA_ERRERR)
    {
      printf ("Error in calling error :-)\n");
    }

  /** **/

  t = lua_gettop (lua);
  str = getVal (lua, "IDENTIFIER_TXT", t);
  printf ("Gotten value!\n");
  printf ("val = %s\n", str);

  t        = lua_gettop (lua);
  str      = getVal (lua, "NR_OF_BLOCKS", t);
  noBlocks = atoi (str);
  printf ("Gotten value!\n");
  printf ("val = %s\n", str);

  // lua_getglobals (lua);
  // t = lua_gettop (lua);

  // readTable  (lua, noBlocks, keyValTop);

  // lua_settop (lua, 0);

  for (t = 0; t < noBlocks; t++)
    {
      block[t] = (BLOCK_T *)malloc (sizeof (BLOCK_T));
      memset (block[t], 0, sizeof (BLOCK_T));

      block[t]->keyVal = (KEYVAL_T **)malloc (sizeof (KEYVAL_T *)*128);
      memset (block[t]->keyVal, 0, sizeof (KEYVAL_T *)*128);

      sprintf (st, "BLOCK_%d", t);
      keyVal.key = st;

      str      = getVal     (lua, keyVal.key, r);

      r        = lua_gettop (lua);
      readTable (lua, noBlocks, block[t]->keyVal);
      // r        = getTable (lua, r);
      // printf ("r = %d\n", r);

      printf ("block[%d]->keyVal[%d].key = %s\n", t, 0,
              block[t]->keyVal[0]->key);

      r        = lua_gettop (lua);

      // Here I have used several test aproaches each giving non desired
      // result :-)
      // str     = getVal     (lua, block[t]->keyVal[0]->key, r);
      // str     = getVal     (lua, "BLOCK_0.specific_length", r);
      setVal (lua, "BLOCK_0.specific_length");
      readTable (lua, noBlocks, block[t]->keyVal);
      // r        = getTable (lua, r);
      //      str = getVal (lua, keyVal.key, r);
      exit (0);
    }
  /** **/

  printf ("Closing the environment!\n");
  lua_close (lua);
  exit (0);
}
----- End C - Source -----
Regards

--
/Frazze, Alias Joakim Hansson