misc/liblua/ltablib.c
author nemo
Tue, 21 Aug 2018 15:11:28 -0400
branch0.9.24
changeset 13682 f60b3998ba56
parent 10017 de822cd3df3a
permissions -rw-r--r--
only-stats should never create visual gears. and lua should never rely on visual gears being created. critical is just to help ensure ones important to gameplay don't get lost in fast-forward
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2812
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     1
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     2
** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     3
** Library for Table Manipulation
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     4
** See Copyright Notice in lua.h
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     5
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     6
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     7
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     8
#include <stddef.h>
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     9
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    10
#define ltablib_c
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    11
#define LUA_LIB
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    12
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    13
#include "lua.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    14
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    15
#include "lauxlib.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    16
#include "lualib.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    17
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    18
10017
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 2812
diff changeset
    19
#define aux_getn(L,n)   (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
2812
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    20
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    21
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    22
static int foreachi (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    23
  int i;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    24
  int n = aux_getn(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    25
  luaL_checktype(L, 2, LUA_TFUNCTION);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    26
  for (i=1; i <= n; i++) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    27
    lua_pushvalue(L, 2);  /* function */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    28
    lua_pushinteger(L, i);  /* 1st argument */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    29
    lua_rawgeti(L, 1, i);  /* 2nd argument */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    30
    lua_call(L, 2, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    31
    if (!lua_isnil(L, -1))
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    32
      return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    33
    lua_pop(L, 1);  /* remove nil result */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    34
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    35
  return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    36
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    37
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    38
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    39
static int foreach (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    40
  luaL_checktype(L, 1, LUA_TTABLE);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    41
  luaL_checktype(L, 2, LUA_TFUNCTION);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    42
  lua_pushnil(L);  /* first key */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    43
  while (lua_next(L, 1)) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    44
    lua_pushvalue(L, 2);  /* function */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    45
    lua_pushvalue(L, -3);  /* key */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    46
    lua_pushvalue(L, -3);  /* value */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    47
    lua_call(L, 2, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    48
    if (!lua_isnil(L, -1))
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    49
      return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    50
    lua_pop(L, 2);  /* remove value and result */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    51
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    52
  return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    53
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    54
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    55
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    56
static int maxn (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    57
  lua_Number max = 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    58
  luaL_checktype(L, 1, LUA_TTABLE);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    59
  lua_pushnil(L);  /* first key */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    60
  while (lua_next(L, 1)) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    61
    lua_pop(L, 1);  /* remove value */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    62
    if (lua_type(L, -1) == LUA_TNUMBER) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    63
      lua_Number v = lua_tonumber(L, -1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    64
      if (v > max) max = v;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    65
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    66
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    67
  lua_pushnumber(L, max);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    68
  return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    69
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    70
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    71
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    72
static int getn (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    73
  lua_pushinteger(L, aux_getn(L, 1));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    74
  return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    75
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    76
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    77
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    78
static int setn (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    79
  luaL_checktype(L, 1, LUA_TTABLE);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    80
#ifndef luaL_setn
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    81
  luaL_setn(L, 1, luaL_checkint(L, 2));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    82
#else
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    83
  luaL_error(L, LUA_QL("setn") " is obsolete");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    84
#endif
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    85
  lua_pushvalue(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    86
  return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    87
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    88
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    89
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    90
static int tinsert (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    91
  int e = aux_getn(L, 1) + 1;  /* first empty element */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    92
  int pos;  /* where to insert new element */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    93
  switch (lua_gettop(L)) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    94
    case 2: {  /* called with only 2 arguments */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    95
      pos = e;  /* insert new element at the end */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    96
      break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    97
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    98
    case 3: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    99
      int i;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   100
      pos = luaL_checkint(L, 2);  /* 2nd argument is the position */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   101
      if (pos > e) e = pos;  /* `grow' array if necessary */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   102
      for (i = e; i > pos; i--) {  /* move up elements */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   103
        lua_rawgeti(L, 1, i-1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   104
        lua_rawseti(L, 1, i);  /* t[i] = t[i-1] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   105
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   106
      break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   107
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   108
    default: {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   109
      return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   110
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   111
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   112
  luaL_setn(L, 1, e);  /* new size */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   113
  lua_rawseti(L, 1, pos);  /* t[pos] = v */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   114
  return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   115
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   116
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   117
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   118
static int tremove (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   119
  int e = aux_getn(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   120
  int pos = luaL_optint(L, 2, e);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   121
  if (!(1 <= pos && pos <= e))  /* position is outside bounds? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   122
   return 0;  /* nothing to remove */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   123
  luaL_setn(L, 1, e - 1);  /* t.n = n-1 */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   124
  lua_rawgeti(L, 1, pos);  /* result = t[pos] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   125
  for ( ;pos<e; pos++) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   126
    lua_rawgeti(L, 1, pos+1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   127
    lua_rawseti(L, 1, pos);  /* t[pos] = t[pos+1] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   128
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   129
  lua_pushnil(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   130
  lua_rawseti(L, 1, e);  /* t[e] = nil */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   131
  return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   132
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   133
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   134
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   135
static void addfield (lua_State *L, luaL_Buffer *b, int i) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   136
  lua_rawgeti(L, 1, i);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   137
  if (!lua_isstring(L, -1))
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   138
    luaL_error(L, "invalid value (%s) at index %d in table for "
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   139
                  LUA_QL("concat"), luaL_typename(L, -1), i);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   140
    luaL_addvalue(b);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   141
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   142
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   143
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   144
static int tconcat (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   145
  luaL_Buffer b;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   146
  size_t lsep;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   147
  int i, last;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   148
  const char *sep = luaL_optlstring(L, 2, "", &lsep);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   149
  luaL_checktype(L, 1, LUA_TTABLE);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   150
  i = luaL_optint(L, 3, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   151
  last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   152
  luaL_buffinit(L, &b);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   153
  for (; i < last; i++) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   154
    addfield(L, &b, i);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   155
    luaL_addlstring(&b, sep, lsep);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   156
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   157
  if (i == last)  /* add last value (if interval was not empty) */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   158
    addfield(L, &b, i);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   159
  luaL_pushresult(&b);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   160
  return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   161
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   162
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   163
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   164
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   165
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   166
** {======================================================
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   167
** Quicksort
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   168
** (based on `Algorithms in MODULA-3', Robert Sedgewick;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   169
**  Addison-Wesley, 1993.)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   170
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   171
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   172
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   173
static void set2 (lua_State *L, int i, int j) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   174
  lua_rawseti(L, 1, i);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   175
  lua_rawseti(L, 1, j);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   176
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   177
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   178
static int sort_comp (lua_State *L, int a, int b) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   179
  if (!lua_isnil(L, 2)) {  /* function? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   180
    int res;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   181
    lua_pushvalue(L, 2);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   182
    lua_pushvalue(L, a-1);  /* -1 to compensate function */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   183
    lua_pushvalue(L, b-2);  /* -2 to compensate function and `a' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   184
    lua_call(L, 2, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   185
    res = lua_toboolean(L, -1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   186
    lua_pop(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   187
    return res;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   188
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   189
  else  /* a < b? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   190
    return lua_lessthan(L, a, b);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   191
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   192
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   193
static void auxsort (lua_State *L, int l, int u) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   194
  while (l < u) {  /* for tail recursion */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   195
    int i, j;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   196
    /* sort elements a[l], a[(l+u)/2] and a[u] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   197
    lua_rawgeti(L, 1, l);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   198
    lua_rawgeti(L, 1, u);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   199
    if (sort_comp(L, -1, -2))  /* a[u] < a[l]? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   200
      set2(L, l, u);  /* swap a[l] - a[u] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   201
    else
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   202
      lua_pop(L, 2);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   203
    if (u-l == 1) break;  /* only 2 elements */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   204
    i = (l+u)/2;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   205
    lua_rawgeti(L, 1, i);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   206
    lua_rawgeti(L, 1, l);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   207
    if (sort_comp(L, -2, -1))  /* a[i]<a[l]? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   208
      set2(L, i, l);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   209
    else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   210
      lua_pop(L, 1);  /* remove a[l] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   211
      lua_rawgeti(L, 1, u);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   212
      if (sort_comp(L, -1, -2))  /* a[u]<a[i]? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   213
        set2(L, i, u);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   214
      else
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   215
        lua_pop(L, 2);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   216
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   217
    if (u-l == 2) break;  /* only 3 elements */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   218
    lua_rawgeti(L, 1, i);  /* Pivot */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   219
    lua_pushvalue(L, -1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   220
    lua_rawgeti(L, 1, u-1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   221
    set2(L, i, u-1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   222
    /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   223
    i = l; j = u-1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   224
    for (;;) {  /* invariant: a[l..i] <= P <= a[j..u] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   225
      /* repeat ++i until a[i] >= P */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   226
      while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   227
        if (i>u) luaL_error(L, "invalid order function for sorting");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   228
        lua_pop(L, 1);  /* remove a[i] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   229
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   230
      /* repeat --j until a[j] <= P */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   231
      while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   232
        if (j<l) luaL_error(L, "invalid order function for sorting");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   233
        lua_pop(L, 1);  /* remove a[j] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   234
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   235
      if (j<i) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   236
        lua_pop(L, 3);  /* pop pivot, a[i], a[j] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   237
        break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   238
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   239
      set2(L, i, j);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   240
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   241
    lua_rawgeti(L, 1, u-1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   242
    lua_rawgeti(L, 1, i);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   243
    set2(L, u-1, i);  /* swap pivot (a[u-1]) with a[i] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   244
    /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   245
    /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   246
    if (i-l < u-i) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   247
      j=l; i=i-1; l=i+2;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   248
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   249
    else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   250
      j=i+1; i=u; u=j-2;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   251
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   252
    auxsort(L, j, i);  /* call recursively the smaller one */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   253
  }  /* repeat the routine for the larger one */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   254
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   255
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   256
static int sort (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   257
  int n = aux_getn(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   258
  luaL_checkstack(L, 40, "");  /* assume array is smaller than 2^40 */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   259
  if (!lua_isnoneornil(L, 2))  /* is there a 2nd argument? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   260
    luaL_checktype(L, 2, LUA_TFUNCTION);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   261
  lua_settop(L, 2);  /* make sure there is two arguments */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   262
  auxsort(L, 1, n);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   263
  return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   264
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   265
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   266
/* }====================================================== */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   267
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   268
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   269
static const luaL_Reg tab_funcs[] = {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   270
  {"concat", tconcat},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   271
  {"foreach", foreach},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   272
  {"foreachi", foreachi},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   273
  {"getn", getn},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   274
  {"maxn", maxn},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   275
  {"insert", tinsert},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   276
  {"remove", tremove},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   277
  {"setn", setn},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   278
  {"sort", sort},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   279
  {NULL, NULL}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   280
};
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   281
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   282
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   283
LUALIB_API int luaopen_table (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   284
  luaL_register(L, LUA_TABLIBNAME, tab_funcs);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   285
  return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   286
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   287