qtlua/qtlua/qtluautils.cpp
/*! Returns potential completion for a string.
  Takes as input a single string composed of 
  identifiers separated by '.' or ':' and returns a table 
  representing an array of potential completions.
  Each completion is a string that could be reasonably 
  appended to the initial argument.
  This function throws errors when something goes wrong.
  Use \a pcall to call it safely. */
Returns potential completion for a string.
Takes as input a single string composed of
identifiers separated by '.' or ':' and returns a table
representing an array of potential completions.
Each completion is a string that could be reasonably
appended to the initial argument.
This function throws errors when something goes wrong.
Use \a pcall to call it safely.
Returns potential completion for a string . Takes as input a single string composed of identifiers separated by ' . ' or ' : ' and returns a table representing an array of potential completions . Each completion is a string that could be reasonably appended to the initial argument . This function throws errors when something goes wrong . Use \ a pcall to call it safely .
int 
luaQ_complete(struct lua_State *L)
{
  int k = 0;
  int loop = 0;
  const char *stem = luaL_checkstring(L, 1);
  lua_pushvalue(L, LUA_GLOBALSINDEX);
  for(;;)
    {
      const char *s = stem;
      while (*s && *s != '.' && *s != ':')
        s++;
      if (*s == 0)
        break;
      lua_pushlstring(L, stem, s-stem);
      lua_gettable(L, -2);
      lua_replace(L, -2);
      stem = s + 1;
    }
  lua_createtable(L, 0, 0);
  lua_insert(L, -2);
  if (lua_isuserdata(L, -1) && lua_getmetatable(L, -1))
    {
      lua_replace(L, -2);
      lua_pushliteral(L, "__index");
      lua_rawget(L, -2);
      if (lua_isfunction(L, -1))
        {
          lua_pop(L, 1);
          lua_pushliteral(L, "__metatable");
          lua_rawget(L, -2);
        }
      lua_replace(L, -2);
    }
  if (! lua_istable(L, -1))
    {
      lua_pop(L, 1);
      return 1;
    }
  size_t stemlen = strlen(stem);
  for(;;)
    {
      lua_pushnil(L);
      while (lua_next(L, -2))
        {
          bool ok = false;
          size_t keylen;
          const char *key = lua_tolstring(L, -2, &keylen);
          if (key && keylen > 0 && keylen >= stemlen)
            if (!strncmp(key, stem, stemlen))
              ok = true;
          if (ok && !isalpha(key[0]))
            ok = false;
          if (ok)
            for (int i=0; ok && i<(int)keylen; i++)
              if (!isalpha(key[i]) && !isdigit(key[i]) && key[i]!='_')
                ok = false;
          if (ok)
            {
              const char *suffix = "";
              switch (lua_type(L, -1)) 
                {
                case LUA_TFUNCTION: 
                  suffix = "("; 
                  break;
                case LUA_TTABLE: 
                  suffix = ".";
                  luaQ_getfield(L, -1, "_C");
                  if (lua_istable(L, -1))
                    suffix = ":";
                  lua_pop(L, 1);
                  break;
                case LUA_TUSERDATA: {
                  QVariant v = luaQ_toqvariant(L, -1);
                  const char *s = QMetaType::typeName(v.userType());
                  if (s && !strcmp(s,"QtLuaMethodInfo"))
                    suffix = "(";
                  else if (s && !strcmp(s, "QtLuaPropertyInfo"))
                    suffix = "";
                  else if (lua_getmetatable(L, -1)) {
                    lua_pop(L, 1);
                    suffix = ":";
                  } else 
                    suffix = "";
                } break;
                default:
                  break;
                }
              lua_pushfstring(L, "%s%s", key+stemlen, suffix);
              lua_rawseti(L, -5, ++k);
            }
          lua_pop(L, 1);
        }
      if (! lua_getmetatable(L, -1))
        break;
      lua_replace(L, -2);
      lua_pushliteral(L, "__index");
      lua_rawget(L, -2);
      lua_replace(L, -2);
      if (! lua_istable(L, -1))
        break;
      if (++loop > 100)
        luaL_error(L, "complete: infinite loop in metatables");
    }
  lua_pop(L, 1);
  lua_replace(L, -2);
  return 1;
}
int luaQ_complete ( struct lua_State * L ) { int k = 0 ; int loop = 0 ; const char * stem = luaL_checkstring ( L , 1 ) ; lua_pushvalue ( L , LUA_GLOBALSINDEX ) ; for ( ; ; ) { const char * s = stem ; while ( * s && * s != ' ' && * s != ' ' ) s ++ ; if ( * s == 0 ) break ; lua_pushlstring ( L , stem , s - stem ) ; lua_gettable ( L , -2 ) ; lua_replace ( L , -2 ) ; stem = s + 1 ; } lua_createtable ( L , 0 , 0 ) ; lua_insert ( L , -2 ) ; if ( lua_isuserdata ( L , -1 ) && lua_getmetatable ( L , -1 ) ) { lua_replace ( L , -2 ) ; lua_pushliteral ( L , " " ) ; lua_rawget ( L , -2 ) ; if ( lua_isfunction ( L , -1 ) ) { lua_pop ( L , 1 ) ; lua_pushliteral ( L , " " ) ; lua_rawget ( L , -2 ) ; } lua_replace ( L , -2 ) ; } if ( ! lua_istable ( L , -1 ) ) { lua_pop ( L , 1 ) ; return 1 ; } size_t stemlen = strlen ( stem ) ; for ( ; ; ) { lua_pushnil ( L ) ; while ( lua_next ( L , -2 ) ) { bool ok = false ; size_t keylen ; const char * key = lua_tolstring ( L , -2 , & keylen ) ; if ( key && keylen > 0 && keylen >= stemlen ) if ( ! strncmp ( key , stem , stemlen ) ) ok = true ; if ( ok && ! isalpha ( key [ 0 ] ) ) ok = false ; if ( ok ) for ( int i = 0 ; ok && i < ( int ) keylen ; i ++ ) if ( ! isalpha ( key [ i ] ) && ! isdigit ( key [ i ] ) && key [ i ] != ' ' ) ok = false ; if ( ok ) { const char * suffix = " " ; switch ( lua_type ( L , -1 ) ) { case LUA_TFUNCTION : suffix = " " ; break ; case LUA_TTABLE : suffix = " " ; luaQ_getfield ( L , -1 , " " ) ; if ( lua_istable ( L , -1 ) ) suffix = " " ; lua_pop ( L , 1 ) ; break ; case LUA_TUSERDATA : { QVariant v = luaQ_toqvariant ( L , -1 ) ; const char * s = QMetaType :: typeName ( v . userType ( ) ) ; if ( s && ! strcmp ( s , " " ) ) suffix = " " ; else if ( s && ! strcmp ( s , " " ) ) suffix = " " ; else if ( lua_getmetatable ( L , -1 ) ) { lua_pop ( L , 1 ) ; suffix = " " ; } else suffix = " " ; } break ; default : break ; } lua_pushfstring ( L , " " , key + stemlen , suffix ) ; lua_rawseti ( L , -5 , ++ k ) ; } lua_pop ( L , 1 ) ; } if ( ! lua_getmetatable ( L , -1 ) ) break ; lua_replace ( L , -2 ) ; lua_pushliteral ( L , " " ) ; lua_rawget ( L , -2 ) ; lua_replace ( L , -2 ) ; if ( ! lua_istable ( L , -1 ) ) break ; if ( ++ loop > 100 ) luaL_error ( L , " " ) ; } lua_pop ( L , 1 ) ; lua_replace ( L , -2 ) ; return 1 ; }
Returns potential completion for a string.
Returns potential completion for a string .
// stack: table str // stack: ntable table str // stack: ntable str // stack: maybetable anstable str // stack: table anstable str // stack: value key table anstable str // stack: value key table anstable str // stack: table anstable str // stack: something anstable str