├── .gitignore ├── GL ├── gl3w.h └── glcorearb.h ├── LICENSE ├── Makefile ├── Makerules ├── area_export.py ├── bind.c ├── cache.c ├── console.c ├── data └── fonts │ ├── SourceCodePro-Regular.ttf │ └── SourceSansPro-Regular.ttf ├── draw.c ├── event.lua ├── font.c ├── getopt.h ├── gl3w.c ├── image.c ├── iqm.h ├── lua-5.2.2 ├── Makefile ├── README ├── doc │ ├── contents.html │ ├── logo.gif │ ├── lua.1 │ ├── lua.css │ ├── luac.1 │ ├── manual.css │ ├── manual.html │ ├── osi-certified-72x60.png │ └── readme.html └── src │ ├── Makefile │ ├── lapi.c │ ├── lapi.h │ ├── lauxlib.c │ ├── lauxlib.h │ ├── lbaselib.c │ ├── lbitlib.c │ ├── lcode.c │ ├── lcode.h │ ├── lcorolib.c │ ├── lctype.c │ ├── lctype.h │ ├── ldblib.c │ ├── ldebug.c │ ├── ldebug.h │ ├── ldo.c │ ├── ldo.h │ ├── ldump.c │ ├── lfunc.c │ ├── lfunc.h │ ├── lgc.c │ ├── lgc.h │ ├── linit.c │ ├── liolib.c │ ├── llex.c │ ├── llex.h │ ├── llimits.h │ ├── lmathlib.c │ ├── lmem.c │ ├── lmem.h │ ├── loadlib.c │ ├── lobject.c │ ├── lobject.h │ ├── lopcodes.c │ ├── lopcodes.h │ ├── loslib.c │ ├── lparser.c │ ├── lparser.h │ ├── lstate.c │ ├── lstate.h │ ├── lstring.c │ ├── lstring.h │ ├── lstrlib.c │ ├── ltable.c │ ├── ltable.h │ ├── ltablib.c │ ├── ltm.c │ ├── ltm.h │ ├── lua.c │ ├── lua.h │ ├── lua.hpp │ ├── luac.c │ ├── luaconf.h │ ├── lualib.h │ ├── lundump.c │ ├── lundump.h │ ├── lvm.c │ ├── lvm.h │ ├── lzio.c │ └── lzio.h ├── main.c ├── material.c ├── mio.h ├── model.c ├── model_iqe.c ├── model_iqm.c ├── model_obj.c ├── proxy.lua ├── queue.h ├── render.c ├── repr.lua ├── rune.c ├── scene.c ├── shader.c ├── stb_image.c ├── stb_truetype.h ├── strict.lua ├── strlcpy.c ├── tree.h ├── vector.c ├── vector.h └── zip.c /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | data 3 | .DS_Store 4 | .*.swp 5 | *.iqe 6 | *.iqm 7 | *.dae 8 | *.blend 9 | *.exe 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Tor Andersson 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 8 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 9 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 10 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 11 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 12 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 13 | PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # GNU Makefile 2 | 3 | build ?= debug 4 | 5 | default: all 6 | 7 | include Makerules 8 | 9 | OUT := build/$(build) 10 | 11 | ifeq "$(verbose)" "" 12 | QUIET_CC = @ echo " " CC $@ ; 13 | QUIET_AR = @ echo " " AR $@ ; 14 | QUIET_LINK = @ echo " " LINK $@ ; 15 | endif 16 | 17 | CC_CMD = $(QUIET_CC) $(CC) -o $@ -c $< $(CFLAGS) 18 | AR_CMD = $(QUIET_AR) $(AR) cru $@ $^ 19 | LINK_CMD = $(QUIET_LINK) $(CC) -o $@ $^ $(LDFLAGS) $(LIBS) 20 | 21 | LUA_DIR := lua-5.2.2/src 22 | LUA_SRC := \ 23 | lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c \ 24 | lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c \ 25 | ltm.c lundump.c lvm.c lzio.c \ 26 | lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c \ 27 | lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c 28 | LUA_OBJ := $(addprefix $(OUT)/, $(LUA_SRC:%.c=%.o)) 29 | LUA_LIB := $(OUT)/liblua.a 30 | LUA_CMD_OBJ := lua.c 31 | LUAC_CMD_OBJ := luac.c 32 | 33 | MIO_HDR := getopt.h iqm.h mio.h stb_truetype.h stb_image.c 34 | MIO_SRC := \ 35 | cache.c console.c draw.c font.c gl3w.c image.c \ 36 | model.c model_obj.c model_iqe.c model_iqm.c \ 37 | material.c scene.c render.c bind.c \ 38 | rune.c shader.c strlcpy.c vector.c zip.c 39 | MIO_OBJ := $(addprefix $(OUT)/, $(MIO_SRC:%.c=%.o)) 40 | MIO_LIB := $(OUT)/libmio.a 41 | 42 | $(OUT) : 43 | mkdir -p $@ 44 | 45 | $(OUT)/%.o : %.c $(MIO_HDR) 46 | $(CC_CMD) -I$(LUA_DIR) 47 | 48 | $(OUT)/%.o : $(LUA_DIR)/%.c 49 | $(CC_CMD) 50 | 51 | $(LUA_LIB) : $(LUA_OBJ) 52 | $(AR_CMD) 53 | 54 | $(MIO_LIB) : $(MIO_OBJ) 55 | $(AR_CMD) 56 | 57 | lua.exe : $(OUT)/lua.o $(LUA_LIB) 58 | $(LINK_CMD) 59 | 60 | luac.exe : $(OUT)/luac.o $(LUA_LIB) 61 | $(LINK_CMD) 62 | 63 | mio.exe : $(OUT)/main.o $(MIO_LIB) $(LUA_LIB) 64 | $(LINK_CMD) 65 | 66 | all: $(OUT) $(LUA_LIB) $(MIO_LIB) mio.exe 67 | 68 | tags: $(MIO_SRC) $(MIO_HDR) 69 | ctags $^ 70 | 71 | clean: 72 | rm -rf $(OUT) 73 | -------------------------------------------------------------------------------- /Makerules: -------------------------------------------------------------------------------- 1 | # System specific configuration 2 | 3 | OS := $(shell uname) 4 | OS := $(OS:MINGW%=MINGW) 5 | 6 | CFLAGS := -Wall -I. 7 | 8 | ifeq "$(build)" "debug" 9 | CFLAGS += -g -DDEBUG 10 | endif 11 | ifeq "$(build)" "release" 12 | CFLAGS += -O2 -DNDEBUG -fomit-frame-pointer 13 | endif 14 | 15 | ifeq "$(OS)" "Linux" 16 | LIBS += -lglut -lGL -lm -ldl 17 | endif 18 | 19 | ifeq "$(OS)" "Darwin" 20 | CFLAGS += -m32 21 | LDFLAGS += -m32 22 | LIBS += -framework GLUT -framework OpenGL -framework Cocoa 23 | endif 24 | 25 | ifeq "$(OS)" "MINGW" 26 | CFLAGS += -DFREEGLUT_STATIC -I../freeglut/include -DHAVE_SRGB_FRAMEBUFFER 27 | LIBS += -L../freeglut/lib -lfreeglut_static -lopengl32 -lwinmm -lgdi32 28 | ifeq "$(build)" "release" 29 | LIBS += -mwindows 30 | endif 31 | endif 32 | -------------------------------------------------------------------------------- /area_export.py: -------------------------------------------------------------------------------- 1 | # Export scene as a lua script along with IQE files. 2 | 3 | bl_info = { 4 | "name": "Export Area", 5 | "description": "Export Area for Mio project.", 6 | "author": "Tor Andersson", 7 | "version": (2013, 9, 8), 8 | "blender": (2, 6, 7), 9 | "location": "File > Export > Area", 10 | "wiki_url": "http://github.com/ccxvii/mio", 11 | "category": "Import-Export", 12 | } 13 | 14 | import bpy, math, struct, os, sys 15 | 16 | from bpy.props import * 17 | from bpy_extras.io_utils import ExportHelper 18 | from mathutils import Matrix, Quaternion, Vector 19 | 20 | done_meshes = set() 21 | 22 | def quote(s): 23 | return "\"%s\"" % s 24 | 25 | def file_write_transform(file, matrix, noscale=False): 26 | t, r, s = matrix.decompose() 27 | file.write("\ttransform = {\n") 28 | file.write("\t\tposition = {%g, %g, %g},\n" % (t.x, t.y, t.z)) 29 | file.write("\t\trotation = {%g, %g, %g, %g},\n" % (r.x, r.y, r.z, r.w)) 30 | if not noscale: 31 | file.write("\t\tscale = {%.9g, %.9g, %.9g},\n" % (s.x, s.y, s.z)) 32 | file.write("\t},\n") 33 | 34 | def export_mesh(filename, mesh): 35 | if mesh in done_meshes: 36 | return 37 | done_meshes.add(mesh) 38 | 39 | print("exporting mesh", filename) 40 | 41 | file = open(filename, "w") 42 | file.write("# Inter-Quake Export\n") 43 | 44 | mesh.calc_tessface() 45 | texcoords = mesh.tessface_uv_textures.get('UVMap') 46 | colors = mesh.tessface_vertex_colors.get('Col') 47 | 48 | out = {} 49 | for face in mesh.tessfaces: 50 | fm = face.material_index 51 | if not fm in out: 52 | out[fm] = [] 53 | out[fm].append(face) 54 | 55 | for fm in out.keys(): 56 | vertex_map = {} 57 | vertex_list = [] 58 | face_list = [] 59 | 60 | for face in out[fm]: 61 | ft = texcoords and texcoords.data[face.index] 62 | fc = colors and colors.data[face.index] 63 | ft = ft and [ft.uv1, ft.uv2, ft.uv3, ft.uv4] 64 | fc = fc and [fc.color1, fc.color2, fc.color3, fc.color4] 65 | f = [] 66 | for i, v in enumerate(face.vertices): 67 | vp = tuple(mesh.vertices[v].co) 68 | vn = tuple(mesh.vertices[v].normal) 69 | vt = ft and tuple(ft[i]) 70 | vc = fc and tuple(fc[i]) 71 | v = vp, vn, vt, vc 72 | if v not in vertex_map: 73 | vertex_map[v] = len(vertex_list) 74 | vertex_list.append(v) 75 | f.append(vertex_map[v]) 76 | face_list.append(f) 77 | 78 | file.write("\n") 79 | file.write("mesh %s\n" % quote(mesh.name)) 80 | if fm < len(mesh.materials): 81 | file.write("material %s\n" % quote(mesh.materials[fm].name)) 82 | else: 83 | file.write("material None\n") 84 | for vp, vn, vt, vc in vertex_list: 85 | file.write("vp %.9g %.9g %.9g\n" % vp) 86 | file.write("vn %.9g %.9g %.9g\n" % vn) 87 | if vt: file.write("vt %.9g %.9g\n" % (vt[0], 1.0 - vt[1])) 88 | if vc: file.write("vc %.9g %.9g %.9g\n" % vc) 89 | for f in face_list: 90 | if len(f) == 3: 91 | file.write("fm %d %d %d\n" % (f[2], f[1], f[0])) 92 | else: 93 | file.write("fm %d %d %d %d\n" % (f[3], f[2], f[1], f[0])) 94 | 95 | file.close() 96 | 97 | def export_object_lamp(dir, file, scene, obj, lamp): 98 | if lamp.type == 'AREA': return 99 | if lamp.type == 'HEMI': return 100 | file.write("\tlamp = {\n") 101 | file.write("\t\ttype = '%s',\n" % lamp.type) 102 | file.write("\t\tcolor = {%g, %g, %g},\n" % tuple(lamp.color[:3])) 103 | file.write("\t\tenergy = %g,\n" % lamp.energy) 104 | if lamp.type == 'SPOT' or lamp.type == 'POINT': 105 | file.write("\t\tdistance = %g,\n" % lamp.distance) 106 | file.write("\t\tuse_sphere = %s,\n" % ("true" if lamp.use_sphere else "false")) 107 | if lamp.type == 'SPOT': 108 | file.write("\t\tspot_angle = %g,\n" % math.degrees(lamp.spot_size)) 109 | file.write("\t\tspot_blend = %g,\n" % lamp.spot_blend) 110 | file.write("\t\tuse_shadow = %s,\n" % ("true" if lamp.use_shadow else "false")) 111 | file.write("\t},\n") 112 | 113 | def export_object_mesh(dir, file, scene, obj): 114 | if len(obj.modifiers) == 0: 115 | mesh = obj.data 116 | meshname = mesh.name 117 | export_mesh(dir + "/" + meshname + ".iqe", mesh) 118 | else: 119 | mesh = obj.to_mesh(scene, True, 'PREVIEW') 120 | meshname = "object_" + obj.name 121 | export_mesh(dir + "/" + meshname + ".iqe", mesh) 122 | bpy.data.meshes.remove(mesh) 123 | file.write("\tmesh = %s,\n" % quote(meshname)) 124 | #file_write_color(file, obj.color) 125 | 126 | def export_object_dupli_group(dir, file, scene, obj): 127 | file.write("\tmesh = %s,\n" % quote(obj.dupli_group.name)) 128 | 129 | def export_object(dir, file, scene, obj): 130 | file.write("\nentity {\n") 131 | file.write("\tname = %s,\n" % quote(obj.name)) 132 | file_write_transform(file, obj.matrix_world) 133 | if obj.type == 'LAMP': 134 | export_object_lamp(dir, file, scene, obj, obj.data) 135 | elif obj.type == 'MESH': 136 | export_object_mesh(dir, file, scene, obj) 137 | elif obj.type == 'EMPTY': 138 | if obj.dupli_type == 'GROUP': 139 | export_object_dupli_group(dir, file, scene, obj) 140 | file.write("}\n") 141 | 142 | def export_scene(dir, scene): 143 | print("exporting scene", scene.name) 144 | file = open(dir + "/" + scene.name + ".lua", "w") 145 | file.write("-- scene: " + scene.name + "\n") 146 | for obj in scene.objects: 147 | export_object(dir, file, scene, obj) 148 | file.close() 149 | 150 | def export_blend(dir): 151 | print("exporting to directory", dir) 152 | os.makedirs(dir, exist_ok=True) 153 | for scene in bpy.data.scenes: 154 | export_scene(dir, scene) 155 | 156 | if __name__ == "__main__": 157 | if len(sys.argv) > 4 and sys.argv[-2] == '--': 158 | export_blend(sys.argv[-1]) 159 | else: 160 | dir = os.path.splitext(bpy.data.filepath)[0] 161 | export_blend(dir) 162 | -------------------------------------------------------------------------------- /cache.c: -------------------------------------------------------------------------------- 1 | #include "mio.h" 2 | 3 | /* Use an AA-tree to quickly look up resources. */ 4 | 5 | struct cache 6 | { 7 | char *key; 8 | void *value; 9 | struct cache *left, *right; 10 | int level; 11 | }; 12 | 13 | static struct cache sentinel = { "", NULL, &sentinel, &sentinel, 0 }; 14 | 15 | static struct cache *make_node(const char *key, void *value) 16 | { 17 | struct cache *node = malloc(sizeof(struct cache)); 18 | node->key = strdup(key); 19 | node->value = value; 20 | node->left = node->right = &sentinel; 21 | node->level = 1; 22 | return node; 23 | } 24 | 25 | void *lookup(struct cache *node, const char *key) 26 | { 27 | if (node) { 28 | while (node != &sentinel) { 29 | int c = strcmp(key, node->key); 30 | if (c == 0) 31 | return node->value; 32 | else if (c < 0) 33 | node = node->left; 34 | else 35 | node = node->right; 36 | } 37 | } 38 | return NULL; 39 | } 40 | 41 | static struct cache *skew(struct cache *node) 42 | { 43 | if (node->left->level == node->level) { 44 | struct cache *save = node; 45 | node = node->left; 46 | save->left = node->right; 47 | node->right = save; 48 | } 49 | return node; 50 | } 51 | 52 | static struct cache *split(struct cache *node) 53 | { 54 | if (node->right->right->level == node->level) { 55 | struct cache *save = node; 56 | node = node->right; 57 | save->right = node->left; 58 | node->left = save; 59 | node->level++; 60 | } 61 | return node; 62 | } 63 | 64 | struct cache *insert(struct cache *node, const char *key, void *value) 65 | { 66 | if (node && node != &sentinel) { 67 | int c = strcmp(key, node->key); 68 | if (c < 0) 69 | node->left = insert(node->left, key, value); 70 | else 71 | node->right = insert(node->right, key, value); 72 | node = skew(node); 73 | node = split(node); 74 | return node; 75 | } 76 | return make_node(key, value); 77 | } 78 | 79 | static void print_cache_imp(struct cache *node, int level) 80 | { 81 | int i; 82 | if (node->left != &sentinel) 83 | print_cache_imp(node->left, level + 1); 84 | for (i = 0; i < level; i++) 85 | putchar(' '); 86 | printf("%s = %p (%d)\n", node->key, node->value, node->level); 87 | if (node->right != &sentinel) 88 | print_cache_imp(node->right, level + 1); 89 | } 90 | 91 | void print_cache(struct cache *root) 92 | { 93 | printf("--- cache dump ---\n"); 94 | if (root && root != &sentinel) 95 | print_cache_imp(root, 0); 96 | printf("---\n"); 97 | } 98 | -------------------------------------------------------------------------------- /console.c: -------------------------------------------------------------------------------- 1 | #include "mio.h" 2 | #include 3 | 4 | void warn(const char *fmt, ...) 5 | { 6 | va_list ap; 7 | char buf[4096]; 8 | va_start(ap, fmt); 9 | vsnprintf(buf, sizeof buf, fmt, ap); 10 | va_end(ap); 11 | console_printnl(buf); 12 | } 13 | 14 | #define PS1 "> " 15 | #define PS2 ">>" 16 | #define COLS 80 17 | #define ROWS 23 18 | #define LAST (ROWS-1) 19 | #define INPUT 80-2 20 | #define HISTORY 100 21 | #define TABSTOP 4 22 | 23 | static char screen[ROWS][COLS+1] = {{0}}; 24 | static int tail = 0; 25 | static char input[INPUT] = {0}; 26 | static int cursor = 0; 27 | static int end = 0; 28 | 29 | static struct history_entry { 30 | TAILQ_ENTRY(history_entry) list; 31 | char s[INPUT]; 32 | } *hist_look; 33 | 34 | static TAILQ_HEAD(history_list, history_entry) history; 35 | 36 | static void scrollup(void) 37 | { 38 | int i; 39 | for (i = 1; i < ROWS; i++) 40 | memcpy(screen[i-1], screen[i], COLS); 41 | screen[LAST][0] = 0; 42 | tail = 0; 43 | } 44 | 45 | void console_putc(int c) 46 | { 47 | putchar(c); 48 | if (c == '\n') { 49 | scrollup(); 50 | } else if (tail >= COLS) { 51 | scrollup(); 52 | screen[LAST][tail++] = c; 53 | } else if (c == '\t') { 54 | int n = TABSTOP - (tail % TABSTOP); 55 | while (n--) 56 | console_putc(' '); 57 | } else { 58 | screen[LAST][tail++] = c; 59 | } 60 | screen[LAST][tail] = 0; 61 | } 62 | 63 | void console_print(const char *s) 64 | { 65 | while (*s) console_putc(*s++); 66 | } 67 | 68 | void console_printnl(const char *s) 69 | { 70 | while (*s) console_putc(*s++); 71 | console_putc('\n'); 72 | } 73 | 74 | void console_printf(const char *fmt, ...) 75 | { 76 | va_list ap; 77 | char buf[4096]; 78 | va_start(ap, fmt); 79 | vsnprintf(buf, sizeof buf, fmt, ap); 80 | va_end(ap); 81 | console_print(buf); 82 | } 83 | 84 | static void console_history_push(char *s) 85 | { 86 | if (strlen(s) > 0) { 87 | struct history_entry *line = malloc(sizeof *line); 88 | strlcpy(line->s, s, sizeof line->s); 89 | TAILQ_INSERT_HEAD(&history, line, list); 90 | hist_look = NULL; 91 | } 92 | } 93 | 94 | static void console_history_prev(void) 95 | { 96 | struct history_entry *candidate; 97 | candidate = hist_look ? TAILQ_NEXT(hist_look, list) : TAILQ_FIRST(&history); 98 | if (candidate) { 99 | hist_look = candidate; 100 | memcpy(input, hist_look->s, INPUT); 101 | cursor = end = strlen(input); 102 | } 103 | } 104 | 105 | static void console_history_next(void) 106 | { 107 | hist_look = hist_look ? TAILQ_PREV(hist_look, history_list, list) : NULL; 108 | if (hist_look) { 109 | memcpy(input, hist_look->s, INPUT); 110 | cursor = end = strlen(input); 111 | } else { 112 | cursor = end = 0; 113 | input[0] = 0; 114 | } 115 | } 116 | 117 | static void console_enter(void) 118 | { 119 | char cmd[INPUT]; 120 | 121 | console_history_push(input); 122 | console_print(PS1); 123 | console_printnl(input); 124 | 125 | if (input[0] == '=') { 126 | strlcpy(cmd, "return ", sizeof cmd); 127 | strlcat(cmd, input + 1, sizeof cmd); 128 | } else { 129 | strlcpy(cmd, input, sizeof cmd); 130 | } 131 | 132 | input[0] = 0; 133 | cursor = end = 0; 134 | 135 | run_string(cmd); 136 | } 137 | 138 | static void console_insert(int c) 139 | { 140 | hist_look = NULL; 141 | if (end + 1 < INPUT) { 142 | memmove(input + cursor + 1, input + cursor, end - cursor); 143 | input[cursor++] = c; 144 | input[++end] = 0; 145 | } 146 | } 147 | 148 | static void console_backspace(void) 149 | { 150 | hist_look = NULL; 151 | if (cursor > 0) { 152 | memmove(input + cursor - 1, input + cursor, end - cursor); 153 | input[--end] = 0; 154 | --cursor; 155 | } 156 | } 157 | 158 | static void console_delete(void) 159 | { 160 | hist_look = NULL; 161 | if (cursor < end) { 162 | memmove(input + cursor, input + cursor + 1, end - cursor); 163 | input[--end] = 0; 164 | } 165 | } 166 | 167 | void console_backspace_word(void) 168 | { 169 | while (cursor > 0 && !isalnum(input[cursor-1])) console_backspace(); 170 | while (cursor > 0 && isalnum(input[cursor-1])) console_backspace(); 171 | } 172 | 173 | void console_delete_word(void) 174 | { 175 | while (cursor < end && isalnum(input[cursor])) console_delete(); 176 | while (cursor < end && !isalnum(input[cursor])) console_delete(); 177 | } 178 | 179 | void console_skip_word_left(void) 180 | { 181 | while (cursor > 0 && !isalnum(input[cursor-1])) --cursor; 182 | while (cursor > 0 && isalnum(input[cursor-1])) --cursor; 183 | } 184 | 185 | void console_skip_word_right(void) 186 | { 187 | while (cursor < end && !isalnum(input[cursor])) ++cursor; 188 | while (cursor < end && isalnum(input[cursor])) ++cursor; 189 | } 190 | 191 | #define CTL(x) (x-64) 192 | 193 | void console_keyboard(int key, int mod) 194 | { 195 | #ifdef __APPLE__ 196 | /* Stupid Apple... */ 197 | if (key == 0x7F) key = 0x08; 198 | else if (key == 0x8) key = 0x7F; 199 | #endif 200 | 201 | if (key >= 0xE000 && key < 0xF900) return; // in PUA 202 | if (key >= 0x10000) return; // outside BMP 203 | 204 | if (mod & GLUT_ACTIVE_ALT) { 205 | switch (key) { 206 | case 'b': console_skip_word_left(); break; 207 | case 'f': console_skip_word_right(); break; 208 | case 'd': console_delete_word(); 209 | } 210 | return; 211 | } 212 | 213 | if (mod & GLUT_ACTIVE_CTRL) { 214 | switch (key) { 215 | case CTL('A'): cursor = 0; break; 216 | case CTL('E'): cursor = end; break; 217 | case CTL('B'): if (cursor > 0) --cursor; break; 218 | case CTL('F'): if (cursor < end) ++cursor; break; 219 | case CTL('H'): console_backspace(); break; 220 | case CTL('U'): while (cursor > 0) console_backspace(); break; 221 | case CTL('K'): while (cursor < end) console_delete(); break; 222 | case CTL('W'): console_backspace_word(); break; 223 | case CTL('T'): if (cursor > 1) { int t = input[cursor-1]; input[cursor-1] = input[cursor]; input[cursor] = t; } break; 224 | case CTL('P'): console_history_prev(); break; 225 | case CTL('N'): console_history_next(); break; 226 | } 227 | return; 228 | } 229 | 230 | if (key == '\r') { 231 | console_enter(); 232 | } else if (key == 0x08) { 233 | console_backspace(); 234 | } else if (key == 0x7F) { 235 | console_delete(); 236 | } else if (isprint(key)) { 237 | console_insert(key); 238 | } 239 | } 240 | 241 | void console_special(int key, int mod) 242 | { 243 | if (mod & GLUT_ACTIVE_CTRL) { 244 | switch (key) { 245 | case GLUT_KEY_LEFT: console_skip_word_left(); break; 246 | case GLUT_KEY_RIGHT: console_skip_word_right(); break; 247 | case GLUT_KEY_UP: cursor = 0; break; 248 | case GLUT_KEY_DOWN: cursor = end; break; 249 | } 250 | return; 251 | } 252 | 253 | switch (key) { 254 | case GLUT_KEY_LEFT: if (cursor > 0) --cursor; break; 255 | case GLUT_KEY_RIGHT: if (cursor < end) ++cursor; break; 256 | case GLUT_KEY_HOME: cursor = 0; break; 257 | case GLUT_KEY_END: cursor = end; break; 258 | case GLUT_KEY_UP: console_history_prev(); break; 259 | case GLUT_KEY_DOWN: console_history_next(); break; 260 | } 261 | } 262 | 263 | void console_draw(mat4 clip_from_view, mat4 view_from_world, struct font *font, float size) 264 | { 265 | float model_view[16]; 266 | float screenw = 2 / clip_from_view[0]; // assume we have an orthogonal matrix 267 | float cellw = font_width(font, size, "0"); 268 | float cellh = size + 2; 269 | float ascent = size * 0.8; 270 | float descent = size * 0.2; 271 | float margin = 8; 272 | 273 | int x0 = (screenw - cellw * COLS) / 2; 274 | int y0 = margin; 275 | int x1 = x0 + cellw * COLS; 276 | int y1 = y0 + cellh * ROWS; 277 | float x, y; 278 | int i; 279 | 280 | mat_identity(model_view); 281 | 282 | draw_begin(clip_from_view, view_from_world); 283 | draw_set_color(0, 0, 0, 0.8); 284 | draw_rect(x0-margin, y0-margin, x1+margin, y1+margin); 285 | draw_end(); 286 | 287 | text_begin(clip_from_view, view_from_world); 288 | text_set_color(1, 1, 1, 1); 289 | text_set_font(font, size); 290 | 291 | y = y0 + ascent; 292 | 293 | for (i = 0; i < ROWS; i++) { 294 | x = text_show(x0, y, screen[i]); 295 | y += cellh; 296 | } 297 | y -= cellh; 298 | x = text_show(x, y, PS1); 299 | x = text_show(x, y, input); 300 | x -= text_width(input + cursor); 301 | 302 | text_end(); 303 | 304 | draw_begin(clip_from_view, view_from_world); 305 | draw_set_color(1, 1, 1, 1); 306 | draw_line(x+1, y-ascent, 0, x+1, y+descent-1, 0); 307 | draw_end(); 308 | } 309 | -------------------------------------------------------------------------------- /data/fonts/SourceCodePro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccxvii/mio/22842b27aa852cb3a3a740e9d1a8fc669521b994/data/fonts/SourceCodePro-Regular.ttf -------------------------------------------------------------------------------- /data/fonts/SourceSansPro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccxvii/mio/22842b27aa852cb3a3a740e9d1a8fc669521b994/data/fonts/SourceSansPro-Regular.ttf -------------------------------------------------------------------------------- /draw.c: -------------------------------------------------------------------------------- 1 | #include "mio.h" 2 | 3 | /* 4 | * Line and rect drawing. 5 | */ 6 | 7 | static const char *draw_vert_src = 8 | "uniform mat4 clip_from_view;\n" 9 | "uniform mat4 view_from_world;\n" 10 | "in vec4 att_position;\n" 11 | "in vec4 att_color;\n" 12 | "out vec4 var_color;\n" 13 | "void main() {\n" 14 | " gl_Position = clip_from_view * view_from_world * att_position;\n" 15 | " var_color = att_color;\n" 16 | "}\n" 17 | ; 18 | 19 | static const char *draw_frag_src = 20 | "in vec4 var_color;\n" 21 | "out vec4 frag_color;\n" 22 | "void main() {\n" 23 | " frag_color = var_color;\n" 24 | "}\n" 25 | ; 26 | 27 | #define MAXBUFFER (256*2) /* size of our triangle buffer */ 28 | 29 | static unsigned int draw_vao = 0; 30 | static unsigned int draw_vbo = 0; 31 | static int draw_buf_len = 0; 32 | static struct { 33 | float position[3]; 34 | float color[4]; 35 | } draw_buf[MAXBUFFER]; 36 | 37 | static float draw_color[4] = { 1, 1, 1, 1 }; 38 | static int draw_kind = GL_LINES; 39 | 40 | void draw_set_color(float r, float g, float b, float a) 41 | { 42 | draw_color[0] = r; 43 | draw_color[1] = g; 44 | draw_color[2] = b; 45 | draw_color[3] = a; 46 | } 47 | 48 | void draw_begin(mat4 clip_from_view, mat4 view_from_world) 49 | { 50 | static int draw_prog = 0; 51 | static int draw_uni_clip_from_view = -1; 52 | static int draw_uni_view_from_world = -1; 53 | 54 | if (!draw_prog) { 55 | draw_prog = compile_shader(draw_vert_src, draw_frag_src); 56 | draw_uni_clip_from_view = glGetUniformLocation(draw_prog, "clip_from_view"); 57 | draw_uni_view_from_world = glGetUniformLocation(draw_prog, "view_from_world"); 58 | } 59 | 60 | if (!draw_vao) { 61 | glGenVertexArrays(1, &draw_vao); 62 | glBindVertexArray(draw_vao); 63 | 64 | glGenBuffers(1, &draw_vbo); 65 | glBindBuffer(GL_ARRAY_BUFFER, draw_vbo); 66 | glBufferData(GL_ARRAY_BUFFER, sizeof draw_buf, NULL, GL_STREAM_DRAW); 67 | 68 | glEnableVertexAttribArray(ATT_POSITION); 69 | glEnableVertexAttribArray(ATT_COLOR); 70 | glVertexAttribPointer(ATT_POSITION, 3, GL_FLOAT, 0, sizeof draw_buf[0], (void*)0); 71 | glVertexAttribPointer(ATT_COLOR, 4, GL_FLOAT, 0, sizeof draw_buf[0], (void*)12); 72 | } 73 | 74 | glEnable(GL_BLEND); 75 | 76 | glUseProgram(draw_prog); 77 | glUniformMatrix4fv(draw_uni_clip_from_view, 1, 0, clip_from_view); 78 | glUniformMatrix4fv(draw_uni_view_from_world, 1, 0, view_from_world); 79 | 80 | glBindVertexArray(draw_vao); 81 | } 82 | 83 | static void draw_flush(void) 84 | { 85 | if (draw_buf_len > 0) { 86 | glBindBuffer(GL_ARRAY_BUFFER, draw_vbo); 87 | glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof draw_buf[0] * draw_buf_len, draw_buf); 88 | glDrawArrays(draw_kind, 0, draw_buf_len); 89 | draw_buf_len = 0; 90 | } 91 | } 92 | 93 | void draw_end(void) 94 | { 95 | draw_flush(); 96 | 97 | glDisable(GL_BLEND); 98 | } 99 | 100 | static void draw_vertex(float x, float y, float z) 101 | { 102 | draw_buf[draw_buf_len].position[0] = x; 103 | draw_buf[draw_buf_len].position[1] = y; 104 | draw_buf[draw_buf_len].position[2] = z; 105 | draw_buf[draw_buf_len].color[0] = draw_color[0]; 106 | draw_buf[draw_buf_len].color[1] = draw_color[1]; 107 | draw_buf[draw_buf_len].color[2] = draw_color[2]; 108 | draw_buf[draw_buf_len].color[3] = draw_color[3]; 109 | draw_buf_len++; 110 | } 111 | 112 | void draw_line(float x0, float y0, float z0, float x1, float y1, float z1) 113 | { 114 | if (draw_kind != GL_LINES) 115 | draw_flush(); 116 | if (draw_buf_len + 2 >= MAXBUFFER) 117 | draw_flush(); 118 | 119 | draw_kind = GL_LINES; 120 | draw_vertex(x0, y0, z0); 121 | draw_vertex(x1, y1, z1); 122 | } 123 | 124 | void draw_triangle(float x0, float y0, float z0, 125 | float x1, float y1, float z1, 126 | float x2, float y2, float z2) 127 | { 128 | if (draw_kind != GL_TRIANGLES) 129 | draw_flush(); 130 | if (draw_buf_len + 3 >= MAXBUFFER) 131 | draw_flush(); 132 | 133 | draw_kind = GL_TRIANGLES; 134 | draw_vertex(x0, y0, z0); 135 | draw_vertex(x1, y1, z1); 136 | draw_vertex(x2, y2, z2); 137 | } 138 | 139 | void draw_quad(float x0, float y0, float z0, 140 | float x1, float y1, float z1, 141 | float x2, float y2, float z2, 142 | float x3, float y3, float z3) 143 | { 144 | if (draw_kind != GL_TRIANGLES) 145 | draw_flush(); 146 | if (draw_buf_len + 6 >= MAXBUFFER) 147 | draw_flush(); 148 | 149 | draw_kind = GL_TRIANGLES; 150 | draw_vertex(x0, y0, z0); 151 | draw_vertex(x1, y1, z1); 152 | draw_vertex(x2, y2, z2); 153 | draw_vertex(x0, y0, z0); 154 | draw_vertex(x2, y2, z2); 155 | draw_vertex(x3, y3, z3); 156 | } 157 | 158 | void draw_rect(float x0, float y0, float x1, float y1) 159 | { 160 | if (draw_kind != GL_TRIANGLES) 161 | draw_flush(); 162 | if (draw_buf_len + 6 >= MAXBUFFER) 163 | draw_flush(); 164 | 165 | draw_kind = GL_TRIANGLES; 166 | draw_vertex(x0, y0, 0); 167 | draw_vertex(x0, y1, 0); 168 | draw_vertex(x1, y1, 0); 169 | draw_vertex(x0, y0, 0); 170 | draw_vertex(x1, y1, 0); 171 | draw_vertex(x1, y0, 0); 172 | } 173 | -------------------------------------------------------------------------------- /event.lua: -------------------------------------------------------------------------------- 1 | uistate = {} 2 | 3 | function on_keyboard(key, mod, x, y) 4 | print("key", key, mod, x, y) 5 | if key == 'UP' then mixer = mixer + 0.1 end 6 | if key == 'DOWN' then mixer = mixer - 0.1 end 7 | if mixer < 0 then mixer = 0 end 8 | if mixer > 1 then mixer = 1 end 9 | end 10 | 11 | function on_mouse(button, state, mod, x, y) 12 | print("mouse", button, state, mod, x, y) 13 | end 14 | 15 | function on_motion(x, y) 16 | print("motion", x, y) 17 | end 18 | -------------------------------------------------------------------------------- /getopt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a version of the public domain getopt implementation by 3 | * Henry Spencer originally posted to net.sources. 4 | * 5 | * This file is in the public domain. 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | char *optarg; /* Global argument pointer. */ 12 | int optind = 0; /* Global argv index. */ 13 | 14 | int 15 | getopt(int argc, char *argv[], char *optstring) 16 | { 17 | static char *scan = NULL; /* Private scan pointer. */ 18 | char c; 19 | char *place; 20 | 21 | optarg = NULL; 22 | 23 | if (scan == NULL || *scan == '\0') { 24 | if (optind == 0) 25 | optind++; 26 | 27 | if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') 28 | return EOF; 29 | if (argv[optind][1] == '-' && argv[optind][2] == '\0') { 30 | optind++; 31 | return EOF; 32 | } 33 | 34 | scan = argv[optind]+1; 35 | optind++; 36 | } 37 | 38 | c = *scan++; 39 | place = strchr(optstring, c); 40 | 41 | if (place == NULL || c == ':') { 42 | fprintf(stderr, "%s: unknown option -%c\n", argv[0], c); 43 | return '?'; 44 | } 45 | 46 | place++; 47 | if (*place == ':') { 48 | if (*scan != '\0') { 49 | optarg = scan; 50 | scan = NULL; 51 | } else if( optind < argc ) { 52 | optarg = argv[optind]; 53 | optind++; 54 | } else { 55 | fprintf(stderr, "%s: option requires argument -%c\n", argv[0], c); 56 | return ':'; 57 | } 58 | } 59 | 60 | return c; 61 | } 62 | -------------------------------------------------------------------------------- /iqm.h: -------------------------------------------------------------------------------- 1 | #ifndef __IQM_H__ 2 | #define __IQM_H__ 3 | 4 | #define IQM_MAGIC "INTERQUAKEMODEL" 5 | #define IQM_VERSION 2 6 | 7 | struct iqmheader 8 | { 9 | char magic[16]; 10 | unsigned int version; 11 | unsigned int filesize; 12 | unsigned int flags; 13 | unsigned int num_text, ofs_text; 14 | unsigned int num_meshes, ofs_meshes; 15 | unsigned int num_vertexarrays, num_vertexes, ofs_vertexarrays; 16 | unsigned int num_triangles, ofs_triangles, ofs_adjacency; 17 | unsigned int num_joints, ofs_joints; 18 | unsigned int num_poses, ofs_poses; 19 | unsigned int num_anims, ofs_anims; 20 | unsigned int num_frames, num_framechannels, ofs_frames, ofs_bounds; 21 | unsigned int num_comment, ofs_comment; 22 | unsigned int num_extensions, ofs_extensions; 23 | }; 24 | 25 | struct iqmmesh 26 | { 27 | unsigned int name; 28 | unsigned int material; 29 | unsigned int first_vertex, num_vertexes; 30 | unsigned int first_triangle, num_triangles; 31 | }; 32 | 33 | enum 34 | { 35 | IQM_POSITION = 0, 36 | IQM_TEXCOORD = 1, 37 | IQM_NORMAL = 2, 38 | IQM_TANGENT = 3, 39 | IQM_BLENDINDEXES = 4, 40 | IQM_BLENDWEIGHTS = 5, 41 | IQM_COLOR = 6, 42 | IQM_CUSTOM = 0x10 43 | }; 44 | 45 | enum 46 | { 47 | IQM_BYTE = 0, 48 | IQM_UBYTE = 1, 49 | IQM_SHORT = 2, 50 | IQM_USHORT = 3, 51 | IQM_INT = 4, 52 | IQM_UINT = 5, 53 | IQM_HALF = 6, 54 | IQM_FLOAT = 7, 55 | IQM_DOUBLE = 8, 56 | }; 57 | 58 | struct iqmtriangle 59 | { 60 | unsigned int vertex[3]; 61 | }; 62 | 63 | struct iqmjointv1 64 | { 65 | unsigned int name; 66 | int parent; 67 | float translate[3], rotate[3], scale[3]; 68 | }; 69 | 70 | struct iqmjoint 71 | { 72 | unsigned int name; 73 | int parent; 74 | float translate[3], rotate[4], scale[3]; 75 | }; 76 | 77 | struct iqmposev1 78 | { 79 | int parent; 80 | unsigned int mask; 81 | float channeloffset[9]; 82 | float channelscale[9]; 83 | }; 84 | 85 | struct iqmpose 86 | { 87 | int parent; 88 | unsigned int mask; 89 | float channeloffset[10]; 90 | float channelscale[10]; 91 | }; 92 | 93 | struct iqmanim 94 | { 95 | unsigned int name; 96 | unsigned int first_frame, num_frames; 97 | float framerate; 98 | unsigned int flags; 99 | }; 100 | 101 | enum 102 | { 103 | IQM_LOOP = 1<<0 104 | }; 105 | 106 | struct iqmvertexarray 107 | { 108 | unsigned int type; 109 | unsigned int flags; 110 | unsigned int format; 111 | unsigned int size; 112 | unsigned int offset; 113 | }; 114 | 115 | struct iqmbounds 116 | { 117 | float bbmin[3], bbmax[3]; 118 | float xyradius, radius; 119 | }; 120 | 121 | struct iqmextension 122 | { 123 | unsigned int name; 124 | unsigned int num_data, ofs_data; 125 | unsigned int ofs_extensions; // pointer to next extension 126 | }; 127 | 128 | #endif 129 | 130 | -------------------------------------------------------------------------------- /lua-5.2.2/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for installing Lua 2 | # See doc/readme.html for installation and customization instructions. 3 | 4 | # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= 5 | 6 | # Your platform. See PLATS for possible values. 7 | PLAT= none 8 | 9 | # Where to install. The installation starts in the src and doc directories, 10 | # so take care if INSTALL_TOP is not an absolute path. See the local target. 11 | # You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with 12 | # LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h. 13 | INSTALL_TOP= /usr/local 14 | INSTALL_BIN= $(INSTALL_TOP)/bin 15 | INSTALL_INC= $(INSTALL_TOP)/include 16 | INSTALL_LIB= $(INSTALL_TOP)/lib 17 | INSTALL_MAN= $(INSTALL_TOP)/man/man1 18 | INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V 19 | INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V 20 | 21 | # How to install. If your install program does not support "-p", then 22 | # you may have to run ranlib on the installed liblua.a. 23 | INSTALL= install -p 24 | INSTALL_EXEC= $(INSTALL) -m 0755 25 | INSTALL_DATA= $(INSTALL) -m 0644 26 | # 27 | # If you don't have "install" you can use "cp" instead. 28 | # INSTALL= cp -p 29 | # INSTALL_EXEC= $(INSTALL) 30 | # INSTALL_DATA= $(INSTALL) 31 | 32 | # Other utilities. 33 | MKDIR= mkdir -p 34 | RM= rm -f 35 | 36 | # == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= 37 | 38 | # Convenience platforms targets. 39 | PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris 40 | 41 | # What to install. 42 | TO_BIN= lua luac 43 | TO_INC= lua.h luaconf.h lualib.h lauxlib.h lua.hpp 44 | TO_LIB= liblua.a 45 | TO_MAN= lua.1 luac.1 46 | 47 | # Lua version and release. 48 | V= 5.2 49 | R= $V.1 50 | 51 | # Targets start here. 52 | all: $(PLAT) 53 | 54 | $(PLATS) clean: 55 | cd src && $(MAKE) $@ 56 | 57 | test: dummy 58 | src/lua -v 59 | 60 | install: dummy 61 | cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD) 62 | cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN) 63 | cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC) 64 | cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB) 65 | cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN) 66 | 67 | uninstall: 68 | cd src && cd $(INSTALL_BIN) && $(RM) $(TO_BIN) 69 | cd src && cd $(INSTALL_INC) && $(RM) $(TO_INC) 70 | cd src && cd $(INSTALL_LIB) && $(RM) $(TO_LIB) 71 | cd doc && cd $(INSTALL_MAN) && $(RM) $(TO_MAN) 72 | 73 | local: 74 | $(MAKE) install INSTALL_TOP=../install 75 | 76 | none: 77 | @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" 78 | @echo " $(PLATS)" 79 | @echo "See doc/readme.html for complete instructions." 80 | 81 | # make may get confused with test/ and install/ 82 | dummy: 83 | 84 | # echo config parameters 85 | echo: 86 | @cd src && $(MAKE) -s echo 87 | @echo "PLAT= $(PLAT)" 88 | @echo "V= $V" 89 | @echo "R= $R" 90 | @echo "TO_BIN= $(TO_BIN)" 91 | @echo "TO_INC= $(TO_INC)" 92 | @echo "TO_LIB= $(TO_LIB)" 93 | @echo "TO_MAN= $(TO_MAN)" 94 | @echo "INSTALL_TOP= $(INSTALL_TOP)" 95 | @echo "INSTALL_BIN= $(INSTALL_BIN)" 96 | @echo "INSTALL_INC= $(INSTALL_INC)" 97 | @echo "INSTALL_LIB= $(INSTALL_LIB)" 98 | @echo "INSTALL_MAN= $(INSTALL_MAN)" 99 | @echo "INSTALL_LMOD= $(INSTALL_LMOD)" 100 | @echo "INSTALL_CMOD= $(INSTALL_CMOD)" 101 | @echo "INSTALL_EXEC= $(INSTALL_EXEC)" 102 | @echo "INSTALL_DATA= $(INSTALL_DATA)" 103 | 104 | # echo pkg-config data 105 | pc: 106 | @echo "version=$R" 107 | @echo "prefix=$(INSTALL_TOP)" 108 | @echo "libdir=$(INSTALL_LIB)" 109 | @echo "includedir=$(INSTALL_INC)" 110 | 111 | # list targets that do not create files (but not all makes understand .PHONY) 112 | .PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho 113 | 114 | # (end of Makefile) 115 | -------------------------------------------------------------------------------- /lua-5.2.2/README: -------------------------------------------------------------------------------- 1 | 2 | This is Lua 5.2.2, released on 21 Mar 2013. 3 | 4 | For installation instructions, license details, and 5 | further information about Lua, see doc/readme.html. 6 | 7 | -------------------------------------------------------------------------------- /lua-5.2.2/doc/logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccxvii/mio/22842b27aa852cb3a3a740e9d1a8fc669521b994/lua-5.2.2/doc/logo.gif -------------------------------------------------------------------------------- /lua-5.2.2/doc/lua.1: -------------------------------------------------------------------------------- 1 | .\" $Id: lua.man,v 1.13 2011/11/16 17:16:53 lhf Exp $ 2 | .TH LUA 1 "$Date: 2011/11/16 17:16:53 $" 3 | .SH NAME 4 | lua \- Lua interpreter 5 | .SH SYNOPSIS 6 | .B lua 7 | [ 8 | .I options 9 | ] 10 | [ 11 | .I script 12 | [ 13 | .I args 14 | ] 15 | ] 16 | .SH DESCRIPTION 17 | .B lua 18 | is the standalone Lua interpreter. 19 | It loads and executes Lua programs, 20 | either in textual source form or 21 | in precompiled binary form. 22 | (Precompiled binaries are output by 23 | .BR luac , 24 | the Lua compiler.) 25 | .B lua 26 | can be used as a batch interpreter and also interactively. 27 | .LP 28 | The given 29 | .I options 30 | are handled in order and then 31 | the Lua program in file 32 | .I script 33 | is loaded and executed. 34 | The given 35 | .I args 36 | are available to 37 | .I script 38 | as strings in a global table named 39 | .BR arg . 40 | If no options or arguments are given, 41 | then 42 | .B "\-v \-i" 43 | is assumed when the standard input is a terminal; 44 | otherwise, 45 | .B "\-" 46 | is assumed. 47 | .LP 48 | In interactive mode, 49 | .B lua 50 | prompts the user, 51 | reads lines from the standard input, 52 | and executes them as they are read. 53 | If a line does not contain a complete statement, 54 | then a secondary prompt is displayed and 55 | lines are read until a complete statement is formed or 56 | a syntax error is found. 57 | If a line starts with 58 | .BR '=' , 59 | then 60 | .B lua 61 | evaluates and displays 62 | the values of the expressions in the remainder of the line. 63 | .LP 64 | At the very start, 65 | before even handling the command line, 66 | .B lua 67 | checks the contents of the environment variables 68 | .B LUA_INIT_5_2 69 | or 70 | .BR LUA_INIT , 71 | in that order. 72 | If the contents is of the form 73 | .RI '@ filename ', 74 | then 75 | .I filename 76 | is executed. 77 | Otherwise, the string is assumed to be a Lua statement and is executed. 78 | .SH OPTIONS 79 | .TP 80 | .BI \-e " stat" 81 | execute statement 82 | .IR stat . 83 | .TP 84 | .B \-i 85 | enter interactive mode after executing 86 | .IR script . 87 | .TP 88 | .BI \-l " name" 89 | execute the equivalent of 90 | .IB name =require(' name ') 91 | before executing 92 | .IR script . 93 | .TP 94 | .B \-v 95 | show version information. 96 | .TP 97 | .B \-E 98 | ignore environment variables. 99 | .TP 100 | .B \-\- 101 | stop handling options. 102 | .TP 103 | .B \- 104 | stop handling options and execute the standard input as a file. 105 | .SH "SEE ALSO" 106 | .BR luac (1) 107 | .br 108 | The documentation at lua.org, 109 | especially section 7 of the reference manual. 110 | .SH DIAGNOSTICS 111 | Error messages should be self explanatory. 112 | .SH AUTHORS 113 | R. Ierusalimschy, 114 | L. H. de Figueiredo, 115 | W. Celes 116 | .\" EOF 117 | -------------------------------------------------------------------------------- /lua-5.2.2/doc/lua.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #000000 ; 3 | background-color: #FFFFFF ; 4 | font-family: Helvetica, Arial, sans-serif ; 5 | text-align: justify ; 6 | margin-right: 30px ; 7 | margin-left: 30px ; 8 | } 9 | 10 | h1, h2, h3, h4 { 11 | font-family: Verdana, Geneva, sans-serif ; 12 | font-weight: normal ; 13 | font-style: italic ; 14 | } 15 | 16 | h2 { 17 | padding-top: 0.4em ; 18 | padding-bottom: 0.4em ; 19 | padding-left: 1em ; 20 | padding-right: 1em ; 21 | background-color: #E0E0FF ; 22 | border-radius: 8px ; 23 | } 24 | 25 | h3 { 26 | padding-left: 0.5em ; 27 | border-left: solid #E0E0FF 1em ; 28 | } 29 | 30 | table h3 { 31 | padding-left: 0px ; 32 | border-left: none ; 33 | } 34 | 35 | a:link { 36 | color: #000080 ; 37 | background-color: inherit ; 38 | text-decoration: none ; 39 | } 40 | 41 | a:visited { 42 | background-color: inherit ; 43 | text-decoration: none ; 44 | } 45 | 46 | a:link:hover, a:visited:hover { 47 | color: #000080 ; 48 | background-color: #E0E0FF ; 49 | } 50 | 51 | a:link:active, a:visited:active { 52 | color: #FF0000 ; 53 | } 54 | 55 | hr { 56 | border: 0 ; 57 | height: 1px ; 58 | color: #a0a0a0 ; 59 | background-color: #a0a0a0 ; 60 | } 61 | 62 | :target { 63 | background-color: #F8F8F8 ; 64 | padding: 8px ; 65 | border: solid #a0a0a0 2px ; 66 | } 67 | 68 | .footer { 69 | color: gray ; 70 | font-size: small ; 71 | } 72 | 73 | input[type=text] { 74 | border: solid #a0a0a0 2px ; 75 | border-radius: 2em ; 76 | -moz-border-radius: 2em ; 77 | background-image: url('images/search.png') ; 78 | background-repeat: no-repeat; 79 | background-position: 4px center ; 80 | padding-left: 20px ; 81 | height: 2em ; 82 | } 83 | 84 | -------------------------------------------------------------------------------- /lua-5.2.2/doc/luac.1: -------------------------------------------------------------------------------- 1 | .\" $Id: luac.man,v 1.29 2011/11/16 13:53:40 lhf Exp $ 2 | .TH LUAC 1 "$Date: 2011/11/16 13:53:40 $" 3 | .SH NAME 4 | luac \- Lua compiler 5 | .SH SYNOPSIS 6 | .B luac 7 | [ 8 | .I options 9 | ] [ 10 | .I filenames 11 | ] 12 | .SH DESCRIPTION 13 | .B luac 14 | is the Lua compiler. 15 | It translates programs written in the Lua programming language 16 | into binary files containing precompiled chunks 17 | that can be later loaded and executed. 18 | .LP 19 | The main advantages of precompiling chunks are: 20 | faster loading, 21 | protecting source code from accidental user changes, 22 | and 23 | off-line syntax checking. 24 | Precompiling does not imply faster execution 25 | because in Lua chunks are always compiled into bytecodes before being executed. 26 | .B luac 27 | simply allows those bytecodes to be saved in a file for later execution. 28 | Precompiled chunks are not necessarily smaller than the corresponding source. 29 | The main goal in precompiling is faster loading. 30 | .LP 31 | In the command line, 32 | you can mix 33 | text files containing Lua source and 34 | binary files containing precompiled chunks. 35 | .B luac 36 | produces a single output file containing the combined bytecodes 37 | for all files given. 38 | Executing the combined file is equivalent to executing the given files. 39 | By default, 40 | the output file is named 41 | .BR luac.out , 42 | but you can change this with the 43 | .B \-o 44 | option. 45 | .LP 46 | Precompiled chunks are 47 | .I not 48 | portable across different architectures. 49 | Moreover, 50 | the internal format of precompiled chunks 51 | is likely to change when a new version of Lua is released. 52 | Make sure you save the source files of all Lua programs that you precompile. 53 | .LP 54 | .SH OPTIONS 55 | .TP 56 | .B \-l 57 | produce a listing of the compiled bytecode for Lua's virtual machine. 58 | Listing bytecodes is useful to learn about Lua's virtual machine. 59 | If no files are given, then 60 | .B luac 61 | loads 62 | .B luac.out 63 | and lists its contents. 64 | Use 65 | .B \-l \-l 66 | for a full listing. 67 | .TP 68 | .BI \-o " file" 69 | output to 70 | .IR file , 71 | instead of the default 72 | .BR luac.out . 73 | (You can use 74 | .B "'\-'" 75 | for standard output, 76 | but not on platforms that open standard output in text mode.) 77 | The output file may be one of the given files because 78 | all files are loaded before the output file is written. 79 | Be careful not to overwrite precious files. 80 | .TP 81 | .B \-p 82 | load files but do not generate any output file. 83 | Used mainly for syntax checking and for testing precompiled chunks: 84 | corrupted files will probably generate errors when loaded. 85 | If no files are given, then 86 | .B luac 87 | loads 88 | .B luac.out 89 | and tests its contents. 90 | No messages are displayed if the file loads without errors. 91 | .TP 92 | .B \-s 93 | strip debug information before writing the output file. 94 | This saves some space in very large chunks, 95 | but if errors occur when running a stripped chunk, 96 | then the error messages may not contain the full information they usually do. 97 | In particular, 98 | line numbers and names of local variables are lost. 99 | .TP 100 | .B \-v 101 | show version information. 102 | .TP 103 | .B \-\- 104 | stop handling options. 105 | .TP 106 | .B \- 107 | stop handling options and process standard input. 108 | .SH "SEE ALSO" 109 | .BR lua (1) 110 | .br 111 | The documentation at lua.org. 112 | .SH DIAGNOSTICS 113 | Error messages should be self explanatory. 114 | .SH AUTHORS 115 | R. Ierusalimschy, 116 | L. H. de Figueiredo, 117 | W. Celes 118 | .\" EOF 119 | -------------------------------------------------------------------------------- /lua-5.2.2/doc/manual.css: -------------------------------------------------------------------------------- 1 | h3 code { 2 | font-family: inherit ; 3 | font-size: inherit ; 4 | } 5 | 6 | pre, code { 7 | font-size: 12pt ; 8 | } 9 | 10 | span.apii { 11 | float: right ; 12 | font-family: inherit ; 13 | font-style: normal ; 14 | font-size: small ; 15 | color: gray ; 16 | } 17 | 18 | p+h1, ul+h1 { 19 | padding-top: 0.4em ; 20 | padding-bottom: 0.4em ; 21 | padding-left: 24px ; 22 | margin-left: -24px ; 23 | background-color: #E0E0FF ; 24 | border-radius: 8px ; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /lua-5.2.2/doc/osi-certified-72x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccxvii/mio/22842b27aa852cb3a3a740e9d1a8fc669521b994/lua-5.2.2/doc/osi-certified-72x60.png -------------------------------------------------------------------------------- /lua-5.2.2/src/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for building Lua 2 | # See ../doc/readme.html for installation and customization instructions. 3 | 4 | # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= 5 | 6 | # Your platform. See PLATS for possible values. 7 | PLAT= none 8 | 9 | CC= gcc 10 | CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS) 11 | LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) 12 | LIBS= -lm $(SYSLIBS) $(MYLIBS) 13 | 14 | AR= ar rcu 15 | RANLIB= ranlib 16 | RM= rm -f 17 | 18 | SYSCFLAGS= 19 | SYSLDFLAGS= 20 | SYSLIBS= 21 | 22 | MYCFLAGS= 23 | MYLDFLAGS= 24 | MYLIBS= 25 | MYOBJS= 26 | 27 | # == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= 28 | 29 | PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris 30 | 31 | LUA_A= liblua.a 32 | CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ 33 | lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ 34 | ltm.o lundump.o lvm.o lzio.o 35 | LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \ 36 | lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o 37 | BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) 38 | 39 | LUA_T= lua 40 | LUA_O= lua.o 41 | 42 | LUAC_T= luac 43 | LUAC_O= luac.o 44 | 45 | ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O) 46 | ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) 47 | ALL_A= $(LUA_A) 48 | 49 | # Targets start here. 50 | default: $(PLAT) 51 | 52 | all: $(ALL_T) 53 | 54 | o: $(ALL_O) 55 | 56 | a: $(ALL_A) 57 | 58 | $(LUA_A): $(BASE_O) 59 | $(AR) $@ $(BASE_O) 60 | $(RANLIB) $@ 61 | 62 | $(LUA_T): $(LUA_O) $(LUA_A) 63 | $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) 64 | 65 | $(LUAC_T): $(LUAC_O) $(LUA_A) 66 | $(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) 67 | 68 | clean: 69 | $(RM) $(ALL_T) $(ALL_O) 70 | 71 | depend: 72 | @$(CC) $(CFLAGS) -MM l*.c 73 | 74 | echo: 75 | @echo "PLAT= $(PLAT)" 76 | @echo "CC= $(CC)" 77 | @echo "CFLAGS= $(CFLAGS)" 78 | @echo "LDFLAGS= $(SYSLDFLAGS)" 79 | @echo "LIBS= $(LIBS)" 80 | @echo "AR= $(AR)" 81 | @echo "RANLIB= $(RANLIB)" 82 | @echo "RM= $(RM)" 83 | 84 | # Convenience targets for popular platforms 85 | ALL= all 86 | 87 | none: 88 | @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" 89 | @echo " $(PLATS)" 90 | 91 | aix: 92 | $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" 93 | 94 | ansi: 95 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI" 96 | 97 | bsd: 98 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E" 99 | 100 | freebsd: 101 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline" 102 | 103 | generic: $(ALL) 104 | 105 | linux: 106 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline" 107 | 108 | macosx: 109 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" 110 | 111 | mingw: 112 | $(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \ 113 | "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ 114 | "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe 115 | $(MAKE) "LUAC_T=luac.exe" luac.exe 116 | 117 | posix: 118 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX" 119 | 120 | solaris: 121 | $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" 122 | 123 | # list targets that do not create files (but not all makes understand .PHONY) 124 | .PHONY: all $(PLATS) default o a clean depend echo none 125 | 126 | # DO NOT DELETE 127 | 128 | lapi.o: lapi.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ 129 | lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h \ 130 | lvm.h 131 | lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h 132 | lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h 133 | lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h 134 | lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ 135 | lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ 136 | lstring.h ltable.h lvm.h 137 | lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h 138 | lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h 139 | ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h 140 | ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ 141 | ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h \ 142 | lfunc.h lstring.h lgc.h ltable.h lvm.h 143 | ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ 144 | lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \ 145 | lstring.h ltable.h lundump.h lvm.h 146 | ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ 147 | lzio.h lmem.h lundump.h 148 | lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \ 149 | lstate.h ltm.h lzio.h lmem.h 150 | lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ 151 | lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h 152 | linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h 153 | liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h 154 | llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \ 155 | lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h 156 | lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h 157 | lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ 158 | ltm.h lzio.h lmem.h ldo.h lgc.h 159 | loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h 160 | lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h \ 161 | lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h 162 | lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h 163 | loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h 164 | lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ 165 | lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h \ 166 | lstring.h lgc.h ltable.h 167 | lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ 168 | ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \ 169 | ltable.h 170 | lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ 171 | ltm.h lzio.h lstring.h lgc.h 172 | lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h 173 | ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ 174 | ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h 175 | ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h 176 | ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ 177 | lmem.h lstring.h lgc.h ltable.h 178 | lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h 179 | luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \ 180 | ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h 181 | lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ 182 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h 183 | lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ 184 | lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h 185 | lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ 186 | lzio.h 187 | 188 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h,v 2.7 2009/11/27 15:37:59 roberto Exp $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lstate.h" 13 | 14 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ 15 | "stack overflow");} 16 | 17 | #define adjustresults(L,nres) \ 18 | { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } 19 | 20 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ 21 | "not enough elements in the stack") 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lauxlib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lauxlib.h,v 1.120 2011/11/29 15:55:08 roberto Exp $ 3 | ** Auxiliary functions for building Lua libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lauxlib_h 9 | #define lauxlib_h 10 | 11 | 12 | #include 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | 18 | 19 | /* extra error code for `luaL_load' */ 20 | #define LUA_ERRFILE (LUA_ERRERR+1) 21 | 22 | 23 | typedef struct luaL_Reg { 24 | const char *name; 25 | lua_CFunction func; 26 | } luaL_Reg; 27 | 28 | 29 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); 30 | #define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) 31 | 32 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); 33 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); 34 | LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); 35 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); 36 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, 37 | size_t *l); 38 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, 39 | const char *def, size_t *l); 40 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); 41 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); 42 | 43 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); 44 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, 45 | lua_Integer def); 46 | LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg); 47 | LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg, 48 | lua_Unsigned def); 49 | 50 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); 51 | LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); 52 | LUALIB_API void (luaL_checkany) (lua_State *L, int narg); 53 | 54 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); 55 | LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); 56 | LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); 57 | LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); 58 | 59 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); 60 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); 61 | 62 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, 63 | const char *const lst[]); 64 | 65 | LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); 66 | LUALIB_API int (luaL_execresult) (lua_State *L, int stat); 67 | 68 | /* pre-defined references */ 69 | #define LUA_NOREF (-2) 70 | #define LUA_REFNIL (-1) 71 | 72 | LUALIB_API int (luaL_ref) (lua_State *L, int t); 73 | LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); 74 | 75 | LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, 76 | const char *mode); 77 | 78 | #define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) 79 | 80 | LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, 81 | const char *name, const char *mode); 82 | LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); 83 | 84 | LUALIB_API lua_State *(luaL_newstate) (void); 85 | 86 | LUALIB_API int (luaL_len) (lua_State *L, int idx); 87 | 88 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, 89 | const char *r); 90 | 91 | LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); 92 | 93 | LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); 94 | 95 | LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, 96 | const char *msg, int level); 97 | 98 | LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, 99 | lua_CFunction openf, int glb); 100 | 101 | /* 102 | ** =============================================================== 103 | ** some useful macros 104 | ** =============================================================== 105 | */ 106 | 107 | 108 | #define luaL_newlibtable(L,l) \ 109 | lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) 110 | 111 | #define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) 112 | 113 | #define luaL_argcheck(L, cond,numarg,extramsg) \ 114 | ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) 115 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) 116 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) 117 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) 118 | #define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) 119 | #define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) 120 | #define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) 121 | 122 | #define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) 123 | 124 | #define luaL_dofile(L, fn) \ 125 | (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) 126 | 127 | #define luaL_dostring(L, s) \ 128 | (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) 129 | 130 | #define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) 131 | 132 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) 133 | 134 | #define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) 135 | 136 | 137 | /* 138 | ** {====================================================== 139 | ** Generic Buffer manipulation 140 | ** ======================================================= 141 | */ 142 | 143 | typedef struct luaL_Buffer { 144 | char *b; /* buffer address */ 145 | size_t size; /* buffer size */ 146 | size_t n; /* number of characters in buffer */ 147 | lua_State *L; 148 | char initb[LUAL_BUFFERSIZE]; /* initial buffer */ 149 | } luaL_Buffer; 150 | 151 | 152 | #define luaL_addchar(B,c) \ 153 | ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ 154 | ((B)->b[(B)->n++] = (c))) 155 | 156 | #define luaL_addsize(B,s) ((B)->n += (s)) 157 | 158 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); 159 | LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); 160 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); 161 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); 162 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); 163 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); 164 | LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); 165 | LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); 166 | 167 | #define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) 168 | 169 | /* }====================================================== */ 170 | 171 | 172 | 173 | /* 174 | ** {====================================================== 175 | ** File handles for IO library 176 | ** ======================================================= 177 | */ 178 | 179 | /* 180 | ** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and 181 | ** initial structure 'luaL_Stream' (it may contain other fields 182 | ** after that initial structure). 183 | */ 184 | 185 | #define LUA_FILEHANDLE "FILE*" 186 | 187 | 188 | typedef struct luaL_Stream { 189 | FILE *f; /* stream (NULL for incompletely created streams) */ 190 | lua_CFunction closef; /* to close stream (NULL for closed streams) */ 191 | } luaL_Stream; 192 | 193 | /* }====================================================== */ 194 | 195 | 196 | 197 | /* compatibility with old module system */ 198 | #if defined(LUA_COMPAT_MODULE) 199 | 200 | LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, 201 | int sizehint); 202 | LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, 203 | const luaL_Reg *l, int nup); 204 | 205 | #define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) 206 | 207 | #endif 208 | 209 | 210 | #endif 211 | 212 | 213 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lbitlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lbitlib.c,v 1.18 2013/03/19 13:19:12 roberto Exp $ 3 | ** Standard library for bitwise operations 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lbitlib_c 8 | #define LUA_LIB 9 | 10 | #include "lua.h" 11 | 12 | #include "lauxlib.h" 13 | #include "lualib.h" 14 | 15 | 16 | /* number of bits to consider in a number */ 17 | #if !defined(LUA_NBITS) 18 | #define LUA_NBITS 32 19 | #endif 20 | 21 | 22 | #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) 23 | 24 | /* macro to trim extra bits */ 25 | #define trim(x) ((x) & ALLONES) 26 | 27 | 28 | /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ 29 | #define mask(n) (~((ALLONES << 1) << ((n) - 1))) 30 | 31 | 32 | typedef lua_Unsigned b_uint; 33 | 34 | 35 | 36 | static b_uint andaux (lua_State *L) { 37 | int i, n = lua_gettop(L); 38 | b_uint r = ~(b_uint)0; 39 | for (i = 1; i <= n; i++) 40 | r &= luaL_checkunsigned(L, i); 41 | return trim(r); 42 | } 43 | 44 | 45 | static int b_and (lua_State *L) { 46 | b_uint r = andaux(L); 47 | lua_pushunsigned(L, r); 48 | return 1; 49 | } 50 | 51 | 52 | static int b_test (lua_State *L) { 53 | b_uint r = andaux(L); 54 | lua_pushboolean(L, r != 0); 55 | return 1; 56 | } 57 | 58 | 59 | static int b_or (lua_State *L) { 60 | int i, n = lua_gettop(L); 61 | b_uint r = 0; 62 | for (i = 1; i <= n; i++) 63 | r |= luaL_checkunsigned(L, i); 64 | lua_pushunsigned(L, trim(r)); 65 | return 1; 66 | } 67 | 68 | 69 | static int b_xor (lua_State *L) { 70 | int i, n = lua_gettop(L); 71 | b_uint r = 0; 72 | for (i = 1; i <= n; i++) 73 | r ^= luaL_checkunsigned(L, i); 74 | lua_pushunsigned(L, trim(r)); 75 | return 1; 76 | } 77 | 78 | 79 | static int b_not (lua_State *L) { 80 | b_uint r = ~luaL_checkunsigned(L, 1); 81 | lua_pushunsigned(L, trim(r)); 82 | return 1; 83 | } 84 | 85 | 86 | static int b_shift (lua_State *L, b_uint r, int i) { 87 | if (i < 0) { /* shift right? */ 88 | i = -i; 89 | r = trim(r); 90 | if (i >= LUA_NBITS) r = 0; 91 | else r >>= i; 92 | } 93 | else { /* shift left */ 94 | if (i >= LUA_NBITS) r = 0; 95 | else r <<= i; 96 | r = trim(r); 97 | } 98 | lua_pushunsigned(L, r); 99 | return 1; 100 | } 101 | 102 | 103 | static int b_lshift (lua_State *L) { 104 | return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2)); 105 | } 106 | 107 | 108 | static int b_rshift (lua_State *L) { 109 | return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2)); 110 | } 111 | 112 | 113 | static int b_arshift (lua_State *L) { 114 | b_uint r = luaL_checkunsigned(L, 1); 115 | int i = luaL_checkint(L, 2); 116 | if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1)))) 117 | return b_shift(L, r, -i); 118 | else { /* arithmetic shift for 'negative' number */ 119 | if (i >= LUA_NBITS) r = ALLONES; 120 | else 121 | r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ 122 | lua_pushunsigned(L, r); 123 | return 1; 124 | } 125 | } 126 | 127 | 128 | static int b_rot (lua_State *L, int i) { 129 | b_uint r = luaL_checkunsigned(L, 1); 130 | i &= (LUA_NBITS - 1); /* i = i % NBITS */ 131 | r = trim(r); 132 | r = (r << i) | (r >> (LUA_NBITS - i)); 133 | lua_pushunsigned(L, trim(r)); 134 | return 1; 135 | } 136 | 137 | 138 | static int b_lrot (lua_State *L) { 139 | return b_rot(L, luaL_checkint(L, 2)); 140 | } 141 | 142 | 143 | static int b_rrot (lua_State *L) { 144 | return b_rot(L, -luaL_checkint(L, 2)); 145 | } 146 | 147 | 148 | /* 149 | ** get field and width arguments for field-manipulation functions, 150 | ** checking whether they are valid. 151 | ** ('luaL_error' called without 'return' to avoid later warnings about 152 | ** 'width' being used uninitialized.) 153 | */ 154 | static int fieldargs (lua_State *L, int farg, int *width) { 155 | int f = luaL_checkint(L, farg); 156 | int w = luaL_optint(L, farg + 1, 1); 157 | luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); 158 | luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); 159 | if (f + w > LUA_NBITS) 160 | luaL_error(L, "trying to access non-existent bits"); 161 | *width = w; 162 | return f; 163 | } 164 | 165 | 166 | static int b_extract (lua_State *L) { 167 | int w; 168 | b_uint r = luaL_checkunsigned(L, 1); 169 | int f = fieldargs(L, 2, &w); 170 | r = (r >> f) & mask(w); 171 | lua_pushunsigned(L, r); 172 | return 1; 173 | } 174 | 175 | 176 | static int b_replace (lua_State *L) { 177 | int w; 178 | b_uint r = luaL_checkunsigned(L, 1); 179 | b_uint v = luaL_checkunsigned(L, 2); 180 | int f = fieldargs(L, 3, &w); 181 | int m = mask(w); 182 | v &= m; /* erase bits outside given width */ 183 | r = (r & ~(m << f)) | (v << f); 184 | lua_pushunsigned(L, r); 185 | return 1; 186 | } 187 | 188 | 189 | static const luaL_Reg bitlib[] = { 190 | {"arshift", b_arshift}, 191 | {"band", b_and}, 192 | {"bnot", b_not}, 193 | {"bor", b_or}, 194 | {"bxor", b_xor}, 195 | {"btest", b_test}, 196 | {"extract", b_extract}, 197 | {"lrotate", b_lrot}, 198 | {"lshift", b_lshift}, 199 | {"replace", b_replace}, 200 | {"rrotate", b_rrot}, 201 | {"rshift", b_rshift}, 202 | {NULL, NULL} 203 | }; 204 | 205 | 206 | 207 | LUAMOD_API int luaopen_bit32 (lua_State *L) { 208 | luaL_newlib(L, bitlib); 209 | return 1; 210 | } 211 | 212 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcode.h,v 1.58 2011/08/30 16:26:41 roberto Exp $ 3 | ** Code generator for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lcode_h 8 | #define lcode_h 9 | 10 | #include "llex.h" 11 | #include "lobject.h" 12 | #include "lopcodes.h" 13 | #include "lparser.h" 14 | 15 | 16 | /* 17 | ** Marks the end of a patch list. It is an invalid value both as an absolute 18 | ** address, and as a list link (would link an element to itself). 19 | */ 20 | #define NO_JUMP (-1) 21 | 22 | 23 | /* 24 | ** grep "ORDER OPR" if you change these enums (ORDER OP) 25 | */ 26 | typedef enum BinOpr { 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, 28 | OPR_CONCAT, 29 | OPR_EQ, OPR_LT, OPR_LE, 30 | OPR_NE, OPR_GT, OPR_GE, 31 | OPR_AND, OPR_OR, 32 | OPR_NOBINOPR 33 | } BinOpr; 34 | 35 | 36 | typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 37 | 38 | 39 | #define getcode(fs,e) ((fs)->f->code[(e)->u.info]) 40 | 41 | #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) 42 | 43 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) 44 | 45 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) 46 | 47 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 48 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); 49 | LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k); 50 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 51 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 52 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 53 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 54 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); 55 | LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); 56 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 57 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 58 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); 59 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 60 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 61 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); 62 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 63 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 64 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 65 | LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); 66 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 67 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 68 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 69 | LUAI_FUNC int luaK_jump (FuncState *fs); 70 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 71 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 72 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 73 | LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); 74 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 75 | LUAI_FUNC int luaK_getlabel (FuncState *fs); 76 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); 77 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 78 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, 79 | expdesc *v2, int line); 80 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 81 | 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lcorolib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcorolib.c,v 1.5 2013/02/21 13:44:53 roberto Exp $ 3 | ** Coroutine Library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | 11 | #define lcorolib_c 12 | #define LUA_LIB 13 | 14 | #include "lua.h" 15 | 16 | #include "lauxlib.h" 17 | #include "lualib.h" 18 | 19 | 20 | static int auxresume (lua_State *L, lua_State *co, int narg) { 21 | int status; 22 | if (!lua_checkstack(co, narg)) { 23 | lua_pushliteral(L, "too many arguments to resume"); 24 | return -1; /* error flag */ 25 | } 26 | if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) { 27 | lua_pushliteral(L, "cannot resume dead coroutine"); 28 | return -1; /* error flag */ 29 | } 30 | lua_xmove(L, co, narg); 31 | status = lua_resume(co, L, narg); 32 | if (status == LUA_OK || status == LUA_YIELD) { 33 | int nres = lua_gettop(co); 34 | if (!lua_checkstack(L, nres + 1)) { 35 | lua_pop(co, nres); /* remove results anyway */ 36 | lua_pushliteral(L, "too many results to resume"); 37 | return -1; /* error flag */ 38 | } 39 | lua_xmove(co, L, nres); /* move yielded values */ 40 | return nres; 41 | } 42 | else { 43 | lua_xmove(co, L, 1); /* move error message */ 44 | return -1; /* error flag */ 45 | } 46 | } 47 | 48 | 49 | static int luaB_coresume (lua_State *L) { 50 | lua_State *co = lua_tothread(L, 1); 51 | int r; 52 | luaL_argcheck(L, co, 1, "coroutine expected"); 53 | r = auxresume(L, co, lua_gettop(L) - 1); 54 | if (r < 0) { 55 | lua_pushboolean(L, 0); 56 | lua_insert(L, -2); 57 | return 2; /* return false + error message */ 58 | } 59 | else { 60 | lua_pushboolean(L, 1); 61 | lua_insert(L, -(r + 1)); 62 | return r + 1; /* return true + `resume' returns */ 63 | } 64 | } 65 | 66 | 67 | static int luaB_auxwrap (lua_State *L) { 68 | lua_State *co = lua_tothread(L, lua_upvalueindex(1)); 69 | int r = auxresume(L, co, lua_gettop(L)); 70 | if (r < 0) { 71 | if (lua_isstring(L, -1)) { /* error object is a string? */ 72 | luaL_where(L, 1); /* add extra info */ 73 | lua_insert(L, -2); 74 | lua_concat(L, 2); 75 | } 76 | return lua_error(L); /* propagate error */ 77 | } 78 | return r; 79 | } 80 | 81 | 82 | static int luaB_cocreate (lua_State *L) { 83 | lua_State *NL; 84 | luaL_checktype(L, 1, LUA_TFUNCTION); 85 | NL = lua_newthread(L); 86 | lua_pushvalue(L, 1); /* move function to top */ 87 | lua_xmove(L, NL, 1); /* move function from L to NL */ 88 | return 1; 89 | } 90 | 91 | 92 | static int luaB_cowrap (lua_State *L) { 93 | luaB_cocreate(L); 94 | lua_pushcclosure(L, luaB_auxwrap, 1); 95 | return 1; 96 | } 97 | 98 | 99 | static int luaB_yield (lua_State *L) { 100 | return lua_yield(L, lua_gettop(L)); 101 | } 102 | 103 | 104 | static int luaB_costatus (lua_State *L) { 105 | lua_State *co = lua_tothread(L, 1); 106 | luaL_argcheck(L, co, 1, "coroutine expected"); 107 | if (L == co) lua_pushliteral(L, "running"); 108 | else { 109 | switch (lua_status(co)) { 110 | case LUA_YIELD: 111 | lua_pushliteral(L, "suspended"); 112 | break; 113 | case LUA_OK: { 114 | lua_Debug ar; 115 | if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ 116 | lua_pushliteral(L, "normal"); /* it is running */ 117 | else if (lua_gettop(co) == 0) 118 | lua_pushliteral(L, "dead"); 119 | else 120 | lua_pushliteral(L, "suspended"); /* initial state */ 121 | break; 122 | } 123 | default: /* some error occurred */ 124 | lua_pushliteral(L, "dead"); 125 | break; 126 | } 127 | } 128 | return 1; 129 | } 130 | 131 | 132 | static int luaB_corunning (lua_State *L) { 133 | int ismain = lua_pushthread(L); 134 | lua_pushboolean(L, ismain); 135 | return 2; 136 | } 137 | 138 | 139 | static const luaL_Reg co_funcs[] = { 140 | {"create", luaB_cocreate}, 141 | {"resume", luaB_coresume}, 142 | {"running", luaB_corunning}, 143 | {"status", luaB_costatus}, 144 | {"wrap", luaB_cowrap}, 145 | {"yield", luaB_yield}, 146 | {NULL, NULL} 147 | }; 148 | 149 | 150 | 151 | LUAMOD_API int luaopen_coroutine (lua_State *L) { 152 | luaL_newlib(L, co_funcs); 153 | return 1; 154 | } 155 | 156 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.c,v 1.11 2011/10/03 16:19:23 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lctype_c 8 | #define LUA_CORE 9 | 10 | #include "lctype.h" 11 | 12 | #if !LUA_USE_CTYPE /* { */ 13 | 14 | #include 15 | 16 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { 17 | 0x00, /* EOZ */ 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ 19 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ 23 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 24 | 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ 25 | 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 26 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ 27 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 28 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ 29 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 30 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ 31 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 32 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ 33 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 34 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ 35 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | }; 51 | 52 | #endif /* } */ 53 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lctype_h 8 | #define lctype_h 9 | 10 | #include "lua.h" 11 | 12 | 13 | /* 14 | ** WARNING: the functions defined here do not necessarily correspond 15 | ** to the similar functions in the standard C ctype.h. They are 16 | ** optimized for the specific needs of Lua 17 | */ 18 | 19 | #if !defined(LUA_USE_CTYPE) 20 | 21 | #if 'A' == 65 && '0' == 48 22 | /* ASCII case: can use its own tables; faster and fixed */ 23 | #define LUA_USE_CTYPE 0 24 | #else 25 | /* must use standard C ctype */ 26 | #define LUA_USE_CTYPE 1 27 | #endif 28 | 29 | #endif 30 | 31 | 32 | #if !LUA_USE_CTYPE /* { */ 33 | 34 | #include 35 | 36 | #include "llimits.h" 37 | 38 | 39 | #define ALPHABIT 0 40 | #define DIGITBIT 1 41 | #define PRINTBIT 2 42 | #define SPACEBIT 3 43 | #define XDIGITBIT 4 44 | 45 | 46 | #define MASK(B) (1 << (B)) 47 | 48 | 49 | /* 50 | ** add 1 to char to allow index -1 (EOZ) 51 | */ 52 | #define testprop(c,p) (luai_ctype_[(c)+1] & (p)) 53 | 54 | /* 55 | ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' 56 | */ 57 | #define lislalpha(c) testprop(c, MASK(ALPHABIT)) 58 | #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) 59 | #define lisdigit(c) testprop(c, MASK(DIGITBIT)) 60 | #define lisspace(c) testprop(c, MASK(SPACEBIT)) 61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) 62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) 63 | 64 | /* 65 | ** this 'ltolower' only works for alphabetic characters 66 | */ 67 | #define ltolower(c) ((c) | ('A' ^ 'a')) 68 | 69 | 70 | /* two more entries for 0 and -1 (EOZ) */ 71 | LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; 72 | 73 | 74 | #else /* }{ */ 75 | 76 | /* 77 | ** use standard C ctypes 78 | */ 79 | 80 | #include 81 | 82 | 83 | #define lislalpha(c) (isalpha(c) || (c) == '_') 84 | #define lislalnum(c) (isalnum(c) || (c) == '_') 85 | #define lisdigit(c) (isdigit(c)) 86 | #define lisspace(c) (isspace(c)) 87 | #define lisprint(c) (isprint(c)) 88 | #define lisxdigit(c) (isxdigit(c)) 89 | 90 | #define ltolower(c) (tolower(c)) 91 | 92 | #endif /* } */ 93 | 94 | #endif 95 | 96 | -------------------------------------------------------------------------------- /lua-5.2.2/src/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h,v 2.7 2011/10/07 20:45:19 roberto Exp $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) 15 | 16 | #define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) 17 | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) 19 | 20 | /* Active Lua function (given call info) */ 21 | #define ci_func(ci) (clLvalue((ci)->func)) 22 | 23 | 24 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 25 | const char *opname); 26 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2); 27 | LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1, 28 | const TValue *p2); 29 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 30 | const TValue *p2); 31 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 32 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /lua-5.2.2/src/ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h,v 2.20 2011/11/29 15:55:08 roberto Exp $ 3 | ** Stack and Call structure of Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldo_h 8 | #define ldo_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | #include "lzio.h" 14 | 15 | 16 | #define luaD_checkstack(L,n) if (L->stack_last - L->top <= (n)) \ 17 | luaD_growstack(L, n); else condmovestack(L); 18 | 19 | 20 | #define incr_top(L) {L->top++; luaD_checkstack(L,0);} 21 | 22 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) 23 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 24 | 25 | 26 | /* type of protected functions, to be ran by `runprotected' */ 27 | typedef void (*Pfunc) (lua_State *L, void *ud); 28 | 29 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 30 | const char *mode); 31 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); 32 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); 33 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults, 34 | int allowyield); 35 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 36 | ptrdiff_t oldtop, ptrdiff_t ef); 37 | LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); 38 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); 39 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); 40 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); 41 | 42 | LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); 43 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 44 | 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /lua-5.2.2/src/ldump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldump.c,v 2.17 2012/01/23 23:02:10 roberto Exp $ 3 | ** save precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | 9 | #define ldump_c 10 | #define LUA_CORE 11 | 12 | #include "lua.h" 13 | 14 | #include "lobject.h" 15 | #include "lstate.h" 16 | #include "lundump.h" 17 | 18 | typedef struct { 19 | lua_State* L; 20 | lua_Writer writer; 21 | void* data; 22 | int strip; 23 | int status; 24 | } DumpState; 25 | 26 | #define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) 27 | #define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) 28 | 29 | static void DumpBlock(const void* b, size_t size, DumpState* D) 30 | { 31 | if (D->status==0) 32 | { 33 | lua_unlock(D->L); 34 | D->status=(*D->writer)(D->L,b,size,D->data); 35 | lua_lock(D->L); 36 | } 37 | } 38 | 39 | static void DumpChar(int y, DumpState* D) 40 | { 41 | char x=(char)y; 42 | DumpVar(x,D); 43 | } 44 | 45 | static void DumpInt(int x, DumpState* D) 46 | { 47 | DumpVar(x,D); 48 | } 49 | 50 | static void DumpNumber(lua_Number x, DumpState* D) 51 | { 52 | DumpVar(x,D); 53 | } 54 | 55 | static void DumpVector(const void* b, int n, size_t size, DumpState* D) 56 | { 57 | DumpInt(n,D); 58 | DumpMem(b,n,size,D); 59 | } 60 | 61 | static void DumpString(const TString* s, DumpState* D) 62 | { 63 | if (s==NULL) 64 | { 65 | size_t size=0; 66 | DumpVar(size,D); 67 | } 68 | else 69 | { 70 | size_t size=s->tsv.len+1; /* include trailing '\0' */ 71 | DumpVar(size,D); 72 | DumpBlock(getstr(s),size*sizeof(char),D); 73 | } 74 | } 75 | 76 | #define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) 77 | 78 | static void DumpFunction(const Proto* f, DumpState* D); 79 | 80 | static void DumpConstants(const Proto* f, DumpState* D) 81 | { 82 | int i,n=f->sizek; 83 | DumpInt(n,D); 84 | for (i=0; ik[i]; 87 | DumpChar(ttypenv(o),D); 88 | switch (ttypenv(o)) 89 | { 90 | case LUA_TNIL: 91 | break; 92 | case LUA_TBOOLEAN: 93 | DumpChar(bvalue(o),D); 94 | break; 95 | case LUA_TNUMBER: 96 | DumpNumber(nvalue(o),D); 97 | break; 98 | case LUA_TSTRING: 99 | DumpString(rawtsvalue(o),D); 100 | break; 101 | default: lua_assert(0); 102 | } 103 | } 104 | n=f->sizep; 105 | DumpInt(n,D); 106 | for (i=0; ip[i],D); 107 | } 108 | 109 | static void DumpUpvalues(const Proto* f, DumpState* D) 110 | { 111 | int i,n=f->sizeupvalues; 112 | DumpInt(n,D); 113 | for (i=0; iupvalues[i].instack,D); 116 | DumpChar(f->upvalues[i].idx,D); 117 | } 118 | } 119 | 120 | static void DumpDebug(const Proto* f, DumpState* D) 121 | { 122 | int i,n; 123 | DumpString((D->strip) ? NULL : f->source,D); 124 | n= (D->strip) ? 0 : f->sizelineinfo; 125 | DumpVector(f->lineinfo,n,sizeof(int),D); 126 | n= (D->strip) ? 0 : f->sizelocvars; 127 | DumpInt(n,D); 128 | for (i=0; ilocvars[i].varname,D); 131 | DumpInt(f->locvars[i].startpc,D); 132 | DumpInt(f->locvars[i].endpc,D); 133 | } 134 | n= (D->strip) ? 0 : f->sizeupvalues; 135 | DumpInt(n,D); 136 | for (i=0; iupvalues[i].name,D); 137 | } 138 | 139 | static void DumpFunction(const Proto* f, DumpState* D) 140 | { 141 | DumpInt(f->linedefined,D); 142 | DumpInt(f->lastlinedefined,D); 143 | DumpChar(f->numparams,D); 144 | DumpChar(f->is_vararg,D); 145 | DumpChar(f->maxstacksize,D); 146 | DumpCode(f,D); 147 | DumpConstants(f,D); 148 | DumpUpvalues(f,D); 149 | DumpDebug(f,D); 150 | } 151 | 152 | static void DumpHeader(DumpState* D) 153 | { 154 | lu_byte h[LUAC_HEADERSIZE]; 155 | luaU_header(h); 156 | DumpBlock(h,LUAC_HEADERSIZE,D); 157 | } 158 | 159 | /* 160 | ** dump Lua function as precompiled chunk 161 | */ 162 | int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) 163 | { 164 | DumpState D; 165 | D.L=L; 166 | D.writer=w; 167 | D.data=data; 168 | D.strip=strip; 169 | D.status=0; 170 | DumpHeader(&D); 171 | DumpFunction(f,&D); 172 | return D.status; 173 | } 174 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lfunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.c,v 2.30 2012/10/03 12:36:46 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lfunc_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "lfunc.h" 16 | #include "lgc.h" 17 | #include "lmem.h" 18 | #include "lobject.h" 19 | #include "lstate.h" 20 | 21 | 22 | 23 | Closure *luaF_newCclosure (lua_State *L, int n) { 24 | Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl; 25 | c->c.nupvalues = cast_byte(n); 26 | return c; 27 | } 28 | 29 | 30 | Closure *luaF_newLclosure (lua_State *L, int n) { 31 | Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl; 32 | c->l.p = NULL; 33 | c->l.nupvalues = cast_byte(n); 34 | while (n--) c->l.upvals[n] = NULL; 35 | return c; 36 | } 37 | 38 | 39 | UpVal *luaF_newupval (lua_State *L) { 40 | UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv; 41 | uv->v = &uv->u.value; 42 | setnilvalue(uv->v); 43 | return uv; 44 | } 45 | 46 | 47 | UpVal *luaF_findupval (lua_State *L, StkId level) { 48 | global_State *g = G(L); 49 | GCObject **pp = &L->openupval; 50 | UpVal *p; 51 | UpVal *uv; 52 | while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { 53 | GCObject *o = obj2gco(p); 54 | lua_assert(p->v != &p->u.value); 55 | lua_assert(!isold(o) || isold(obj2gco(L))); 56 | if (p->v == level) { /* found a corresponding upvalue? */ 57 | if (isdead(g, o)) /* is it dead? */ 58 | changewhite(o); /* resurrect it */ 59 | return p; 60 | } 61 | pp = &p->next; 62 | } 63 | /* not found: create a new one */ 64 | uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv; 65 | uv->v = level; /* current value lives in the stack */ 66 | uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ 67 | uv->u.l.next = g->uvhead.u.l.next; 68 | uv->u.l.next->u.l.prev = uv; 69 | g->uvhead.u.l.next = uv; 70 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); 71 | return uv; 72 | } 73 | 74 | 75 | static void unlinkupval (UpVal *uv) { 76 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); 77 | uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ 78 | uv->u.l.prev->u.l.next = uv->u.l.next; 79 | } 80 | 81 | 82 | void luaF_freeupval (lua_State *L, UpVal *uv) { 83 | if (uv->v != &uv->u.value) /* is it open? */ 84 | unlinkupval(uv); /* remove from open list */ 85 | luaM_free(L, uv); /* free upvalue */ 86 | } 87 | 88 | 89 | void luaF_close (lua_State *L, StkId level) { 90 | UpVal *uv; 91 | global_State *g = G(L); 92 | while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) { 93 | GCObject *o = obj2gco(uv); 94 | lua_assert(!isblack(o) && uv->v != &uv->u.value); 95 | L->openupval = uv->next; /* remove from `open' list */ 96 | if (isdead(g, o)) 97 | luaF_freeupval(L, uv); /* free upvalue */ 98 | else { 99 | unlinkupval(uv); /* remove upvalue from 'uvhead' list */ 100 | setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ 101 | uv->v = &uv->u.value; /* now current value lives here */ 102 | gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */ 103 | g->allgc = o; 104 | luaC_checkupvalcolor(g, uv); 105 | } 106 | } 107 | } 108 | 109 | 110 | Proto *luaF_newproto (lua_State *L) { 111 | Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p; 112 | f->k = NULL; 113 | f->sizek = 0; 114 | f->p = NULL; 115 | f->sizep = 0; 116 | f->code = NULL; 117 | f->cache = NULL; 118 | f->sizecode = 0; 119 | f->lineinfo = NULL; 120 | f->sizelineinfo = 0; 121 | f->upvalues = NULL; 122 | f->sizeupvalues = 0; 123 | f->numparams = 0; 124 | f->is_vararg = 0; 125 | f->maxstacksize = 0; 126 | f->locvars = NULL; 127 | f->sizelocvars = 0; 128 | f->linedefined = 0; 129 | f->lastlinedefined = 0; 130 | f->source = NULL; 131 | return f; 132 | } 133 | 134 | 135 | void luaF_freeproto (lua_State *L, Proto *f) { 136 | luaM_freearray(L, f->code, f->sizecode); 137 | luaM_freearray(L, f->p, f->sizep); 138 | luaM_freearray(L, f->k, f->sizek); 139 | luaM_freearray(L, f->lineinfo, f->sizelineinfo); 140 | luaM_freearray(L, f->locvars, f->sizelocvars); 141 | luaM_freearray(L, f->upvalues, f->sizeupvalues); 142 | luaM_free(L, f); 143 | } 144 | 145 | 146 | /* 147 | ** Look for n-th local variable at line `line' in function `func'. 148 | ** Returns NULL if not found. 149 | */ 150 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { 151 | int i; 152 | for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { 153 | if (pc < f->locvars[i].endpc) { /* is variable active? */ 154 | local_number--; 155 | if (local_number == 0) 156 | return getstr(f->locvars[i].varname); 157 | } 158 | } 159 | return NULL; /* not found */ 160 | } 161 | 162 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h,v 2.8 2012/05/08 13:53:33 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ 15 | cast(int, sizeof(TValue)*((n)-1))) 16 | 17 | #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ 18 | cast(int, sizeof(TValue *)*((n)-1))) 19 | 20 | 21 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 22 | LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems); 23 | LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems); 24 | LUAI_FUNC UpVal *luaF_newupval (lua_State *L); 25 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 26 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); 27 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 28 | LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); 29 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 30 | int pc); 31 | 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lgc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lgc.h,v 2.58 2012/09/11 12:53:08 roberto Exp $ 3 | ** Garbage Collector 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lgc_h 8 | #define lgc_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | /* 15 | ** Collectable objects may have one of three colors: white, which 16 | ** means the object is not marked; gray, which means the 17 | ** object is marked, but its references may be not marked; and 18 | ** black, which means that the object and all its references are marked. 19 | ** The main invariant of the garbage collector, while marking objects, 20 | ** is that a black object can never point to a white one. Moreover, 21 | ** any gray object must be in a "gray list" (gray, grayagain, weak, 22 | ** allweak, ephemeron) so that it can be visited again before finishing 23 | ** the collection cycle. These lists have no meaning when the invariant 24 | ** is not being enforced (e.g., sweep phase). 25 | */ 26 | 27 | 28 | 29 | /* how much to allocate before next GC step */ 30 | #if !defined(GCSTEPSIZE) 31 | /* ~100 small strings */ 32 | #define GCSTEPSIZE (cast_int(100 * sizeof(TString))) 33 | #endif 34 | 35 | 36 | /* 37 | ** Possible states of the Garbage Collector 38 | */ 39 | #define GCSpropagate 0 40 | #define GCSatomic 1 41 | #define GCSsweepstring 2 42 | #define GCSsweepudata 3 43 | #define GCSsweep 4 44 | #define GCSpause 5 45 | 46 | 47 | #define issweepphase(g) \ 48 | (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep) 49 | 50 | #define isgenerational(g) ((g)->gckind == KGC_GEN) 51 | 52 | /* 53 | ** macros to tell when main invariant (white objects cannot point to black 54 | ** ones) must be kept. During a non-generational collection, the sweep 55 | ** phase may break the invariant, as objects turned white may point to 56 | ** still-black objects. The invariant is restored when sweep ends and 57 | ** all objects are white again. During a generational collection, the 58 | ** invariant must be kept all times. 59 | */ 60 | 61 | #define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) 62 | 63 | 64 | /* 65 | ** Outside the collector, the state in generational mode is kept in 66 | ** 'propagate', so 'keepinvariant' is always true. 67 | */ 68 | #define keepinvariantout(g) \ 69 | check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \ 70 | g->gcstate <= GCSatomic) 71 | 72 | 73 | /* 74 | ** some useful bit tricks 75 | */ 76 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) 77 | #define setbits(x,m) ((x) |= (m)) 78 | #define testbits(x,m) ((x) & (m)) 79 | #define bitmask(b) (1<<(b)) 80 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 81 | #define l_setbit(x,b) setbits(x, bitmask(b)) 82 | #define resetbit(x,b) resetbits(x, bitmask(b)) 83 | #define testbit(x,b) testbits(x, bitmask(b)) 84 | 85 | 86 | /* Layout for bit use in `marked' field: */ 87 | #define WHITE0BIT 0 /* object is white (type 0) */ 88 | #define WHITE1BIT 1 /* object is white (type 1) */ 89 | #define BLACKBIT 2 /* object is black */ 90 | #define FINALIZEDBIT 3 /* object has been separated for finalization */ 91 | #define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ 92 | #define FIXEDBIT 5 /* object is fixed (should not be collected) */ 93 | #define OLDBIT 6 /* object is old (only in generational mode) */ 94 | /* bit 7 is currently used by tests (luaL_checkmemory) */ 95 | 96 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 97 | 98 | 99 | #define iswhite(x) testbits((x)->gch.marked, WHITEBITS) 100 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) 101 | #define isgray(x) /* neither white nor black */ \ 102 | (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) 103 | 104 | #define isold(x) testbit((x)->gch.marked, OLDBIT) 105 | 106 | /* MOVE OLD rule: whenever an object is moved to the beginning of 107 | a GC list, its old bit must be cleared */ 108 | #define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT) 109 | 110 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) 111 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) 112 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked) 113 | 114 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) 115 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) 116 | 117 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) 118 | 119 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) 120 | 121 | 122 | #define luaC_condGC(L,c) \ 123 | {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);} 124 | #define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) 125 | 126 | 127 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ 128 | luaC_barrier_(L,obj2gco(p),gcvalue(v)); } 129 | 130 | #define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ 131 | luaC_barrierback_(L,p); } 132 | 133 | #define luaC_objbarrier(L,p,o) \ 134 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ 135 | luaC_barrier_(L,obj2gco(p),obj2gco(o)); } 136 | 137 | #define luaC_objbarrierback(L,p,o) \ 138 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); } 139 | 140 | #define luaC_barrierproto(L,p,c) \ 141 | { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); } 142 | 143 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); 144 | LUAI_FUNC void luaC_step (lua_State *L); 145 | LUAI_FUNC void luaC_forcestep (lua_State *L); 146 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); 147 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); 148 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, 149 | GCObject **list, int offset); 150 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); 151 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); 152 | LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c); 153 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); 154 | LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); 155 | LUAI_FUNC void luaC_changemode (lua_State *L, int mode); 156 | 157 | #endif 158 | -------------------------------------------------------------------------------- /lua-5.2.2/src/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c,v 1.32 2011/04/08 19:17:36 roberto Exp $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | /* 9 | ** If you embed Lua in your program and need to open the standard 10 | ** libraries, call luaL_openlibs in your program. If you need a 11 | ** different set of libraries, copy this file to your project and edit 12 | ** it to suit your needs. 13 | */ 14 | 15 | 16 | #define linit_c 17 | #define LUA_LIB 18 | 19 | #include "lua.h" 20 | 21 | #include "lualib.h" 22 | #include "lauxlib.h" 23 | 24 | 25 | /* 26 | ** these libs are loaded by lua.c and are readily available to any Lua 27 | ** program 28 | */ 29 | static const luaL_Reg loadedlibs[] = { 30 | {"_G", luaopen_base}, 31 | {LUA_LOADLIBNAME, luaopen_package}, 32 | {LUA_COLIBNAME, luaopen_coroutine}, 33 | {LUA_TABLIBNAME, luaopen_table}, 34 | {LUA_IOLIBNAME, luaopen_io}, 35 | {LUA_OSLIBNAME, luaopen_os}, 36 | {LUA_STRLIBNAME, luaopen_string}, 37 | {LUA_BITLIBNAME, luaopen_bit32}, 38 | {LUA_MATHLIBNAME, luaopen_math}, 39 | {LUA_DBLIBNAME, luaopen_debug}, 40 | {NULL, NULL} 41 | }; 42 | 43 | 44 | /* 45 | ** these libs are preloaded and must be required before used 46 | */ 47 | static const luaL_Reg preloadedlibs[] = { 48 | {NULL, NULL} 49 | }; 50 | 51 | 52 | LUALIB_API void luaL_openlibs (lua_State *L) { 53 | const luaL_Reg *lib; 54 | /* call open functions from 'loadedlibs' and set results to global table */ 55 | for (lib = loadedlibs; lib->func; lib++) { 56 | luaL_requiref(L, lib->name, lib->func, 1); 57 | lua_pop(L, 1); /* remove lib */ 58 | } 59 | /* add open functions from 'preloadedlibs' into 'package.preload' table */ 60 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); 61 | for (lib = preloadedlibs; lib->func; lib++) { 62 | lua_pushcfunction(L, lib->func); 63 | lua_setfield(L, -2, lib->name); 64 | } 65 | lua_pop(L, 1); /* remove _PRELOAD table */ 66 | } 67 | 68 | -------------------------------------------------------------------------------- /lua-5.2.2/src/llex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.h,v 1.72 2011/11/30 12:43:51 roberto Exp $ 3 | ** Lexical Analyzer 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llex_h 8 | #define llex_h 9 | 10 | #include "lobject.h" 11 | #include "lzio.h" 12 | 13 | 14 | #define FIRST_RESERVED 257 15 | 16 | 17 | 18 | /* 19 | * WARNING: if you change the order of this enumeration, 20 | * grep "ORDER RESERVED" 21 | */ 22 | enum RESERVED { 23 | /* terminal symbols denoted by reserved words */ 24 | TK_AND = FIRST_RESERVED, TK_BREAK, 25 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 26 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 27 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 28 | /* other terminal symbols */ 29 | TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS, 30 | TK_NUMBER, TK_NAME, TK_STRING 31 | }; 32 | 33 | /* number of reserved words */ 34 | #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) 35 | 36 | 37 | typedef union { 38 | lua_Number r; 39 | TString *ts; 40 | } SemInfo; /* semantics information */ 41 | 42 | 43 | typedef struct Token { 44 | int token; 45 | SemInfo seminfo; 46 | } Token; 47 | 48 | 49 | /* state of the lexer plus state of the parser when shared by all 50 | functions */ 51 | typedef struct LexState { 52 | int current; /* current character (charint) */ 53 | int linenumber; /* input line counter */ 54 | int lastline; /* line of last token `consumed' */ 55 | Token t; /* current token */ 56 | Token lookahead; /* look ahead token */ 57 | struct FuncState *fs; /* current function (parser) */ 58 | struct lua_State *L; 59 | ZIO *z; /* input stream */ 60 | Mbuffer *buff; /* buffer for tokens */ 61 | struct Dyndata *dyd; /* dynamic structures used by the parser */ 62 | TString *source; /* current source name */ 63 | TString *envn; /* environment variable name */ 64 | char decpoint; /* locale decimal point */ 65 | } LexState; 66 | 67 | 68 | LUAI_FUNC void luaX_init (lua_State *L); 69 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 70 | TString *source, int firstchar); 71 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 72 | LUAI_FUNC void luaX_next (LexState *ls); 73 | LUAI_FUNC int luaX_lookahead (LexState *ls); 74 | LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); 75 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 76 | 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /lua-5.2.2/src/llimits.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llimits.h,v 1.103 2013/02/20 14:08:56 roberto Exp $ 3 | ** Limits, basic types, and some other `installation-dependent' definitions 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llimits_h 8 | #define llimits_h 9 | 10 | 11 | #include 12 | #include 13 | 14 | 15 | #include "lua.h" 16 | 17 | 18 | typedef unsigned LUA_INT32 lu_int32; 19 | 20 | typedef LUAI_UMEM lu_mem; 21 | 22 | typedef LUAI_MEM l_mem; 23 | 24 | 25 | 26 | /* chars used as small naturals (so that `char' is reserved for characters) */ 27 | typedef unsigned char lu_byte; 28 | 29 | 30 | #define MAX_SIZET ((size_t)(~(size_t)0)-2) 31 | 32 | #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) 33 | 34 | #define MAX_LMEM ((l_mem) ((MAX_LUMEM >> 1) - 2)) 35 | 36 | 37 | #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ 38 | 39 | /* 40 | ** conversion of pointer to integer 41 | ** this is for hashing only; there is no problem if the integer 42 | ** cannot hold the whole pointer value 43 | */ 44 | #define IntPoint(p) ((unsigned int)(lu_mem)(p)) 45 | 46 | 47 | 48 | /* type to ensure maximum alignment */ 49 | #if !defined(LUAI_USER_ALIGNMENT_T) 50 | #define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } 51 | #endif 52 | 53 | typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; 54 | 55 | 56 | /* result of a `usual argument conversion' over lua_Number */ 57 | typedef LUAI_UACNUMBER l_uacNumber; 58 | 59 | 60 | /* internal assertions for in-house debugging */ 61 | #if defined(lua_assert) 62 | #define check_exp(c,e) (lua_assert(c), (e)) 63 | /* to avoid problems with conditions too long */ 64 | #define lua_longassert(c) { if (!(c)) lua_assert(0); } 65 | #else 66 | #define lua_assert(c) ((void)0) 67 | #define check_exp(c,e) (e) 68 | #define lua_longassert(c) ((void)0) 69 | #endif 70 | 71 | /* 72 | ** assertion for checking API calls 73 | */ 74 | #if !defined(luai_apicheck) 75 | 76 | #if defined(LUA_USE_APICHECK) 77 | #include 78 | #define luai_apicheck(L,e) assert(e) 79 | #else 80 | #define luai_apicheck(L,e) lua_assert(e) 81 | #endif 82 | 83 | #endif 84 | 85 | #define api_check(l,e,msg) luai_apicheck(l,(e) && msg) 86 | 87 | 88 | #if !defined(UNUSED) 89 | #define UNUSED(x) ((void)(x)) /* to avoid warnings */ 90 | #endif 91 | 92 | 93 | #define cast(t, exp) ((t)(exp)) 94 | 95 | #define cast_byte(i) cast(lu_byte, (i)) 96 | #define cast_num(i) cast(lua_Number, (i)) 97 | #define cast_int(i) cast(int, (i)) 98 | #define cast_uchar(i) cast(unsigned char, (i)) 99 | 100 | 101 | /* 102 | ** non-return type 103 | */ 104 | #if defined(__GNUC__) 105 | #define l_noret void __attribute__((noreturn)) 106 | #elif defined(_MSC_VER) 107 | #define l_noret void __declspec(noreturn) 108 | #else 109 | #define l_noret void 110 | #endif 111 | 112 | 113 | 114 | /* 115 | ** maximum depth for nested C calls and syntactical nested non-terminals 116 | ** in a program. (Value must fit in an unsigned short int.) 117 | */ 118 | #if !defined(LUAI_MAXCCALLS) 119 | #define LUAI_MAXCCALLS 200 120 | #endif 121 | 122 | /* 123 | ** maximum number of upvalues in a closure (both C and Lua). (Value 124 | ** must fit in an unsigned char.) 125 | */ 126 | #define MAXUPVAL UCHAR_MAX 127 | 128 | 129 | /* 130 | ** type for virtual-machine instructions 131 | ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) 132 | */ 133 | typedef lu_int32 Instruction; 134 | 135 | 136 | 137 | /* maximum stack for a Lua function */ 138 | #define MAXSTACK 250 139 | 140 | 141 | 142 | /* minimum size for the string table (must be power of 2) */ 143 | #if !defined(MINSTRTABSIZE) 144 | #define MINSTRTABSIZE 32 145 | #endif 146 | 147 | 148 | /* minimum size for string buffer */ 149 | #if !defined(LUA_MINBUFFER) 150 | #define LUA_MINBUFFER 32 151 | #endif 152 | 153 | 154 | #if !defined(lua_lock) 155 | #define lua_lock(L) ((void) 0) 156 | #define lua_unlock(L) ((void) 0) 157 | #endif 158 | 159 | #if !defined(luai_threadyield) 160 | #define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} 161 | #endif 162 | 163 | 164 | /* 165 | ** these macros allow user-specific actions on threads when you defined 166 | ** LUAI_EXTRASPACE and need to do something extra when a thread is 167 | ** created/deleted/resumed/yielded. 168 | */ 169 | #if !defined(luai_userstateopen) 170 | #define luai_userstateopen(L) ((void)L) 171 | #endif 172 | 173 | #if !defined(luai_userstateclose) 174 | #define luai_userstateclose(L) ((void)L) 175 | #endif 176 | 177 | #if !defined(luai_userstatethread) 178 | #define luai_userstatethread(L,L1) ((void)L) 179 | #endif 180 | 181 | #if !defined(luai_userstatefree) 182 | #define luai_userstatefree(L,L1) ((void)L) 183 | #endif 184 | 185 | #if !defined(luai_userstateresume) 186 | #define luai_userstateresume(L,n) ((void)L) 187 | #endif 188 | 189 | #if !defined(luai_userstateyield) 190 | #define luai_userstateyield(L,n) ((void)L) 191 | #endif 192 | 193 | /* 194 | ** lua_number2int is a macro to convert lua_Number to int. 195 | ** lua_number2integer is a macro to convert lua_Number to lua_Integer. 196 | ** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned. 197 | ** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number. 198 | ** luai_hashnum is a macro to hash a lua_Number value into an integer. 199 | ** The hash must be deterministic and give reasonable values for 200 | ** both small and large values (outside the range of integers). 201 | */ 202 | 203 | #if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */ 204 | /* trick with Microsoft assembler for X86 */ 205 | 206 | #define lua_number2int(i,n) __asm {__asm fld n __asm fistp i} 207 | #define lua_number2integer(i,n) lua_number2int(i, n) 208 | #define lua_number2unsigned(i,n) \ 209 | {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;} 210 | 211 | 212 | #elif defined(LUA_IEEE754TRICK) /* }{ */ 213 | /* the next trick should work on any machine using IEEE754 with 214 | a 32-bit int type */ 215 | 216 | union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; 217 | 218 | #if !defined(LUA_IEEEENDIAN) /* { */ 219 | #define LUAI_EXTRAIEEE \ 220 | static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)}; 221 | #define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33) 222 | #else 223 | #define LUA_IEEEENDIANLOC LUA_IEEEENDIAN 224 | #define LUAI_EXTRAIEEE /* empty */ 225 | #endif /* } */ 226 | 227 | #define lua_number2int32(i,n,t) \ 228 | { LUAI_EXTRAIEEE \ 229 | volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ 230 | (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; } 231 | 232 | #define luai_hashnum(i,n) \ 233 | { volatile union luai_Cast u; u.l_d = (n) + 1.0; /* avoid -0 */ \ 234 | (i) = u.l_p[0]; (i) += u.l_p[1]; } /* add double bits for his hash */ 235 | 236 | #define lua_number2int(i,n) lua_number2int32(i, n, int) 237 | #define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned) 238 | 239 | /* the trick can be expanded to lua_Integer when it is a 32-bit value */ 240 | #if defined(LUA_IEEELL) 241 | #define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer) 242 | #endif 243 | 244 | #endif /* } */ 245 | 246 | 247 | /* the following definitions always work, but may be slow */ 248 | 249 | #if !defined(lua_number2int) 250 | #define lua_number2int(i,n) ((i)=(int)(n)) 251 | #endif 252 | 253 | #if !defined(lua_number2integer) 254 | #define lua_number2integer(i,n) ((i)=(lua_Integer)(n)) 255 | #endif 256 | 257 | #if !defined(lua_number2unsigned) /* { */ 258 | /* the following definition assures proper modulo behavior */ 259 | #if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT) 260 | #include 261 | #define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1) 262 | #define lua_number2unsigned(i,n) \ 263 | ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED)) 264 | #else 265 | #define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n)) 266 | #endif 267 | #endif /* } */ 268 | 269 | 270 | #if !defined(lua_unsigned2number) 271 | /* on several machines, coercion from unsigned to double is slow, 272 | so it may be worth to avoid */ 273 | #define lua_unsigned2number(u) \ 274 | (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u)) 275 | #endif 276 | 277 | 278 | 279 | #if defined(ltable_c) && !defined(luai_hashnum) 280 | 281 | #include 282 | #include 283 | 284 | #define luai_hashnum(i,n) { int e; \ 285 | n = l_mathop(frexp)(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ 286 | lua_number2int(i, n); i += e; } 287 | 288 | #endif 289 | 290 | 291 | 292 | /* 293 | ** macro to control inclusion of some hard tests on stack reallocation 294 | */ 295 | #if !defined(HARDSTACKTESTS) 296 | #define condmovestack(L) ((void)0) 297 | #else 298 | /* realloc stack keeping its size */ 299 | #define condmovestack(L) luaD_reallocstack((L), (L)->stacksize) 300 | #endif 301 | 302 | #if !defined(HARDMEMTESTS) 303 | #define condchangemem(L) condmovestack(L) 304 | #else 305 | #define condchangemem(L) \ 306 | ((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1))) 307 | #endif 308 | 309 | #endif 310 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lmathlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmathlib.c,v 1.83 2013/03/07 18:21:32 roberto Exp $ 3 | ** Standard mathematical library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | 11 | #define lmathlib_c 12 | #define LUA_LIB 13 | 14 | #include "lua.h" 15 | 16 | #include "lauxlib.h" 17 | #include "lualib.h" 18 | 19 | 20 | #undef PI 21 | #define PI ((lua_Number)(3.1415926535897932384626433832795)) 22 | #define RADIANS_PER_DEGREE ((lua_Number)(PI/180.0)) 23 | 24 | 25 | 26 | static int math_abs (lua_State *L) { 27 | lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); 28 | return 1; 29 | } 30 | 31 | static int math_sin (lua_State *L) { 32 | lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); 33 | return 1; 34 | } 35 | 36 | static int math_sinh (lua_State *L) { 37 | lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); 38 | return 1; 39 | } 40 | 41 | static int math_cos (lua_State *L) { 42 | lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); 43 | return 1; 44 | } 45 | 46 | static int math_cosh (lua_State *L) { 47 | lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); 48 | return 1; 49 | } 50 | 51 | static int math_tan (lua_State *L) { 52 | lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); 53 | return 1; 54 | } 55 | 56 | static int math_tanh (lua_State *L) { 57 | lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); 58 | return 1; 59 | } 60 | 61 | static int math_asin (lua_State *L) { 62 | lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); 63 | return 1; 64 | } 65 | 66 | static int math_acos (lua_State *L) { 67 | lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); 68 | return 1; 69 | } 70 | 71 | static int math_atan (lua_State *L) { 72 | lua_pushnumber(L, l_mathop(atan)(luaL_checknumber(L, 1))); 73 | return 1; 74 | } 75 | 76 | static int math_atan2 (lua_State *L) { 77 | lua_pushnumber(L, l_mathop(atan2)(luaL_checknumber(L, 1), 78 | luaL_checknumber(L, 2))); 79 | return 1; 80 | } 81 | 82 | static int math_ceil (lua_State *L) { 83 | lua_pushnumber(L, l_mathop(ceil)(luaL_checknumber(L, 1))); 84 | return 1; 85 | } 86 | 87 | static int math_floor (lua_State *L) { 88 | lua_pushnumber(L, l_mathop(floor)(luaL_checknumber(L, 1))); 89 | return 1; 90 | } 91 | 92 | static int math_fmod (lua_State *L) { 93 | lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), 94 | luaL_checknumber(L, 2))); 95 | return 1; 96 | } 97 | 98 | static int math_modf (lua_State *L) { 99 | lua_Number ip; 100 | lua_Number fp = l_mathop(modf)(luaL_checknumber(L, 1), &ip); 101 | lua_pushnumber(L, ip); 102 | lua_pushnumber(L, fp); 103 | return 2; 104 | } 105 | 106 | static int math_sqrt (lua_State *L) { 107 | lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); 108 | return 1; 109 | } 110 | 111 | static int math_pow (lua_State *L) { 112 | lua_Number x = luaL_checknumber(L, 1); 113 | lua_Number y = luaL_checknumber(L, 2); 114 | lua_pushnumber(L, l_mathop(pow)(x, y)); 115 | return 1; 116 | } 117 | 118 | static int math_log (lua_State *L) { 119 | lua_Number x = luaL_checknumber(L, 1); 120 | lua_Number res; 121 | if (lua_isnoneornil(L, 2)) 122 | res = l_mathop(log)(x); 123 | else { 124 | lua_Number base = luaL_checknumber(L, 2); 125 | if (base == (lua_Number)10.0) res = l_mathop(log10)(x); 126 | else res = l_mathop(log)(x)/l_mathop(log)(base); 127 | } 128 | lua_pushnumber(L, res); 129 | return 1; 130 | } 131 | 132 | #if defined(LUA_COMPAT_LOG10) 133 | static int math_log10 (lua_State *L) { 134 | lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); 135 | return 1; 136 | } 137 | #endif 138 | 139 | static int math_exp (lua_State *L) { 140 | lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); 141 | return 1; 142 | } 143 | 144 | static int math_deg (lua_State *L) { 145 | lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); 146 | return 1; 147 | } 148 | 149 | static int math_rad (lua_State *L) { 150 | lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); 151 | return 1; 152 | } 153 | 154 | static int math_frexp (lua_State *L) { 155 | int e; 156 | lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); 157 | lua_pushinteger(L, e); 158 | return 2; 159 | } 160 | 161 | static int math_ldexp (lua_State *L) { 162 | lua_Number x = luaL_checknumber(L, 1); 163 | int ep = luaL_checkint(L, 2); 164 | lua_pushnumber(L, l_mathop(ldexp)(x, ep)); 165 | return 1; 166 | } 167 | 168 | 169 | 170 | static int math_min (lua_State *L) { 171 | int n = lua_gettop(L); /* number of arguments */ 172 | lua_Number dmin = luaL_checknumber(L, 1); 173 | int i; 174 | for (i=2; i<=n; i++) { 175 | lua_Number d = luaL_checknumber(L, i); 176 | if (d < dmin) 177 | dmin = d; 178 | } 179 | lua_pushnumber(L, dmin); 180 | return 1; 181 | } 182 | 183 | 184 | static int math_max (lua_State *L) { 185 | int n = lua_gettop(L); /* number of arguments */ 186 | lua_Number dmax = luaL_checknumber(L, 1); 187 | int i; 188 | for (i=2; i<=n; i++) { 189 | lua_Number d = luaL_checknumber(L, i); 190 | if (d > dmax) 191 | dmax = d; 192 | } 193 | lua_pushnumber(L, dmax); 194 | return 1; 195 | } 196 | 197 | 198 | static int math_random (lua_State *L) { 199 | /* the `%' avoids the (rare) case of r==1, and is needed also because on 200 | some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ 201 | lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; 202 | switch (lua_gettop(L)) { /* check number of arguments */ 203 | case 0: { /* no arguments */ 204 | lua_pushnumber(L, r); /* Number between 0 and 1 */ 205 | break; 206 | } 207 | case 1: { /* only upper limit */ 208 | lua_Number u = luaL_checknumber(L, 1); 209 | luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty"); 210 | lua_pushnumber(L, l_mathop(floor)(r*u) + (lua_Number)(1.0)); /* [1, u] */ 211 | break; 212 | } 213 | case 2: { /* lower and upper limits */ 214 | lua_Number l = luaL_checknumber(L, 1); 215 | lua_Number u = luaL_checknumber(L, 2); 216 | luaL_argcheck(L, l <= u, 2, "interval is empty"); 217 | lua_pushnumber(L, l_mathop(floor)(r*(u-l+1)) + l); /* [l, u] */ 218 | break; 219 | } 220 | default: return luaL_error(L, "wrong number of arguments"); 221 | } 222 | return 1; 223 | } 224 | 225 | 226 | static int math_randomseed (lua_State *L) { 227 | srand(luaL_checkunsigned(L, 1)); 228 | (void)rand(); /* discard first value to avoid undesirable correlations */ 229 | return 0; 230 | } 231 | 232 | 233 | static const luaL_Reg mathlib[] = { 234 | {"abs", math_abs}, 235 | {"acos", math_acos}, 236 | {"asin", math_asin}, 237 | {"atan2", math_atan2}, 238 | {"atan", math_atan}, 239 | {"ceil", math_ceil}, 240 | {"cosh", math_cosh}, 241 | {"cos", math_cos}, 242 | {"deg", math_deg}, 243 | {"exp", math_exp}, 244 | {"floor", math_floor}, 245 | {"fmod", math_fmod}, 246 | {"frexp", math_frexp}, 247 | {"ldexp", math_ldexp}, 248 | #if defined(LUA_COMPAT_LOG10) 249 | {"log10", math_log10}, 250 | #endif 251 | {"log", math_log}, 252 | {"max", math_max}, 253 | {"min", math_min}, 254 | {"modf", math_modf}, 255 | {"pow", math_pow}, 256 | {"rad", math_rad}, 257 | {"random", math_random}, 258 | {"randomseed", math_randomseed}, 259 | {"sinh", math_sinh}, 260 | {"sin", math_sin}, 261 | {"sqrt", math_sqrt}, 262 | {"tanh", math_tanh}, 263 | {"tan", math_tan}, 264 | {NULL, NULL} 265 | }; 266 | 267 | 268 | /* 269 | ** Open math library 270 | */ 271 | LUAMOD_API int luaopen_math (lua_State *L) { 272 | luaL_newlib(L, mathlib); 273 | lua_pushnumber(L, PI); 274 | lua_setfield(L, -2, "pi"); 275 | lua_pushnumber(L, HUGE_VAL); 276 | lua_setfield(L, -2, "huge"); 277 | return 1; 278 | } 279 | 280 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.c,v 1.84 2012/05/23 15:41:53 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lmem_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "ldebug.h" 16 | #include "ldo.h" 17 | #include "lgc.h" 18 | #include "lmem.h" 19 | #include "lobject.h" 20 | #include "lstate.h" 21 | 22 | 23 | 24 | /* 25 | ** About the realloc function: 26 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 27 | ** (`osize' is the old size, `nsize' is the new size) 28 | ** 29 | ** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no 30 | ** matter 'x'). 31 | ** 32 | ** * frealloc(ud, p, x, 0) frees the block `p' 33 | ** (in this specific case, frealloc must return NULL); 34 | ** particularly, frealloc(ud, NULL, 0, 0) does nothing 35 | ** (which is equivalent to free(NULL) in ANSI C) 36 | ** 37 | ** frealloc returns NULL if it cannot create or reallocate the area 38 | ** (any reallocation to an equal or smaller size cannot fail!) 39 | */ 40 | 41 | 42 | 43 | #define MINSIZEARRAY 4 44 | 45 | 46 | void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, 47 | int limit, const char *what) { 48 | void *newblock; 49 | int newsize; 50 | if (*size >= limit/2) { /* cannot double it? */ 51 | if (*size >= limit) /* cannot grow even a little? */ 52 | luaG_runerror(L, "too many %s (limit is %d)", what, limit); 53 | newsize = limit; /* still have at least one free place */ 54 | } 55 | else { 56 | newsize = (*size)*2; 57 | if (newsize < MINSIZEARRAY) 58 | newsize = MINSIZEARRAY; /* minimum size */ 59 | } 60 | newblock = luaM_reallocv(L, block, *size, newsize, size_elems); 61 | *size = newsize; /* update only when everything else is OK */ 62 | return newblock; 63 | } 64 | 65 | 66 | l_noret luaM_toobig (lua_State *L) { 67 | luaG_runerror(L, "memory allocation error: block too big"); 68 | } 69 | 70 | 71 | 72 | /* 73 | ** generic allocation routine. 74 | */ 75 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 76 | void *newblock; 77 | global_State *g = G(L); 78 | size_t realosize = (block) ? osize : 0; 79 | lua_assert((realosize == 0) == (block == NULL)); 80 | #if defined(HARDMEMTESTS) 81 | if (nsize > realosize && g->gcrunning) 82 | luaC_fullgc(L, 1); /* force a GC whenever possible */ 83 | #endif 84 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); 85 | if (newblock == NULL && nsize > 0) { 86 | api_check(L, nsize > realosize, 87 | "realloc cannot fail when shrinking a block"); 88 | if (g->gcrunning) { 89 | luaC_fullgc(L, 1); /* try to free some memory... */ 90 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ 91 | } 92 | if (newblock == NULL) 93 | luaD_throw(L, LUA_ERRMEM); 94 | } 95 | lua_assert((nsize == 0) == (newblock == NULL)); 96 | g->GCdebt = (g->GCdebt + nsize) - realosize; 97 | return newblock; 98 | } 99 | 100 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.h,v 1.40 2013/02/20 14:08:21 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lmem_h 8 | #define lmem_h 9 | 10 | 11 | #include 12 | 13 | #include "llimits.h" 14 | #include "lua.h" 15 | 16 | 17 | /* 18 | ** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is 19 | ** always constant. 20 | ** The macro is somewhat complex to avoid warnings: 21 | ** +1 avoids warnings of "comparison has constant result"; 22 | ** cast to 'void' avoids warnings of "value unused". 23 | */ 24 | #define luaM_reallocv(L,b,on,n,e) \ 25 | (cast(void, \ 26 | (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \ 27 | luaM_realloc_(L, (b), (on)*(e), (n)*(e))) 28 | 29 | #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) 30 | #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) 31 | #define luaM_freearray(L, b, n) luaM_reallocv(L, (b), n, 0, sizeof((b)[0])) 32 | 33 | #define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) 34 | #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) 35 | #define luaM_newvector(L,n,t) \ 36 | cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) 37 | 38 | #define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s)) 39 | 40 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ 41 | if ((nelems)+1 > (size)) \ 42 | ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) 43 | 44 | #define luaM_reallocvector(L, v,oldn,n,t) \ 45 | ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) 46 | 47 | LUAI_FUNC l_noret luaM_toobig (lua_State *L); 48 | 49 | /* not to be called directly */ 50 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 51 | size_t size); 52 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, 53 | size_t size_elem, int limit, 54 | const char *what); 55 | 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lopcodes.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.c,v 1.49 2012/05/14 13:34:18 roberto Exp $ 3 | ** Opcodes for Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define lopcodes_c 9 | #define LUA_CORE 10 | 11 | 12 | #include "lopcodes.h" 13 | 14 | 15 | /* ORDER OP */ 16 | 17 | LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { 18 | "MOVE", 19 | "LOADK", 20 | "LOADKX", 21 | "LOADBOOL", 22 | "LOADNIL", 23 | "GETUPVAL", 24 | "GETTABUP", 25 | "GETTABLE", 26 | "SETTABUP", 27 | "SETUPVAL", 28 | "SETTABLE", 29 | "NEWTABLE", 30 | "SELF", 31 | "ADD", 32 | "SUB", 33 | "MUL", 34 | "DIV", 35 | "MOD", 36 | "POW", 37 | "UNM", 38 | "NOT", 39 | "LEN", 40 | "CONCAT", 41 | "JMP", 42 | "EQ", 43 | "LT", 44 | "LE", 45 | "TEST", 46 | "TESTSET", 47 | "CALL", 48 | "TAILCALL", 49 | "RETURN", 50 | "FORLOOP", 51 | "FORPREP", 52 | "TFORCALL", 53 | "TFORLOOP", 54 | "SETLIST", 55 | "CLOSURE", 56 | "VARARG", 57 | "EXTRAARG", 58 | NULL 59 | }; 60 | 61 | 62 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) 63 | 64 | LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { 65 | /* T A B C mode opcode */ 66 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ 67 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ 68 | ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ 69 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ 70 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ 71 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ 72 | ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ 73 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ 74 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ 75 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ 76 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ 77 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ 78 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ 79 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ 80 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ 81 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ 82 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ 83 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ 84 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ 85 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ 86 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ 87 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ 88 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ 89 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ 90 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ 91 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ 92 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ 93 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ 94 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ 95 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ 96 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ 97 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ 98 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ 99 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ 100 | ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ 101 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ 102 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ 103 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ 104 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ 105 | ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ 106 | }; 107 | 108 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lparser.h,v 1.70 2012/05/08 13:53:33 roberto Exp $ 3 | ** Lua Parser 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lparser_h 8 | #define lparser_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* 16 | ** Expression descriptor 17 | */ 18 | 19 | typedef enum { 20 | VVOID, /* no value */ 21 | VNIL, 22 | VTRUE, 23 | VFALSE, 24 | VK, /* info = index of constant in `k' */ 25 | VKNUM, /* nval = numerical value */ 26 | VNONRELOC, /* info = result register */ 27 | VLOCAL, /* info = local register */ 28 | VUPVAL, /* info = index of upvalue in 'upvalues' */ 29 | VINDEXED, /* t = table register/upvalue; idx = index R/K */ 30 | VJMP, /* info = instruction pc */ 31 | VRELOCABLE, /* info = instruction pc */ 32 | VCALL, /* info = instruction pc */ 33 | VVARARG /* info = instruction pc */ 34 | } expkind; 35 | 36 | 37 | #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) 38 | #define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) 39 | 40 | typedef struct expdesc { 41 | expkind k; 42 | union { 43 | struct { /* for indexed variables (VINDEXED) */ 44 | short idx; /* index (R/K) */ 45 | lu_byte t; /* table (register or upvalue) */ 46 | lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ 47 | } ind; 48 | int info; /* for generic use */ 49 | lua_Number nval; /* for VKNUM */ 50 | } u; 51 | int t; /* patch list of `exit when true' */ 52 | int f; /* patch list of `exit when false' */ 53 | } expdesc; 54 | 55 | 56 | /* description of active local variable */ 57 | typedef struct Vardesc { 58 | short idx; /* variable index in stack */ 59 | } Vardesc; 60 | 61 | 62 | /* description of pending goto statements and label statements */ 63 | typedef struct Labeldesc { 64 | TString *name; /* label identifier */ 65 | int pc; /* position in code */ 66 | int line; /* line where it appeared */ 67 | lu_byte nactvar; /* local level where it appears in current block */ 68 | } Labeldesc; 69 | 70 | 71 | /* list of labels or gotos */ 72 | typedef struct Labellist { 73 | Labeldesc *arr; /* array */ 74 | int n; /* number of entries in use */ 75 | int size; /* array size */ 76 | } Labellist; 77 | 78 | 79 | /* dynamic structures used by the parser */ 80 | typedef struct Dyndata { 81 | struct { /* list of active local variables */ 82 | Vardesc *arr; 83 | int n; 84 | int size; 85 | } actvar; 86 | Labellist gt; /* list of pending gotos */ 87 | Labellist label; /* list of active labels */ 88 | } Dyndata; 89 | 90 | 91 | /* control of blocks */ 92 | struct BlockCnt; /* defined in lparser.c */ 93 | 94 | 95 | /* state needed to generate code for a given function */ 96 | typedef struct FuncState { 97 | Proto *f; /* current function header */ 98 | Table *h; /* table to find (and reuse) elements in `k' */ 99 | struct FuncState *prev; /* enclosing function */ 100 | struct LexState *ls; /* lexical state */ 101 | struct BlockCnt *bl; /* chain of current blocks */ 102 | int pc; /* next position to code (equivalent to `ncode') */ 103 | int lasttarget; /* 'label' of last 'jump label' */ 104 | int jpc; /* list of pending jumps to `pc' */ 105 | int nk; /* number of elements in `k' */ 106 | int np; /* number of elements in `p' */ 107 | int firstlocal; /* index of first local var (in Dyndata array) */ 108 | short nlocvars; /* number of elements in 'f->locvars' */ 109 | lu_byte nactvar; /* number of active local variables */ 110 | lu_byte nups; /* number of upvalues */ 111 | lu_byte freereg; /* first free register */ 112 | } FuncState; 113 | 114 | 115 | LUAI_FUNC Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 116 | Dyndata *dyd, const char *name, int firstchar); 117 | 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lstate.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.c,v 2.99 2012/10/02 17:40:53 roberto Exp $ 3 | ** Global State 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | #include 10 | 11 | #define lstate_c 12 | #define LUA_CORE 13 | 14 | #include "lua.h" 15 | 16 | #include "lapi.h" 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lfunc.h" 20 | #include "lgc.h" 21 | #include "llex.h" 22 | #include "lmem.h" 23 | #include "lstate.h" 24 | #include "lstring.h" 25 | #include "ltable.h" 26 | #include "ltm.h" 27 | 28 | 29 | #if !defined(LUAI_GCPAUSE) 30 | #define LUAI_GCPAUSE 200 /* 200% */ 31 | #endif 32 | 33 | #if !defined(LUAI_GCMAJOR) 34 | #define LUAI_GCMAJOR 200 /* 200% */ 35 | #endif 36 | 37 | #if !defined(LUAI_GCMUL) 38 | #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ 39 | #endif 40 | 41 | 42 | #define MEMERRMSG "not enough memory" 43 | 44 | 45 | /* 46 | ** a macro to help the creation of a unique random seed when a state is 47 | ** created; the seed is used to randomize hashes. 48 | */ 49 | #if !defined(luai_makeseed) 50 | #include 51 | #define luai_makeseed() cast(unsigned int, time(NULL)) 52 | #endif 53 | 54 | 55 | 56 | /* 57 | ** thread state + extra space 58 | */ 59 | typedef struct LX { 60 | #if defined(LUAI_EXTRASPACE) 61 | char buff[LUAI_EXTRASPACE]; 62 | #endif 63 | lua_State l; 64 | } LX; 65 | 66 | 67 | /* 68 | ** Main thread combines a thread state and the global state 69 | */ 70 | typedef struct LG { 71 | LX l; 72 | global_State g; 73 | } LG; 74 | 75 | 76 | 77 | #define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) 78 | 79 | 80 | /* 81 | ** Compute an initial seed as random as possible. In ANSI, rely on 82 | ** Address Space Layout Randomization (if present) to increase 83 | ** randomness.. 84 | */ 85 | #define addbuff(b,p,e) \ 86 | { size_t t = cast(size_t, e); \ 87 | memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); } 88 | 89 | static unsigned int makeseed (lua_State *L) { 90 | char buff[4 * sizeof(size_t)]; 91 | unsigned int h = luai_makeseed(); 92 | int p = 0; 93 | addbuff(buff, p, L); /* heap variable */ 94 | addbuff(buff, p, &h); /* local variable */ 95 | addbuff(buff, p, luaO_nilobject); /* global variable */ 96 | addbuff(buff, p, &lua_newstate); /* public function */ 97 | lua_assert(p == sizeof(buff)); 98 | return luaS_hash(buff, p, h); 99 | } 100 | 101 | 102 | /* 103 | ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) 104 | ** invariant 105 | */ 106 | void luaE_setdebt (global_State *g, l_mem debt) { 107 | g->totalbytes -= (debt - g->GCdebt); 108 | g->GCdebt = debt; 109 | } 110 | 111 | 112 | CallInfo *luaE_extendCI (lua_State *L) { 113 | CallInfo *ci = luaM_new(L, CallInfo); 114 | lua_assert(L->ci->next == NULL); 115 | L->ci->next = ci; 116 | ci->previous = L->ci; 117 | ci->next = NULL; 118 | return ci; 119 | } 120 | 121 | 122 | void luaE_freeCI (lua_State *L) { 123 | CallInfo *ci = L->ci; 124 | CallInfo *next = ci->next; 125 | ci->next = NULL; 126 | while ((ci = next) != NULL) { 127 | next = ci->next; 128 | luaM_free(L, ci); 129 | } 130 | } 131 | 132 | 133 | static void stack_init (lua_State *L1, lua_State *L) { 134 | int i; CallInfo *ci; 135 | /* initialize stack array */ 136 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); 137 | L1->stacksize = BASIC_STACK_SIZE; 138 | for (i = 0; i < BASIC_STACK_SIZE; i++) 139 | setnilvalue(L1->stack + i); /* erase new stack */ 140 | L1->top = L1->stack; 141 | L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; 142 | /* initialize first ci */ 143 | ci = &L1->base_ci; 144 | ci->next = ci->previous = NULL; 145 | ci->callstatus = 0; 146 | ci->func = L1->top; 147 | setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ 148 | ci->top = L1->top + LUA_MINSTACK; 149 | L1->ci = ci; 150 | } 151 | 152 | 153 | static void freestack (lua_State *L) { 154 | if (L->stack == NULL) 155 | return; /* stack not completely built yet */ 156 | L->ci = &L->base_ci; /* free the entire 'ci' list */ 157 | luaE_freeCI(L); 158 | luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ 159 | } 160 | 161 | 162 | /* 163 | ** Create registry table and its predefined values 164 | */ 165 | static void init_registry (lua_State *L, global_State *g) { 166 | TValue mt; 167 | /* create registry */ 168 | Table *registry = luaH_new(L); 169 | sethvalue(L, &g->l_registry, registry); 170 | luaH_resize(L, registry, LUA_RIDX_LAST, 0); 171 | /* registry[LUA_RIDX_MAINTHREAD] = L */ 172 | setthvalue(L, &mt, L); 173 | luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt); 174 | /* registry[LUA_RIDX_GLOBALS] = table of globals */ 175 | sethvalue(L, &mt, luaH_new(L)); 176 | luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt); 177 | } 178 | 179 | 180 | /* 181 | ** open parts of the state that may cause memory-allocation errors 182 | */ 183 | static void f_luaopen (lua_State *L, void *ud) { 184 | global_State *g = G(L); 185 | UNUSED(ud); 186 | stack_init(L, L); /* init stack */ 187 | init_registry(L, g); 188 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 189 | luaT_init(L); 190 | luaX_init(L); 191 | /* pre-create memory-error message */ 192 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); 193 | luaS_fix(g->memerrmsg); /* it should never be collected */ 194 | g->gcrunning = 1; /* allow gc */ 195 | } 196 | 197 | 198 | /* 199 | ** preinitialize a state with consistent values without allocating 200 | ** any memory (to avoid errors) 201 | */ 202 | static void preinit_state (lua_State *L, global_State *g) { 203 | G(L) = g; 204 | L->stack = NULL; 205 | L->ci = NULL; 206 | L->stacksize = 0; 207 | L->errorJmp = NULL; 208 | L->nCcalls = 0; 209 | L->hook = NULL; 210 | L->hookmask = 0; 211 | L->basehookcount = 0; 212 | L->allowhook = 1; 213 | resethookcount(L); 214 | L->openupval = NULL; 215 | L->nny = 1; 216 | L->status = LUA_OK; 217 | L->errfunc = 0; 218 | } 219 | 220 | 221 | static void close_state (lua_State *L) { 222 | global_State *g = G(L); 223 | luaF_close(L, L->stack); /* close all upvalues for this thread */ 224 | luaC_freeallobjects(L); /* collect all objects */ 225 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); 226 | luaZ_freebuffer(L, &g->buff); 227 | freestack(L); 228 | lua_assert(gettotalbytes(g) == sizeof(LG)); 229 | (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ 230 | } 231 | 232 | 233 | LUA_API lua_State *lua_newthread (lua_State *L) { 234 | lua_State *L1; 235 | lua_lock(L); 236 | luaC_checkGC(L); 237 | L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th; 238 | setthvalue(L, L->top, L1); 239 | api_incr_top(L); 240 | preinit_state(L1, G(L)); 241 | L1->hookmask = L->hookmask; 242 | L1->basehookcount = L->basehookcount; 243 | L1->hook = L->hook; 244 | resethookcount(L1); 245 | luai_userstatethread(L, L1); 246 | stack_init(L1, L); /* init stack */ 247 | lua_unlock(L); 248 | return L1; 249 | } 250 | 251 | 252 | void luaE_freethread (lua_State *L, lua_State *L1) { 253 | LX *l = fromstate(L1); 254 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */ 255 | lua_assert(L1->openupval == NULL); 256 | luai_userstatefree(L, L1); 257 | freestack(L1); 258 | luaM_free(L, l); 259 | } 260 | 261 | 262 | LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { 263 | int i; 264 | lua_State *L; 265 | global_State *g; 266 | LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); 267 | if (l == NULL) return NULL; 268 | L = &l->l.l; 269 | g = &l->g; 270 | L->next = NULL; 271 | L->tt = LUA_TTHREAD; 272 | g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); 273 | L->marked = luaC_white(g); 274 | g->gckind = KGC_NORMAL; 275 | preinit_state(L, g); 276 | g->frealloc = f; 277 | g->ud = ud; 278 | g->mainthread = L; 279 | g->seed = makeseed(L); 280 | g->uvhead.u.l.prev = &g->uvhead; 281 | g->uvhead.u.l.next = &g->uvhead; 282 | g->gcrunning = 0; /* no GC while building state */ 283 | g->GCestimate = 0; 284 | g->strt.size = 0; 285 | g->strt.nuse = 0; 286 | g->strt.hash = NULL; 287 | setnilvalue(&g->l_registry); 288 | luaZ_initbuffer(L, &g->buff); 289 | g->panic = NULL; 290 | g->version = lua_version(NULL); 291 | g->gcstate = GCSpause; 292 | g->allgc = NULL; 293 | g->finobj = NULL; 294 | g->tobefnz = NULL; 295 | g->sweepgc = g->sweepfin = NULL; 296 | g->gray = g->grayagain = NULL; 297 | g->weak = g->ephemeron = g->allweak = NULL; 298 | g->totalbytes = sizeof(LG); 299 | g->GCdebt = 0; 300 | g->gcpause = LUAI_GCPAUSE; 301 | g->gcmajorinc = LUAI_GCMAJOR; 302 | g->gcstepmul = LUAI_GCMUL; 303 | for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; 304 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { 305 | /* memory allocation error: free partial state */ 306 | close_state(L); 307 | L = NULL; 308 | } 309 | else 310 | luai_userstateopen(L); 311 | return L; 312 | } 313 | 314 | 315 | LUA_API void lua_close (lua_State *L) { 316 | L = G(L)->mainthread; /* only the main thread can be closed */ 317 | lua_lock(L); 318 | luai_userstateclose(L); 319 | close_state(L); 320 | } 321 | 322 | 323 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lstate.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstate.h,v 2.82 2012/07/02 13:37:04 roberto Exp $ 3 | ** Global State 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstate_h 8 | #define lstate_h 9 | 10 | #include "lua.h" 11 | 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | #include "lzio.h" 15 | 16 | 17 | /* 18 | 19 | ** Some notes about garbage-collected objects: All objects in Lua must 20 | ** be kept somehow accessible until being freed. 21 | ** 22 | ** Lua keeps most objects linked in list g->allgc. The link uses field 23 | ** 'next' of the CommonHeader. 24 | ** 25 | ** Strings are kept in several lists headed by the array g->strt.hash. 26 | ** 27 | ** Open upvalues are not subject to independent garbage collection. They 28 | ** are collected together with their respective threads. Lua keeps a 29 | ** double-linked list with all open upvalues (g->uvhead) so that it can 30 | ** mark objects referred by them. (They are always gray, so they must 31 | ** be remarked in the atomic step. Usually their contents would be marked 32 | ** when traversing the respective threads, but the thread may already be 33 | ** dead, while the upvalue is still accessible through closures.) 34 | ** 35 | ** Objects with finalizers are kept in the list g->finobj. 36 | ** 37 | ** The list g->tobefnz links all objects being finalized. 38 | 39 | */ 40 | 41 | 42 | struct lua_longjmp; /* defined in ldo.c */ 43 | 44 | 45 | 46 | /* extra stack space to handle TM calls and some other extras */ 47 | #define EXTRA_STACK 5 48 | 49 | 50 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) 51 | 52 | 53 | /* kinds of Garbage Collection */ 54 | #define KGC_NORMAL 0 55 | #define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ 56 | #define KGC_GEN 2 /* generational collection */ 57 | 58 | 59 | typedef struct stringtable { 60 | GCObject **hash; 61 | lu_int32 nuse; /* number of elements */ 62 | int size; 63 | } stringtable; 64 | 65 | 66 | /* 67 | ** information about a call 68 | */ 69 | typedef struct CallInfo { 70 | StkId func; /* function index in the stack */ 71 | StkId top; /* top for this function */ 72 | struct CallInfo *previous, *next; /* dynamic call link */ 73 | short nresults; /* expected number of results from this function */ 74 | lu_byte callstatus; 75 | ptrdiff_t extra; 76 | union { 77 | struct { /* only for Lua functions */ 78 | StkId base; /* base for this function */ 79 | const Instruction *savedpc; 80 | } l; 81 | struct { /* only for C functions */ 82 | int ctx; /* context info. in case of yields */ 83 | lua_CFunction k; /* continuation in case of yields */ 84 | ptrdiff_t old_errfunc; 85 | lu_byte old_allowhook; 86 | lu_byte status; 87 | } c; 88 | } u; 89 | } CallInfo; 90 | 91 | 92 | /* 93 | ** Bits in CallInfo status 94 | */ 95 | #define CIST_LUA (1<<0) /* call is running a Lua function */ 96 | #define CIST_HOOKED (1<<1) /* call is running a debug hook */ 97 | #define CIST_REENTRY (1<<2) /* call is running on same invocation of 98 | luaV_execute of previous call */ 99 | #define CIST_YIELDED (1<<3) /* call reentered after suspension */ 100 | #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ 101 | #define CIST_STAT (1<<5) /* call has an error status (pcall) */ 102 | #define CIST_TAIL (1<<6) /* call was tail called */ 103 | #define CIST_HOOKYIELD (1<<7) /* last hook called yielded */ 104 | 105 | 106 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) 107 | 108 | 109 | /* 110 | ** `global state', shared by all threads of this state 111 | */ 112 | typedef struct global_State { 113 | lua_Alloc frealloc; /* function to reallocate memory */ 114 | void *ud; /* auxiliary data to `frealloc' */ 115 | lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */ 116 | l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ 117 | lu_mem GCmemtrav; /* memory traversed by the GC */ 118 | lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ 119 | stringtable strt; /* hash table for strings */ 120 | TValue l_registry; 121 | unsigned int seed; /* randomized seed for hashes */ 122 | lu_byte currentwhite; 123 | lu_byte gcstate; /* state of garbage collector */ 124 | lu_byte gckind; /* kind of GC running */ 125 | lu_byte gcrunning; /* true if GC is running */ 126 | int sweepstrgc; /* position of sweep in `strt' */ 127 | GCObject *allgc; /* list of all collectable objects */ 128 | GCObject *finobj; /* list of collectable objects with finalizers */ 129 | GCObject **sweepgc; /* current position of sweep in list 'allgc' */ 130 | GCObject **sweepfin; /* current position of sweep in list 'finobj' */ 131 | GCObject *gray; /* list of gray objects */ 132 | GCObject *grayagain; /* list of objects to be traversed atomically */ 133 | GCObject *weak; /* list of tables with weak values */ 134 | GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ 135 | GCObject *allweak; /* list of all-weak tables */ 136 | GCObject *tobefnz; /* list of userdata to be GC */ 137 | UpVal uvhead; /* head of double-linked list of all open upvalues */ 138 | Mbuffer buff; /* temporary buffer for string concatenation */ 139 | int gcpause; /* size of pause between successive GCs */ 140 | int gcmajorinc; /* pause between major collections (only in gen. mode) */ 141 | int gcstepmul; /* GC `granularity' */ 142 | lua_CFunction panic; /* to be called in unprotected errors */ 143 | struct lua_State *mainthread; 144 | const lua_Number *version; /* pointer to version number */ 145 | TString *memerrmsg; /* memory-error message */ 146 | TString *tmname[TM_N]; /* array with tag-method names */ 147 | struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ 148 | } global_State; 149 | 150 | 151 | /* 152 | ** `per thread' state 153 | */ 154 | struct lua_State { 155 | CommonHeader; 156 | lu_byte status; 157 | StkId top; /* first free slot in the stack */ 158 | global_State *l_G; 159 | CallInfo *ci; /* call info for current function */ 160 | const Instruction *oldpc; /* last pc traced */ 161 | StkId stack_last; /* last free slot in the stack */ 162 | StkId stack; /* stack base */ 163 | int stacksize; 164 | unsigned short nny; /* number of non-yieldable calls in stack */ 165 | unsigned short nCcalls; /* number of nested C calls */ 166 | lu_byte hookmask; 167 | lu_byte allowhook; 168 | int basehookcount; 169 | int hookcount; 170 | lua_Hook hook; 171 | GCObject *openupval; /* list of open upvalues in this stack */ 172 | GCObject *gclist; 173 | struct lua_longjmp *errorJmp; /* current error recover point */ 174 | ptrdiff_t errfunc; /* current error handling function (stack index) */ 175 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ 176 | }; 177 | 178 | 179 | #define G(L) (L->l_G) 180 | 181 | 182 | /* 183 | ** Union of all collectable objects 184 | */ 185 | union GCObject { 186 | GCheader gch; /* common header */ 187 | union TString ts; 188 | union Udata u; 189 | union Closure cl; 190 | struct Table h; 191 | struct Proto p; 192 | struct UpVal uv; 193 | struct lua_State th; /* thread */ 194 | }; 195 | 196 | 197 | #define gch(o) (&(o)->gch) 198 | 199 | /* macros to convert a GCObject into a specific value */ 200 | #define rawgco2ts(o) \ 201 | check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((o)->ts)) 202 | #define gco2ts(o) (&rawgco2ts(o)->tsv) 203 | #define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) 204 | #define gco2u(o) (&rawgco2u(o)->uv) 205 | #define gco2lcl(o) check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l)) 206 | #define gco2ccl(o) check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c)) 207 | #define gco2cl(o) \ 208 | check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl)) 209 | #define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) 210 | #define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) 211 | #define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) 212 | #define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) 213 | 214 | /* macro to convert any Lua object into a GCObject */ 215 | #define obj2gco(v) (cast(GCObject *, (v))) 216 | 217 | 218 | /* actual number of total bytes allocated */ 219 | #define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt) 220 | 221 | LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); 222 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 223 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); 224 | LUAI_FUNC void luaE_freeCI (lua_State *L); 225 | 226 | 227 | #endif 228 | 229 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.c,v 2.26 2013/01/08 13:50:10 roberto Exp $ 3 | ** String table (keeps all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lstring_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "lmem.h" 16 | #include "lobject.h" 17 | #include "lstate.h" 18 | #include "lstring.h" 19 | 20 | 21 | /* 22 | ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to 23 | ** compute its hash 24 | */ 25 | #if !defined(LUAI_HASHLIMIT) 26 | #define LUAI_HASHLIMIT 5 27 | #endif 28 | 29 | 30 | /* 31 | ** equality for long strings 32 | */ 33 | int luaS_eqlngstr (TString *a, TString *b) { 34 | size_t len = a->tsv.len; 35 | lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR); 36 | return (a == b) || /* same instance or... */ 37 | ((len == b->tsv.len) && /* equal length and ... */ 38 | (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ 39 | } 40 | 41 | 42 | /* 43 | ** equality for strings 44 | */ 45 | int luaS_eqstr (TString *a, TString *b) { 46 | return (a->tsv.tt == b->tsv.tt) && 47 | (a->tsv.tt == LUA_TSHRSTR ? eqshrstr(a, b) : luaS_eqlngstr(a, b)); 48 | } 49 | 50 | 51 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { 52 | unsigned int h = seed ^ cast(unsigned int, l); 53 | size_t l1; 54 | size_t step = (l >> LUAI_HASHLIMIT) + 1; 55 | for (l1 = l; l1 >= step; l1 -= step) 56 | h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1 - 1])); 57 | return h; 58 | } 59 | 60 | 61 | /* 62 | ** resizes the string table 63 | */ 64 | void luaS_resize (lua_State *L, int newsize) { 65 | int i; 66 | stringtable *tb = &G(L)->strt; 67 | /* cannot resize while GC is traversing strings */ 68 | luaC_runtilstate(L, ~bitmask(GCSsweepstring)); 69 | if (newsize > tb->size) { 70 | luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); 71 | for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL; 72 | } 73 | /* rehash */ 74 | for (i=0; isize; i++) { 75 | GCObject *p = tb->hash[i]; 76 | tb->hash[i] = NULL; 77 | while (p) { /* for each node in the list */ 78 | GCObject *next = gch(p)->next; /* save next */ 79 | unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ 80 | gch(p)->next = tb->hash[h]; /* chain it */ 81 | tb->hash[h] = p; 82 | resetoldbit(p); /* see MOVE OLD rule */ 83 | p = next; 84 | } 85 | } 86 | if (newsize < tb->size) { 87 | /* shrinking slice must be empty */ 88 | lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); 89 | luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); 90 | } 91 | tb->size = newsize; 92 | } 93 | 94 | 95 | /* 96 | ** creates a new string object 97 | */ 98 | static TString *createstrobj (lua_State *L, const char *str, size_t l, 99 | int tag, unsigned int h, GCObject **list) { 100 | TString *ts; 101 | size_t totalsize; /* total size of TString object */ 102 | totalsize = sizeof(TString) + ((l + 1) * sizeof(char)); 103 | ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts; 104 | ts->tsv.len = l; 105 | ts->tsv.hash = h; 106 | ts->tsv.extra = 0; 107 | memcpy(ts+1, str, l*sizeof(char)); 108 | ((char *)(ts+1))[l] = '\0'; /* ending 0 */ 109 | return ts; 110 | } 111 | 112 | 113 | /* 114 | ** creates a new short string, inserting it into string table 115 | */ 116 | static TString *newshrstr (lua_State *L, const char *str, size_t l, 117 | unsigned int h) { 118 | GCObject **list; /* (pointer to) list where it will be inserted */ 119 | stringtable *tb = &G(L)->strt; 120 | TString *s; 121 | if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) 122 | luaS_resize(L, tb->size*2); /* too crowded */ 123 | list = &tb->hash[lmod(h, tb->size)]; 124 | s = createstrobj(L, str, l, LUA_TSHRSTR, h, list); 125 | tb->nuse++; 126 | return s; 127 | } 128 | 129 | 130 | /* 131 | ** checks whether short string exists and reuses it or creates a new one 132 | */ 133 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { 134 | GCObject *o; 135 | global_State *g = G(L); 136 | unsigned int h = luaS_hash(str, l, g->seed); 137 | for (o = g->strt.hash[lmod(h, g->strt.size)]; 138 | o != NULL; 139 | o = gch(o)->next) { 140 | TString *ts = rawgco2ts(o); 141 | if (h == ts->tsv.hash && 142 | l == ts->tsv.len && 143 | (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { 144 | if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */ 145 | changewhite(o); /* resurrect it */ 146 | return ts; 147 | } 148 | } 149 | return newshrstr(L, str, l, h); /* not found; create a new string */ 150 | } 151 | 152 | 153 | /* 154 | ** new string (with explicit length) 155 | */ 156 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { 157 | if (l <= LUAI_MAXSHORTLEN) /* short string? */ 158 | return internshrstr(L, str, l); 159 | else { 160 | if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) 161 | luaM_toobig(L); 162 | return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL); 163 | } 164 | } 165 | 166 | 167 | /* 168 | ** new zero-terminated string 169 | */ 170 | TString *luaS_new (lua_State *L, const char *str) { 171 | return luaS_newlstr(L, str, strlen(str)); 172 | } 173 | 174 | 175 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { 176 | Udata *u; 177 | if (s > MAX_SIZET - sizeof(Udata)) 178 | luaM_toobig(L); 179 | u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u; 180 | u->uv.len = s; 181 | u->uv.metatable = NULL; 182 | u->uv.env = e; 183 | return u; 184 | } 185 | 186 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h,v 1.49 2012/02/01 21:57:15 roberto Exp $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | #define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) 16 | 17 | #define sizeudata(u) (sizeof(union Udata)+(u)->len) 18 | 19 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 20 | (sizeof(s)/sizeof(char))-1)) 21 | 22 | #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) 23 | 24 | 25 | /* 26 | ** test whether a string is a reserved word 27 | */ 28 | #define isreserved(s) ((s)->tsv.tt == LUA_TSHRSTR && (s)->tsv.extra > 0) 29 | 30 | 31 | /* 32 | ** equality for short strings, which are always internalized 33 | */ 34 | #define eqshrstr(a,b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b)) 35 | 36 | 37 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 39 | LUAI_FUNC int luaS_eqstr (TString *a, TString *b); 40 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 41 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); 42 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 43 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /lua-5.2.2/src/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h,v 2.16 2011/08/17 20:26:47 roberto Exp $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gkey(n) (&(n)->i_key.tvk) 15 | #define gval(n) (&(n)->i_val) 16 | #define gnext(n) ((n)->i_key.nk.next) 17 | 18 | #define invalidateTMcache(t) ((t)->flags = 0) 19 | 20 | 21 | LUAI_FUNC const TValue *luaH_getint (Table *t, int key); 22 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value); 23 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 24 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 25 | LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); 26 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 27 | LUAI_FUNC Table *luaH_new (lua_State *L); 28 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize); 29 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); 30 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 31 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 32 | LUAI_FUNC int luaH_getn (Table *t); 33 | 34 | 35 | #if defined(LUA_DEBUG) 36 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 37 | LUAI_FUNC int luaH_isdummy (Node *n); 38 | #endif 39 | 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /lua-5.2.2/src/ltablib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltablib.c,v 1.65 2013/03/07 18:17:24 roberto Exp $ 3 | ** Library for Table Manipulation 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define ltablib_c 11 | #define LUA_LIB 12 | 13 | #include "lua.h" 14 | 15 | #include "lauxlib.h" 16 | #include "lualib.h" 17 | 18 | 19 | #define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n)) 20 | 21 | 22 | 23 | #if defined(LUA_COMPAT_MAXN) 24 | static int maxn (lua_State *L) { 25 | lua_Number max = 0; 26 | luaL_checktype(L, 1, LUA_TTABLE); 27 | lua_pushnil(L); /* first key */ 28 | while (lua_next(L, 1)) { 29 | lua_pop(L, 1); /* remove value */ 30 | if (lua_type(L, -1) == LUA_TNUMBER) { 31 | lua_Number v = lua_tonumber(L, -1); 32 | if (v > max) max = v; 33 | } 34 | } 35 | lua_pushnumber(L, max); 36 | return 1; 37 | } 38 | #endif 39 | 40 | 41 | static int tinsert (lua_State *L) { 42 | int e = aux_getn(L, 1) + 1; /* first empty element */ 43 | int pos; /* where to insert new element */ 44 | switch (lua_gettop(L)) { 45 | case 2: { /* called with only 2 arguments */ 46 | pos = e; /* insert new element at the end */ 47 | break; 48 | } 49 | case 3: { 50 | int i; 51 | pos = luaL_checkint(L, 2); /* 2nd argument is the position */ 52 | luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); 53 | for (i = e; i > pos; i--) { /* move up elements */ 54 | lua_rawgeti(L, 1, i-1); 55 | lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ 56 | } 57 | break; 58 | } 59 | default: { 60 | return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); 61 | } 62 | } 63 | lua_rawseti(L, 1, pos); /* t[pos] = v */ 64 | return 0; 65 | } 66 | 67 | 68 | static int tremove (lua_State *L) { 69 | int size = aux_getn(L, 1); 70 | int pos = luaL_optint(L, 2, size); 71 | if (pos != size) /* validate 'pos' if given */ 72 | luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); 73 | lua_rawgeti(L, 1, pos); /* result = t[pos] */ 74 | for ( ; pos < size; pos++) { 75 | lua_rawgeti(L, 1, pos+1); 76 | lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ 77 | } 78 | lua_pushnil(L); 79 | lua_rawseti(L, 1, pos); /* t[pos] = nil */ 80 | return 1; 81 | } 82 | 83 | 84 | static void addfield (lua_State *L, luaL_Buffer *b, int i) { 85 | lua_rawgeti(L, 1, i); 86 | if (!lua_isstring(L, -1)) 87 | luaL_error(L, "invalid value (%s) at index %d in table for " 88 | LUA_QL("concat"), luaL_typename(L, -1), i); 89 | luaL_addvalue(b); 90 | } 91 | 92 | 93 | static int tconcat (lua_State *L) { 94 | luaL_Buffer b; 95 | size_t lsep; 96 | int i, last; 97 | const char *sep = luaL_optlstring(L, 2, "", &lsep); 98 | luaL_checktype(L, 1, LUA_TTABLE); 99 | i = luaL_optint(L, 3, 1); 100 | last = luaL_opt(L, luaL_checkint, 4, luaL_len(L, 1)); 101 | luaL_buffinit(L, &b); 102 | for (; i < last; i++) { 103 | addfield(L, &b, i); 104 | luaL_addlstring(&b, sep, lsep); 105 | } 106 | if (i == last) /* add last value (if interval was not empty) */ 107 | addfield(L, &b, i); 108 | luaL_pushresult(&b); 109 | return 1; 110 | } 111 | 112 | 113 | /* 114 | ** {====================================================== 115 | ** Pack/unpack 116 | ** ======================================================= 117 | */ 118 | 119 | static int pack (lua_State *L) { 120 | int n = lua_gettop(L); /* number of elements to pack */ 121 | lua_createtable(L, n, 1); /* create result table */ 122 | lua_pushinteger(L, n); 123 | lua_setfield(L, -2, "n"); /* t.n = number of elements */ 124 | if (n > 0) { /* at least one element? */ 125 | int i; 126 | lua_pushvalue(L, 1); 127 | lua_rawseti(L, -2, 1); /* insert first element */ 128 | lua_replace(L, 1); /* move table into index 1 */ 129 | for (i = n; i >= 2; i--) /* assign other elements */ 130 | lua_rawseti(L, 1, i); 131 | } 132 | return 1; /* return table */ 133 | } 134 | 135 | 136 | static int unpack (lua_State *L) { 137 | int i, e, n; 138 | luaL_checktype(L, 1, LUA_TTABLE); 139 | i = luaL_optint(L, 2, 1); 140 | e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1)); 141 | if (i > e) return 0; /* empty range */ 142 | n = e - i + 1; /* number of elements */ 143 | if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ 144 | return luaL_error(L, "too many results to unpack"); 145 | lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ 146 | while (i++ < e) /* push arg[i + 1...e] */ 147 | lua_rawgeti(L, 1, i); 148 | return n; 149 | } 150 | 151 | /* }====================================================== */ 152 | 153 | 154 | 155 | /* 156 | ** {====================================================== 157 | ** Quicksort 158 | ** (based on `Algorithms in MODULA-3', Robert Sedgewick; 159 | ** Addison-Wesley, 1993.) 160 | ** ======================================================= 161 | */ 162 | 163 | 164 | static void set2 (lua_State *L, int i, int j) { 165 | lua_rawseti(L, 1, i); 166 | lua_rawseti(L, 1, j); 167 | } 168 | 169 | static int sort_comp (lua_State *L, int a, int b) { 170 | if (!lua_isnil(L, 2)) { /* function? */ 171 | int res; 172 | lua_pushvalue(L, 2); 173 | lua_pushvalue(L, a-1); /* -1 to compensate function */ 174 | lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */ 175 | lua_call(L, 2, 1); 176 | res = lua_toboolean(L, -1); 177 | lua_pop(L, 1); 178 | return res; 179 | } 180 | else /* a < b? */ 181 | return lua_compare(L, a, b, LUA_OPLT); 182 | } 183 | 184 | static void auxsort (lua_State *L, int l, int u) { 185 | while (l < u) { /* for tail recursion */ 186 | int i, j; 187 | /* sort elements a[l], a[(l+u)/2] and a[u] */ 188 | lua_rawgeti(L, 1, l); 189 | lua_rawgeti(L, 1, u); 190 | if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */ 191 | set2(L, l, u); /* swap a[l] - a[u] */ 192 | else 193 | lua_pop(L, 2); 194 | if (u-l == 1) break; /* only 2 elements */ 195 | i = (l+u)/2; 196 | lua_rawgeti(L, 1, i); 197 | lua_rawgeti(L, 1, l); 198 | if (sort_comp(L, -2, -1)) /* a[i]= P */ 217 | while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { 218 | if (i>=u) luaL_error(L, "invalid order function for sorting"); 219 | lua_pop(L, 1); /* remove a[i] */ 220 | } 221 | /* repeat --j until a[j] <= P */ 222 | while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { 223 | if (j<=l) luaL_error(L, "invalid order function for sorting"); 224 | lua_pop(L, 1); /* remove a[j] */ 225 | } 226 | if (j 9 | 10 | #define ltm_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "lobject.h" 16 | #include "lstate.h" 17 | #include "lstring.h" 18 | #include "ltable.h" 19 | #include "ltm.h" 20 | 21 | 22 | static const char udatatypename[] = "userdata"; 23 | 24 | LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { 25 | "no value", 26 | "nil", "boolean", udatatypename, "number", 27 | "string", "table", "function", udatatypename, "thread", 28 | "proto", "upval" /* these last two cases are used for tests only */ 29 | }; 30 | 31 | 32 | void luaT_init (lua_State *L) { 33 | static const char *const luaT_eventname[] = { /* ORDER TM */ 34 | "__index", "__newindex", 35 | "__gc", "__mode", "__len", "__eq", 36 | "__add", "__sub", "__mul", "__div", "__mod", 37 | "__pow", "__unm", "__lt", "__le", 38 | "__concat", "__call" 39 | }; 40 | int i; 41 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); 43 | luaS_fix(G(L)->tmname[i]); /* never collect these names */ 44 | } 45 | } 46 | 47 | 48 | /* 49 | ** function to be used with macro "fasttm": optimized for absence of 50 | ** tag methods 51 | */ 52 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 53 | const TValue *tm = luaH_getstr(events, ename); 54 | lua_assert(event <= TM_EQ); 55 | if (ttisnil(tm)) { /* no tag method? */ 56 | events->flags |= cast_byte(1u<metatable; 68 | break; 69 | case LUA_TUSERDATA: 70 | mt = uvalue(o)->metatable; 71 | break; 72 | default: 73 | mt = G(L)->mt[ttypenv(o)]; 74 | } 75 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); 76 | } 77 | 78 | -------------------------------------------------------------------------------- /lua-5.2.2/src/ltm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.h,v 2.11 2011/02/28 17:32:10 roberto Exp $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltm_h 8 | #define ltm_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | /* 15 | * WARNING: if you change the order of this enumeration, 16 | * grep "ORDER TM" 17 | */ 18 | typedef enum { 19 | TM_INDEX, 20 | TM_NEWINDEX, 21 | TM_GC, 22 | TM_MODE, 23 | TM_LEN, 24 | TM_EQ, /* last tag method with `fast' access */ 25 | TM_ADD, 26 | TM_SUB, 27 | TM_MUL, 28 | TM_DIV, 29 | TM_MOD, 30 | TM_POW, 31 | TM_UNM, 32 | TM_LT, 33 | TM_LE, 34 | TM_CONCAT, 35 | TM_CALL, 36 | TM_N /* number of elements in the enum */ 37 | } TMS; 38 | 39 | 40 | 41 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 42 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) 43 | 44 | #define fasttm(l,et,e) gfasttm(G(l), et, e) 45 | 46 | #define ttypename(x) luaT_typenames_[(x) + 1] 47 | #define objtypename(x) ttypename(ttypenv(x)) 48 | 49 | LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; 50 | 51 | 52 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 53 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 54 | TMS event); 55 | LUAI_FUNC void luaT_init (lua_State *L); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h,v 1.43 2011/12/08 12:11:37 roberto Exp $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | 15 | LUAMOD_API int (luaopen_base) (lua_State *L); 16 | 17 | #define LUA_COLIBNAME "coroutine" 18 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 19 | 20 | #define LUA_TABLIBNAME "table" 21 | LUAMOD_API int (luaopen_table) (lua_State *L); 22 | 23 | #define LUA_IOLIBNAME "io" 24 | LUAMOD_API int (luaopen_io) (lua_State *L); 25 | 26 | #define LUA_OSLIBNAME "os" 27 | LUAMOD_API int (luaopen_os) (lua_State *L); 28 | 29 | #define LUA_STRLIBNAME "string" 30 | LUAMOD_API int (luaopen_string) (lua_State *L); 31 | 32 | #define LUA_BITLIBNAME "bit32" 33 | LUAMOD_API int (luaopen_bit32) (lua_State *L); 34 | 35 | #define LUA_MATHLIBNAME "math" 36 | LUAMOD_API int (luaopen_math) (lua_State *L); 37 | 38 | #define LUA_DBLIBNAME "debug" 39 | LUAMOD_API int (luaopen_debug) (lua_State *L); 40 | 41 | #define LUA_LOADLIBNAME "package" 42 | LUAMOD_API int (luaopen_package) (lua_State *L); 43 | 44 | 45 | /* open all previous libraries */ 46 | LUALIB_API void (luaL_openlibs) (lua_State *L); 47 | 48 | 49 | 50 | #if !defined(lua_assert) 51 | #define lua_assert(x) ((void)0) 52 | #endif 53 | 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lundump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.c,v 2.22 2012/05/08 13:53:33 roberto Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #include 8 | 9 | #define lundump_c 10 | #define LUA_CORE 11 | 12 | #include "lua.h" 13 | 14 | #include "ldebug.h" 15 | #include "ldo.h" 16 | #include "lfunc.h" 17 | #include "lmem.h" 18 | #include "lobject.h" 19 | #include "lstring.h" 20 | #include "lundump.h" 21 | #include "lzio.h" 22 | 23 | typedef struct { 24 | lua_State* L; 25 | ZIO* Z; 26 | Mbuffer* b; 27 | const char* name; 28 | } LoadState; 29 | 30 | static l_noret error(LoadState* S, const char* why) 31 | { 32 | luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why); 33 | luaD_throw(S->L,LUA_ERRSYNTAX); 34 | } 35 | 36 | #define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) 37 | #define LoadByte(S) (lu_byte)LoadChar(S) 38 | #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) 39 | #define LoadVector(S,b,n,size) LoadMem(S,b,n,size) 40 | 41 | #if !defined(luai_verifycode) 42 | #define luai_verifycode(L,b,f) /* empty */ 43 | #endif 44 | 45 | static void LoadBlock(LoadState* S, void* b, size_t size) 46 | { 47 | if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated"); 48 | } 49 | 50 | static int LoadChar(LoadState* S) 51 | { 52 | char x; 53 | LoadVar(S,x); 54 | return x; 55 | } 56 | 57 | static int LoadInt(LoadState* S) 58 | { 59 | int x; 60 | LoadVar(S,x); 61 | if (x<0) error(S,"corrupted"); 62 | return x; 63 | } 64 | 65 | static lua_Number LoadNumber(LoadState* S) 66 | { 67 | lua_Number x; 68 | LoadVar(S,x); 69 | return x; 70 | } 71 | 72 | static TString* LoadString(LoadState* S) 73 | { 74 | size_t size; 75 | LoadVar(S,size); 76 | if (size==0) 77 | return NULL; 78 | else 79 | { 80 | char* s=luaZ_openspace(S->L,S->b,size); 81 | LoadBlock(S,s,size*sizeof(char)); 82 | return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ 83 | } 84 | } 85 | 86 | static void LoadCode(LoadState* S, Proto* f) 87 | { 88 | int n=LoadInt(S); 89 | f->code=luaM_newvector(S->L,n,Instruction); 90 | f->sizecode=n; 91 | LoadVector(S,f->code,n,sizeof(Instruction)); 92 | } 93 | 94 | static void LoadFunction(LoadState* S, Proto* f); 95 | 96 | static void LoadConstants(LoadState* S, Proto* f) 97 | { 98 | int i,n; 99 | n=LoadInt(S); 100 | f->k=luaM_newvector(S->L,n,TValue); 101 | f->sizek=n; 102 | for (i=0; ik[i]); 103 | for (i=0; ik[i]; 106 | int t=LoadChar(S); 107 | switch (t) 108 | { 109 | case LUA_TNIL: 110 | setnilvalue(o); 111 | break; 112 | case LUA_TBOOLEAN: 113 | setbvalue(o,LoadChar(S)); 114 | break; 115 | case LUA_TNUMBER: 116 | setnvalue(o,LoadNumber(S)); 117 | break; 118 | case LUA_TSTRING: 119 | setsvalue2n(S->L,o,LoadString(S)); 120 | break; 121 | default: lua_assert(0); 122 | } 123 | } 124 | n=LoadInt(S); 125 | f->p=luaM_newvector(S->L,n,Proto*); 126 | f->sizep=n; 127 | for (i=0; ip[i]=NULL; 128 | for (i=0; ip[i]=luaF_newproto(S->L); 131 | LoadFunction(S,f->p[i]); 132 | } 133 | } 134 | 135 | static void LoadUpvalues(LoadState* S, Proto* f) 136 | { 137 | int i,n; 138 | n=LoadInt(S); 139 | f->upvalues=luaM_newvector(S->L,n,Upvaldesc); 140 | f->sizeupvalues=n; 141 | for (i=0; iupvalues[i].name=NULL; 142 | for (i=0; iupvalues[i].instack=LoadByte(S); 145 | f->upvalues[i].idx=LoadByte(S); 146 | } 147 | } 148 | 149 | static void LoadDebug(LoadState* S, Proto* f) 150 | { 151 | int i,n; 152 | f->source=LoadString(S); 153 | n=LoadInt(S); 154 | f->lineinfo=luaM_newvector(S->L,n,int); 155 | f->sizelineinfo=n; 156 | LoadVector(S,f->lineinfo,n,sizeof(int)); 157 | n=LoadInt(S); 158 | f->locvars=luaM_newvector(S->L,n,LocVar); 159 | f->sizelocvars=n; 160 | for (i=0; ilocvars[i].varname=NULL; 161 | for (i=0; ilocvars[i].varname=LoadString(S); 164 | f->locvars[i].startpc=LoadInt(S); 165 | f->locvars[i].endpc=LoadInt(S); 166 | } 167 | n=LoadInt(S); 168 | for (i=0; iupvalues[i].name=LoadString(S); 169 | } 170 | 171 | static void LoadFunction(LoadState* S, Proto* f) 172 | { 173 | f->linedefined=LoadInt(S); 174 | f->lastlinedefined=LoadInt(S); 175 | f->numparams=LoadByte(S); 176 | f->is_vararg=LoadByte(S); 177 | f->maxstacksize=LoadByte(S); 178 | LoadCode(S,f); 179 | LoadConstants(S,f); 180 | LoadUpvalues(S,f); 181 | LoadDebug(S,f); 182 | } 183 | 184 | /* the code below must be consistent with the code in luaU_header */ 185 | #define N0 LUAC_HEADERSIZE 186 | #define N1 (sizeof(LUA_SIGNATURE)-sizeof(char)) 187 | #define N2 N1+2 188 | #define N3 N2+6 189 | 190 | static void LoadHeader(LoadState* S) 191 | { 192 | lu_byte h[LUAC_HEADERSIZE]; 193 | lu_byte s[LUAC_HEADERSIZE]; 194 | luaU_header(h); 195 | memcpy(s,h,sizeof(char)); /* first char already read */ 196 | LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char)); 197 | if (memcmp(h,s,N0)==0) return; 198 | if (memcmp(h,s,N1)!=0) error(S,"not a"); 199 | if (memcmp(h,s,N2)!=0) error(S,"version mismatch in"); 200 | if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted"); 201 | } 202 | 203 | /* 204 | ** load precompiled chunk 205 | */ 206 | Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) 207 | { 208 | LoadState S; 209 | Closure* cl; 210 | if (*name=='@' || *name=='=') 211 | S.name=name+1; 212 | else if (*name==LUA_SIGNATURE[0]) 213 | S.name="binary string"; 214 | else 215 | S.name=name; 216 | S.L=L; 217 | S.Z=Z; 218 | S.b=buff; 219 | LoadHeader(&S); 220 | cl=luaF_newLclosure(L,1); 221 | setclLvalue(L,L->top,cl); incr_top(L); 222 | cl->l.p=luaF_newproto(L); 223 | LoadFunction(&S,cl->l.p); 224 | if (cl->l.p->sizeupvalues != 1) 225 | { 226 | Proto* p=cl->l.p; 227 | cl=luaF_newLclosure(L,cl->l.p->sizeupvalues); 228 | cl->l.p=p; 229 | setclLvalue(L,L->top-1,cl); 230 | } 231 | luai_verifycode(L,buff,cl->l.p); 232 | return cl; 233 | } 234 | 235 | #define MYINT(s) (s[0]-'0') 236 | #define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR) 237 | #define FORMAT 0 /* this is the official format */ 238 | 239 | /* 240 | * make header for precompiled chunks 241 | * if you change the code below be sure to update LoadHeader and FORMAT above 242 | * and LUAC_HEADERSIZE in lundump.h 243 | */ 244 | void luaU_header (lu_byte* h) 245 | { 246 | int x=1; 247 | memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char)); 248 | h+=sizeof(LUA_SIGNATURE)-sizeof(char); 249 | *h++=cast_byte(VERSION); 250 | *h++=cast_byte(FORMAT); 251 | *h++=cast_byte(*(char*)&x); /* endianness */ 252 | *h++=cast_byte(sizeof(int)); 253 | *h++=cast_byte(sizeof(size_t)); 254 | *h++=cast_byte(sizeof(Instruction)); 255 | *h++=cast_byte(sizeof(lua_Number)); 256 | *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */ 257 | memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char)); 258 | } 259 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h,v 1.39 2012/05/08 13:53:33 roberto Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "lobject.h" 11 | #include "lzio.h" 12 | 13 | /* load one chunk; from lundump.c */ 14 | LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); 15 | 16 | /* make header; from lundump.c */ 17 | LUAI_FUNC void luaU_header (lu_byte* h); 18 | 19 | /* dump one chunk; from ldump.c */ 20 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); 21 | 22 | /* data to catch conversion errors */ 23 | #define LUAC_TAIL "\x19\x93\r\n\x1a\n" 24 | 25 | /* size in bytes of header of binary files */ 26 | #define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char)) 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lvm.h,v 2.18 2013/01/08 14:06:55 roberto Exp $ 3 | ** Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lvm_h 8 | #define lvm_h 9 | 10 | 11 | #include "ldo.h" 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | 15 | 16 | #define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o))) 17 | 18 | #define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL)) 19 | 20 | #define equalobj(L,o1,o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2)) 21 | 22 | #define luaV_rawequalobj(o1,o2) equalobj(NULL,o1,o2) 23 | 24 | 25 | /* not to called directly */ 26 | LUAI_FUNC int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2); 27 | 28 | 29 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 30 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); 31 | LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); 32 | LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); 33 | LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, 34 | StkId val); 35 | LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, 36 | StkId val); 37 | LUAI_FUNC void luaV_finishOp (lua_State *L); 38 | LUAI_FUNC void luaV_execute (lua_State *L); 39 | LUAI_FUNC void luaV_concat (lua_State *L, int total); 40 | LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb, 41 | const TValue *rc, TMS op); 42 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c,v 1.35 2012/05/14 13:34:18 roberto Exp $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #include 9 | 10 | #define lzio_c 11 | #define LUA_CORE 12 | 13 | #include "lua.h" 14 | 15 | #include "llimits.h" 16 | #include "lmem.h" 17 | #include "lstate.h" 18 | #include "lzio.h" 19 | 20 | 21 | int luaZ_fill (ZIO *z) { 22 | size_t size; 23 | lua_State *L = z->L; 24 | const char *buff; 25 | lua_unlock(L); 26 | buff = z->reader(L, z->data, &size); 27 | lua_lock(L); 28 | if (buff == NULL || size == 0) 29 | return EOZ; 30 | z->n = size - 1; /* discount char being returned */ 31 | z->p = buff; 32 | return cast_uchar(*(z->p++)); 33 | } 34 | 35 | 36 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 37 | z->L = L; 38 | z->reader = reader; 39 | z->data = data; 40 | z->n = 0; 41 | z->p = NULL; 42 | } 43 | 44 | 45 | /* --------------------------------------------------------------- read --- */ 46 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 47 | while (n) { 48 | size_t m; 49 | if (z->n == 0) { /* no bytes in buffer? */ 50 | if (luaZ_fill(z) == EOZ) /* try to read more */ 51 | return n; /* no more input; return number of missing bytes */ 52 | else { 53 | z->n++; /* luaZ_fill consumed first byte; put it back */ 54 | z->p--; 55 | } 56 | } 57 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 58 | memcpy(b, z->p, m); 59 | z->n -= m; 60 | z->p += m; 61 | b = (char *)b + m; 62 | n -= m; 63 | } 64 | return 0; 65 | } 66 | 67 | /* ------------------------------------------------------------------------ */ 68 | char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { 69 | if (n > buff->buffsize) { 70 | if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; 71 | luaZ_resizebuffer(L, buff, n); 72 | } 73 | return buff->buffer; 74 | } 75 | 76 | 77 | -------------------------------------------------------------------------------- /lua-5.2.2/src/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h,v 1.26 2011/07/15 12:48:03 roberto Exp $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 36 | 37 | 38 | #define luaZ_resizebuffer(L, buff, size) \ 39 | (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ 40 | (buff)->buffsize = size) 41 | 42 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 43 | 44 | 45 | LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); 46 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 47 | void *data); 48 | LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ 49 | 50 | 51 | 52 | /* --------- Private Part ------------------ */ 53 | 54 | struct Zio { 55 | size_t n; /* bytes still unread */ 56 | const char *p; /* current position in buffer */ 57 | lua_Reader reader; /* reader function */ 58 | void* data; /* additional data */ 59 | lua_State *L; /* Lua state (for reader) */ 60 | }; 61 | 62 | 63 | LUAI_FUNC int luaZ_fill (ZIO *z); 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /material.c: -------------------------------------------------------------------------------- 1 | #include "mio.h" 2 | 3 | int load_material(char *dirname, char *material) 4 | { 5 | char filename[1024], *s; 6 | int texture; 7 | s = strrchr(material, ';'); 8 | if (s) s++; else s = material; 9 | if (dirname[0]) { 10 | strlcpy(filename, dirname, sizeof filename); 11 | strlcat(filename, "/textures/", sizeof filename); 12 | strlcat(filename, s, sizeof filename); 13 | strlcat(filename, ".png", sizeof filename); 14 | } else { 15 | strlcpy(filename, "textures/", sizeof filename); 16 | strlcat(filename, s, sizeof filename); 17 | strlcat(filename, ".png", sizeof filename); 18 | } 19 | texture = load_texture(filename, 1); 20 | if (strstr(material, "clamp;")) { 21 | glBindTexture(GL_TEXTURE_2D, texture); 22 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 23 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 24 | } 25 | return texture; 26 | } 27 | -------------------------------------------------------------------------------- /model.c: -------------------------------------------------------------------------------- 1 | #include "mio.h" 2 | 3 | struct { 4 | const char *suffix; 5 | struct model *(*load)(const char *filename, unsigned char *data, int len); 6 | } formats[] = { 7 | { ".iqm", load_iqm_from_memory }, 8 | { ".iqe", load_iqe_from_memory }, 9 | { ".obj", load_obj_from_memory }, 10 | }; 11 | 12 | static struct cache *model_cache = NULL; 13 | 14 | struct model *load_model(const char *name) 15 | { 16 | char filename[1024]; 17 | unsigned char *data = NULL; 18 | struct model *model; 19 | int i, len; 20 | 21 | model = lookup(model_cache, name); 22 | if (model) 23 | return model; 24 | 25 | for (i = 0; i < nelem(formats); i++) { 26 | strlcpy(filename, name, sizeof filename); 27 | strlcat(filename, formats[i].suffix, sizeof filename); 28 | data = load_file(filename, &len); 29 | if (data) 30 | break; 31 | } 32 | 33 | if (!data) { 34 | warn("error: cannot find model: '%s'", name); 35 | return NULL; 36 | } 37 | 38 | model = formats[i].load(filename, data, len); 39 | if (!model) 40 | warn("error: cannot load model: '%s'", filename); 41 | 42 | free(data); 43 | 44 | if (model) 45 | model_cache = insert(model_cache, name, model); 46 | 47 | if (model && model->anim) { 48 | struct anim *anim = model->anim; 49 | struct pose a_from_org, b_from_org; 50 | vec4 org_from_a; 51 | extract_frame_root(&a_from_org, anim, 0); 52 | extract_frame_root(&b_from_org, anim, anim->frames - 1); 53 | vec_sub(anim->motion.position, b_from_org.position, a_from_org.position); 54 | quat_conjugate(org_from_a, a_from_org.rotation); 55 | quat_mul(anim->motion.rotation, b_from_org.rotation, org_from_a); 56 | vec_div(anim->motion.scale, b_from_org.scale, a_from_org.scale); 57 | } 58 | 59 | return model; 60 | } 61 | 62 | struct skel *load_skel(const char *filename) 63 | { 64 | struct model *model = load_model(filename); 65 | if (model) 66 | return model->skel; 67 | return NULL; 68 | } 69 | 70 | struct mesh *load_mesh(const char *filename) 71 | { 72 | struct model *model = load_model(filename); 73 | if (model) 74 | return model->mesh; 75 | return NULL; 76 | } 77 | 78 | struct anim *load_anim(const char *filename) 79 | { 80 | struct model *model = load_model(filename); 81 | if (model) 82 | return model->anim; 83 | return NULL; 84 | } 85 | 86 | void extract_raw_frame_root(struct pose *pose, struct anim *anim, int frame) 87 | { 88 | float *s = anim->data + anim->channels * frame; 89 | int mask = anim->mask[0]; 90 | *pose = anim->pose[0]; 91 | if (mask & 0x01) pose->position[0] = *s++; 92 | if (mask & 0x02) pose->position[1] = *s++; 93 | if (mask & 0x04) pose->position[2] = *s++; 94 | if (mask & 0x08) pose->rotation[0] = *s++; 95 | if (mask & 0x10) pose->rotation[1] = *s++; 96 | if (mask & 0x20) pose->rotation[2] = *s++; 97 | if (mask & 0x40) pose->rotation[3] = *s++; 98 | if (mask & 0x80) pose->scale[0] = *s++; 99 | if (mask & 0x100) pose->scale[1] = *s++; 100 | if (mask & 0x200) pose->scale[2] = *s++; 101 | } 102 | 103 | void extract_raw_frame(struct pose *pose, struct anim *anim, int frame) 104 | { 105 | float *s = anim->data + anim->channels * frame; 106 | int i; 107 | for (i = 0; i < anim->skel->count; i++) { 108 | int mask = anim->mask[i]; 109 | pose[i] = anim->pose[i]; 110 | if (mask & 0x01) pose[i].position[0] = *s++; 111 | if (mask & 0x02) pose[i].position[1] = *s++; 112 | if (mask & 0x04) pose[i].position[2] = *s++; 113 | if (mask & 0x08) pose[i].rotation[0] = *s++; 114 | if (mask & 0x10) pose[i].rotation[1] = *s++; 115 | if (mask & 0x20) pose[i].rotation[2] = *s++; 116 | if (mask & 0x40) pose[i].rotation[3] = *s++; 117 | if (mask & 0x80) pose[i].scale[0] = *s++; 118 | if (mask & 0x100) pose[i].scale[1] = *s++; 119 | if (mask & 0x200) pose[i].scale[2] = *s++; 120 | } 121 | } 122 | 123 | void lerp_frame(struct pose *out, struct pose *a, struct pose *b, float t, int n) 124 | { 125 | int i; 126 | for (i = 0; i < n; i++) { 127 | vec_lerp(out[i].position, a[i].position, b[i].position, t); 128 | quat_lerp_neighbor_normalize(out[i].rotation, a[i].rotation, b[i].rotation, t); 129 | vec_lerp(out[i].scale, a[i].scale, b[i].scale, t); 130 | } 131 | } 132 | 133 | void extract_frame_root(struct pose *pose, struct anim *anim, float frame) 134 | { 135 | int frame0 = frame; 136 | int frame1 = frame0 + 1; 137 | if (frame <= 0) { 138 | extract_raw_frame_root(pose, anim, 0); 139 | return; 140 | } 141 | if (frame1 >= anim->frames) { 142 | extract_raw_frame_root(pose, anim, anim->frames - 1); 143 | return; 144 | } 145 | float t = frame - floorf(frame); 146 | struct pose a, b; 147 | extract_raw_frame_root(&a, anim, frame0); 148 | extract_raw_frame_root(&b, anim, frame1); 149 | lerp_frame(pose, &a, &b, t, 1); 150 | } 151 | 152 | void extract_frame(struct pose *pose, struct anim *anim, float frame) 153 | { 154 | int frame0 = frame; 155 | int frame1 = frame0 + 1; 156 | if (frame <= 0) { 157 | extract_raw_frame(pose, anim, 0); 158 | return; 159 | } 160 | if (frame1 >= anim->frames) { 161 | extract_raw_frame(pose, anim, anim->frames - 1); 162 | return; 163 | } 164 | float t = frame - floorf(frame); 165 | struct pose a[MAXBONE], b[MAXBONE]; 166 | extract_raw_frame(a, anim, frame0); 167 | extract_raw_frame(b, anim, frame1); 168 | lerp_frame(pose, a, b, t, anim->skel->count); 169 | } 170 | 171 | static int haschildren(int *parent, int count, int x) 172 | { 173 | int i; 174 | for (i = x; i < count; i++) 175 | if (parent[i] == x) 176 | return 1; 177 | return 0; 178 | } 179 | 180 | void draw_skel(mat4 *abs_pose_matrix, int *parent, int count) 181 | { 182 | vec3 x = { 0.1, 0, 0 }; 183 | int i; 184 | for (i = 0; i < count; i++) { 185 | float *a = abs_pose_matrix[i]; 186 | if (parent[i] >= 0) { 187 | float *b = abs_pose_matrix[parent[i]]; 188 | draw_line(a[12], a[13], a[14], b[12], b[13], b[14]); 189 | } else { 190 | draw_line(a[12], a[13], a[14], 0, 0, 0); 191 | } 192 | if (!haschildren(parent, count, i)) { 193 | vec3 b; 194 | mat_vec_mul(b, abs_pose_matrix[i], x); 195 | draw_line(a[12], a[13], a[14], b[0], b[1], b[2]); 196 | } 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /proxy.lua: -------------------------------------------------------------------------------- 1 | local table_unpack = table.unpack 2 | local table_insert = table.insert 3 | 4 | local meshlist = {} 5 | local lamplist = {} 6 | 7 | entities = {} 8 | actions = {} 9 | 10 | function playonce(skel, anim) 11 | local frame = 0 12 | local n = anim_len(anim) 13 | while frame < n do 14 | skel:animate(anim, frame, 1) 15 | coroutine.yield() 16 | frame = frame + 1 17 | end 18 | end 19 | 20 | mixer = 0 21 | 22 | function playmix2(skel, a, b) 23 | local a_i, a_n = 0, anim_len(a) 24 | local b_i, b_n = 0, anim_len(b) 25 | local a_step = a_n / b_n 26 | while true do 27 | skel:animate(a, a_i, 1) 28 | skel:animate(b, b_i, mixer) 29 | coroutine.yield() 30 | a_i = a_i + a_step 31 | b_i = b_i + 1 32 | if a_i >= a_n then a_i = a_i - a_n end 33 | if b_i >= b_n then b_i = b_i - b_n end 34 | end 35 | end 36 | 37 | function playmix(skel, a, b, duration) 38 | local a_i, a_n = 0, anim_len(a) 39 | local b_i, b_n = 0, anim_len(b) 40 | local a_step = a_n / b_n 41 | local i = 0 42 | print("mix", a_n, b_n, a_step) 43 | for i = 0, duration-1 do 44 | skel:animate(a, a_i, 1) 45 | skel:animate(b, b_i, (i / duration)) 46 | coroutine.yield() 47 | a_i = a_i + a_step 48 | b_i = b_i + 1 49 | if a_i >= a_n then a_i = a_i - a_n end 50 | if b_i >= b_n then b_i = b_i - b_n end 51 | i = i + 1 52 | end 53 | while true do 54 | skel:animate(b, b_i, 1) 55 | coroutine.yield() 56 | b_i = b_i + 1 57 | if b_i >= b_n then b_i = b_i - b_n end 58 | end 59 | end 60 | 61 | function playseq(skel, list) 62 | while true do 63 | for i, anim in ipairs(list) do 64 | playonce(skel, anim) 65 | end 66 | end 67 | end 68 | 69 | function playloop(skel, anim, frame) 70 | local n = anim_len(anim) 71 | while true do 72 | skel:animate(anim, frame, 1) 73 | coroutine.yield() 74 | frame = frame + 1 75 | if frame >= n then 76 | frame = frame - n 77 | end 78 | end 79 | end 80 | 81 | function run(f) 82 | table.insert(actions, coroutine.wrap(f)) 83 | end 84 | 85 | function update() 86 | for k, action in pairs(actions) do 87 | action() 88 | end 89 | 90 | for k, ent in pairs(meshlist) do 91 | if ent.transform then 92 | if ent.parent then 93 | if ent.parentbone then 94 | update_transform_parent_skel(ent.transform, ent.parent.transform, ent.parent.skel, ent.parentbone) 95 | else 96 | update_transform_parent(ent.transform, ent.parent.transform) 97 | end 98 | else 99 | update_transform(ent.transform) 100 | end 101 | end 102 | end 103 | end 104 | 105 | function draw_geometry() 106 | for k, ent in pairs(meshlist) do 107 | if ent.skel then 108 | if ent.mesh then 109 | draw_mesh_skel(ent.transform, ent.mesh, ent.skel) 110 | end 111 | if ent.meshlist then 112 | for i, mesh in pairs(ent.meshlist) do 113 | draw_mesh_skel(ent.transform, mesh, ent.skel) 114 | end 115 | end 116 | else 117 | if ent.mesh then 118 | draw_mesh(ent.transform, ent.mesh) 119 | end 120 | if ent.meshlist then 121 | for i, mesh in pairs(ent.meshlist) do 122 | draw_mesh(ent.transform, mesh) 123 | end 124 | end 125 | end 126 | end 127 | end 128 | 129 | function draw_light() 130 | for k, ent in pairs(lamplist) do 131 | if ent.lamp then 132 | draw_lamp(ent.transform, ent.lamp) 133 | end 134 | end 135 | end 136 | 137 | function new_transform(t) 138 | local tra = new_transform_imp() 139 | if t then 140 | if t.position then tra:set_position(table_unpack(t.position)) end 141 | if t.rotation then tra:set_rotation(table_unpack(t.rotation)) end 142 | if t.scale then tra:set_scale(table_unpack(t.scale)) end 143 | end 144 | return tra 145 | end 146 | 147 | function new_lamp(t) 148 | local lamp = new_lamp_imp() 149 | if t then 150 | if t.type then lamp:set_type(t.type) end 151 | if t.energy then lamp:set_energy(t.energy) end 152 | if t.color then lamp:set_color(table_unpack(t.color)) end 153 | if t.distance then lamp:set_distance(t.distance) end 154 | if t.spot_angle then lamp:set_spot_angle(t.spot_angle) end 155 | if t.spot_blend then lamp:set_spot_blend(t.spot_blend) end 156 | if type(t.use_sphere) == 'boolean' then lamp:set_use_sphere(t.use_sphere) end 157 | if type(t.use_shadow) == 'boolean' then lamp:set_use_shadow(t.use_shadow) end 158 | end 159 | return lamp 160 | end 161 | 162 | function new_meshlist(list) 163 | for k, filename in pairs(list) do 164 | list[k] = new_mesh(filename) 165 | end 166 | return list 167 | end 168 | 169 | function entity(t) 170 | if t.name then 171 | entities[t.name] = t 172 | end 173 | 174 | t.transform = new_transform(t.transform) 175 | 176 | if t.lamp then t.lamp = new_lamp(t.lamp) end 177 | if t.skel then t.skel = new_skel(t.skel) end 178 | if t.mesh then t.mesh = new_mesh(t.mesh) end 179 | if t.meshlist then t.meshlist = new_meshlist(t.meshlist) end 180 | 181 | if t.mesh or t.meshlist then table_insert(meshlist, t) end 182 | if t.lamp then table_insert(lamplist, t) end 183 | 184 | return t 185 | end 186 | -------------------------------------------------------------------------------- /repr.lua: -------------------------------------------------------------------------------- 1 | -- Simple tostring replacement that will also print table contents. 2 | 3 | local tostring_old = tostring 4 | 5 | local keywords = { 6 | ["and"] = true, 7 | ["break"] = true, 8 | ["do"] = true, 9 | ["else"] = true, 10 | ["elseif"] = true, 11 | ["end"] = true, 12 | ["false"] = true, 13 | ["for"] = true, 14 | ["function"] = true, 15 | ["if"] = true, 16 | ["in"] = true, 17 | ["local"] = true, 18 | ["nil"] = true, 19 | ["not"] = true, 20 | ["or"] = true, 21 | ["repeat"] = true, 22 | ["return"] = true, 23 | ["then"] = true, 24 | ["true"] = true, 25 | ["until"] = true, 26 | ["while"] = true 27 | } 28 | 29 | local function tostring_imp(x, cat, seen) 30 | if type(x) == 'table' and not seen[x] then 31 | seen[x] = true 32 | cat("{") 33 | local last_i = 0 34 | for i, v in ipairs(x) do 35 | if i > 1 then cat(", ") end 36 | tostring_imp(v, cat, seen) 37 | last_i = i 38 | end 39 | local needs_comma = last_i > 0 40 | for k, v in pairs(x) do 41 | if type(k) ~= 'number' or k < 1 or k > last_i or k % 1 ~= 0 then 42 | if needs_comma then cat(", ") else needs_comma = true end 43 | if type(k) == 'string' and not keywords[k] and string.match(k, "^[%a_][%a%d_]*$") then 44 | cat(k) cat("=") 45 | else 46 | cat("[") tostring_imp(k, cat, seen) cat("]=") 47 | end 48 | tostring_imp(v, cat, seen) 49 | end 50 | end 51 | cat("}") 52 | seen[x] = nil 53 | elseif type(x) == 'string' then 54 | cat(string.format("%q", x)) 55 | elseif type(x) == 'number' or type(x) == 'boolean' or x == nil then 56 | cat(tostring_old(x)) 57 | else 58 | cat("<") cat(tostring_old(x)) cat(">") 59 | end 60 | end 61 | 62 | function tostring(x) 63 | local buf = {} 64 | tostring_imp(x, function(v) buf[#buf+1] = v end, {}) 65 | return table.concat(buf) 66 | end 67 | 68 | function printf(...) print(string.format(...)) end 69 | -------------------------------------------------------------------------------- /rune.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The authors of this software are Rob Pike and Ken Thompson. 3 | * Copyright (c) 2002 by Lucent Technologies. 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose without fee is hereby granted, provided that this entire notice 6 | * is included in all copies of any software which is or includes a copy 7 | * or modification of this software and in all copies of the supporting 8 | * documentation for such software. 9 | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 10 | * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE 11 | * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY 12 | * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. 13 | */ 14 | 15 | typedef int Rune; /* 32 bits */ 16 | 17 | enum 18 | { 19 | UTFmax = 4, /* maximum bytes per rune */ 20 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ 21 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ 22 | Runeerror = 0xFFFD, /* decoding error in UTF */ 23 | Runemax = 0x10FFFF /* maximum rune value */ 24 | }; 25 | 26 | typedef unsigned char uchar; 27 | 28 | enum 29 | { 30 | Bit1 = 7, 31 | Bitx = 6, 32 | Bit2 = 5, 33 | Bit3 = 4, 34 | Bit4 = 3, 35 | Bit5 = 2, 36 | 37 | T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */ 38 | Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */ 39 | T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */ 40 | T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */ 41 | T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */ 42 | T5 = ((1<<(Bit5+1))-1) ^ 0xFF, /* 1111 1000 */ 43 | 44 | Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0000 0000 0111 1111 */ 45 | Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0000 0000 0111 1111 1111 */ 46 | Rune3 = (1<<(Bit3+2*Bitx))-1, /* 0000 0000 1111 1111 1111 1111 */ 47 | Rune4 = (1<<(Bit4+3*Bitx))-1, /* 0011 1111 1111 1111 1111 1111 */ 48 | 49 | Maskx = (1< T1 64 | */ 65 | c = *(uchar*)str; 66 | if(c < Tx) { 67 | *rune = c; 68 | return 1; 69 | } 70 | 71 | /* 72 | * two character sequence 73 | * 0080-07FF => T2 Tx 74 | */ 75 | c1 = *(uchar*)(str+1) ^ Tx; 76 | if(c1 & Testx) 77 | goto bad; 78 | if(c < T3) { 79 | if(c < T2) 80 | goto bad; 81 | l = ((c << Bitx) | c1) & Rune2; 82 | if(l <= Rune1) 83 | goto bad; 84 | *rune = l; 85 | return 2; 86 | } 87 | 88 | /* 89 | * three character sequence 90 | * 0800-FFFF => T3 Tx Tx 91 | */ 92 | c2 = *(uchar*)(str+2) ^ Tx; 93 | if(c2 & Testx) 94 | goto bad; 95 | if(c < T4) { 96 | l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3; 97 | if(l <= Rune2) 98 | goto bad; 99 | *rune = l; 100 | return 3; 101 | } 102 | 103 | /* 104 | * four character sequence 105 | * 10000-10FFFF => T4 Tx Tx Tx 106 | */ 107 | if(UTFmax >= 4) { 108 | c3 = *(uchar*)(str+3) ^ Tx; 109 | if(c3 & Testx) 110 | goto bad; 111 | if(c < T5) { 112 | l = ((((((c << Bitx) | c1) << Bitx) | c2) << Bitx) | c3) & Rune4; 113 | if(l <= Rune3) 114 | goto bad; 115 | if(l > Runemax) 116 | goto bad; 117 | *rune = l; 118 | return 4; 119 | } 120 | } 121 | 122 | /* 123 | * bad decoding 124 | */ 125 | bad: 126 | *rune = Bad; 127 | return 1; 128 | } 129 | 130 | int 131 | runetochar(char *str, Rune *rune) 132 | { 133 | long c; 134 | 135 | /* 136 | * one character sequence 137 | * 00000-0007F => 00-7F 138 | */ 139 | c = *rune; 140 | if(c <= Rune1) { 141 | str[0] = c; 142 | return 1; 143 | } 144 | 145 | /* 146 | * two character sequence 147 | * 00080-007FF => T2 Tx 148 | */ 149 | if(c <= Rune2) { 150 | str[0] = T2 | (c >> 1*Bitx); 151 | str[1] = Tx | (c & Maskx); 152 | return 2; 153 | } 154 | 155 | /* 156 | * three character sequence 157 | * 00800-0FFFF => T3 Tx Tx 158 | */ 159 | if(c > Runemax) 160 | c = Runeerror; 161 | if(c <= Rune3) { 162 | str[0] = T3 | (c >> 2*Bitx); 163 | str[1] = Tx | ((c >> 1*Bitx) & Maskx); 164 | str[2] = Tx | (c & Maskx); 165 | return 3; 166 | } 167 | 168 | /* 169 | * four character sequence 170 | * 010000-1FFFFF => T4 Tx Tx Tx 171 | */ 172 | str[0] = T4 | (c >> 3*Bitx); 173 | str[1] = Tx | ((c >> 2*Bitx) & Maskx); 174 | str[2] = Tx | ((c >> 1*Bitx) & Maskx); 175 | str[3] = Tx | (c & Maskx); 176 | return 4; 177 | } 178 | -------------------------------------------------------------------------------- /scene.c: -------------------------------------------------------------------------------- 1 | #include "mio.h" 2 | 3 | static int find_bone(struct skel *skel, const char *name) 4 | { 5 | int i; 6 | for (i = 0; i < skel->count; i++) 7 | if (!strcmp(skel->name[i], name)) 8 | return i; 9 | return -1; 10 | } 11 | 12 | void pose_lerp(struct pose *p, const struct pose *a, const struct pose *b, float t) 13 | { 14 | vec_lerp(p->position, a->position, b->position, t); 15 | quat_lerp_neighbor_normalize(p->rotation, a->rotation, b->rotation, t); 16 | vec_lerp(p->scale, a->scale, b->scale, t); 17 | } 18 | 19 | void init_transform(struct transform *trafo) 20 | { 21 | vec_init(trafo->position, 0, 0, 0); 22 | quat_init(trafo->rotation, 0, 0, 0, 1); 23 | vec_init(trafo->scale, 1, 1, 1); 24 | mat_identity(trafo->matrix); 25 | } 26 | 27 | void init_skelpose(struct skelpose *skelpose, struct skel *skel) 28 | { 29 | int i; 30 | skelpose->skel = skel; 31 | for (i = 0; i < skel->count; i++) 32 | skelpose->pose[i] = skel->pose[i]; 33 | } 34 | 35 | void init_lamp(struct lamp *lamp) 36 | { 37 | lamp->type = LAMP_POINT; 38 | vec_init(lamp->color, 1, 1, 1); 39 | lamp->energy = 1; 40 | lamp->distance = 25; 41 | lamp->spot_angle = 45; 42 | } 43 | 44 | void update_transform(struct transform *transform) 45 | { 46 | mat_from_pose(transform->matrix, transform->position, transform->rotation, transform->scale); 47 | } 48 | 49 | void update_transform_parent(struct transform *transform, struct transform *parent) 50 | { 51 | mat4 local_matrix; 52 | mat_from_pose(local_matrix, transform->position, transform->rotation, transform->scale); 53 | mat_mul44(transform->matrix, parent->matrix, local_matrix); 54 | } 55 | 56 | void calc_pose(mat4 out, struct skel *skel, struct pose *pose, int bone) 57 | { 58 | int parent = skel->parent[bone]; 59 | if (parent == -1) { 60 | mat_from_pose(out, pose[bone].position, pose[bone].rotation, pose[bone].scale); 61 | } else { 62 | mat4 par, loc; 63 | calc_pose(par, skel, pose, parent); 64 | mat_from_pose(loc, pose[bone].position, pose[bone].rotation, pose[bone].scale); 65 | mat_mul44(out, par, loc); 66 | } 67 | } 68 | 69 | void update_transform_parent_skel(struct transform *transform, 70 | struct transform *parent, struct skelpose *skelpose, const char *bone) 71 | { 72 | mat4 local_matrix, pose_matrix, m; 73 | int i = find_bone(skelpose->skel, bone); 74 | mat_from_pose(local_matrix, transform->position, transform->rotation, transform->scale); 75 | calc_pose(pose_matrix, skelpose->skel, skelpose->pose, i); 76 | mat_mul44(m, pose_matrix, local_matrix); 77 | mat_mul44(transform->matrix, parent->matrix, m); 78 | } 79 | 80 | static mat4 proj; 81 | static mat4 view; 82 | 83 | void render_camera(mat4 iproj, mat4 iview) 84 | { 85 | mat_copy(proj, iproj); 86 | mat_copy(view, iview); 87 | } 88 | 89 | void render_skelpose(struct transform *transform, struct skelpose *skelpose) 90 | { 91 | struct skel *skel = skelpose->skel; 92 | struct pose *pose = skelpose->pose; 93 | mat4 local_pose[MAXBONE]; 94 | mat4 model_pose[MAXBONE]; 95 | mat4 model_view; 96 | 97 | calc_matrix_from_pose(local_pose, pose, skel->count); 98 | calc_abs_matrix(model_pose, local_pose, skel->parent, skel->count); 99 | 100 | mat_mul(model_view, view, transform->matrix); 101 | 102 | draw_begin(proj, model_view); 103 | draw_set_color(1, 1, 1, 1); 104 | draw_skel(model_pose, skel->parent, skel->count); 105 | draw_end(); 106 | } 107 | 108 | void animate_skelpose(struct skelpose *skelpose, struct anim *anim, float frame, float blend) 109 | { 110 | struct skel *skel = skelpose->skel; 111 | struct pose *pose = skelpose->pose; 112 | struct skel *askel = anim->skel; 113 | struct pose apose[MAXBONE]; 114 | int si, ai; 115 | 116 | extract_frame(apose, anim, frame); 117 | 118 | if (anim->loop) { 119 | vec3 dpos; 120 | vec4 drot, identity, tmp; 121 | float t; 122 | 123 | t = frame / (anim->frames - 1); 124 | vec_scale(dpos, anim->motion.position, t); 125 | vec_sub(apose[0].position, apose[0].position, dpos); 126 | 127 | quat_init(identity, 0, 0, 0, 1); 128 | quat_conjugate(drot, anim->motion.rotation); 129 | quat_lerp_neighbor_normalize(drot, identity, drot, t); 130 | quat_copy(tmp, apose[0].rotation); 131 | quat_mul(apose[0].rotation, drot, tmp); 132 | } 133 | 134 | for (si = 0; si < skel->count; si++) { 135 | // TODO: bone map 136 | ai = find_bone(askel, skel->name[si]); 137 | if (blend == 1) 138 | pose[si] = ai >= 0 ? apose[ai] : skel->pose[si]; 139 | else 140 | pose_lerp(pose+si, pose+si, ai >= 0 ? apose+ai : skel->pose+si, blend); 141 | } 142 | } 143 | 144 | void render_mesh_skel(struct transform *transform, struct mesh *mesh, struct skelpose *skelpose) 145 | { 146 | struct skel *skel = skelpose->skel; 147 | struct pose *pose = skelpose->pose; 148 | struct skel *ms = mesh->skel; 149 | mat4 local_pose[MAXBONE]; 150 | mat4 model_pose[MAXBONE]; 151 | mat4 model_view; 152 | mat4 model_from_bind_pose[MAXBONE]; 153 | int mi, si; 154 | 155 | calc_matrix_from_pose(local_pose, pose, skel->count); 156 | calc_abs_matrix(model_pose, local_pose, skel->parent, skel->count); 157 | 158 | mat_mul(model_view, view, transform->matrix); 159 | 160 | for (mi = 0; mi < ms->count; mi++) { 161 | // TODO: bone map 162 | si = find_bone(skel, ms->name[mi]); 163 | if (si < 0) { 164 | fprintf(stderr, "cannot find bone: %s\n", skel->name[mi]); 165 | return; /* error! */ 166 | } 167 | mat_mul(model_from_bind_pose[mi], model_pose[si], mesh->inv_bind_matrix[mi]); 168 | } 169 | 170 | render_skinned_mesh(mesh, proj, model_view, model_from_bind_pose); 171 | } 172 | 173 | void render_mesh(struct transform *transform, struct mesh *mesh) 174 | { 175 | mat4 model_view; 176 | mat_mul(model_view, view, transform->matrix); 177 | render_static_mesh(mesh, proj, model_view); 178 | } 179 | 180 | void render_lamp(struct transform *transform, struct lamp *lamp) 181 | { 182 | switch (lamp->type) { 183 | case LAMP_POINT: render_point_lamp(lamp, proj, view, transform->matrix); break; 184 | case LAMP_SPOT: render_spot_lamp(lamp, proj, view, transform->matrix); break; 185 | case LAMP_SUN: render_sun_lamp(lamp, proj, view, transform->matrix); break; 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /shader.c: -------------------------------------------------------------------------------- 1 | #include "mio.h" 2 | 3 | #ifdef __APPLE__ 4 | #define GLSL_VERT_PROLOG "#version 150\n" 5 | #define GLSL_FRAG_PROLOG "#version 150\n" 6 | #else 7 | #define GLSL_VERT_PROLOG "#version 130\n" 8 | #define GLSL_FRAG_PROLOG "#version 130\n" 9 | #endif 10 | 11 | const char *gl_error_string(GLenum code) 12 | { 13 | #define CASE(E) case E: return #E; break 14 | switch (code) 15 | { 16 | /* glGetError */ 17 | CASE(GL_NO_ERROR); 18 | CASE(GL_INVALID_ENUM); 19 | CASE(GL_INVALID_VALUE); 20 | CASE(GL_INVALID_OPERATION); 21 | CASE(GL_INVALID_FRAMEBUFFER_OPERATION); 22 | CASE(GL_OUT_OF_MEMORY); 23 | CASE(GL_STACK_UNDERFLOW); 24 | CASE(GL_STACK_OVERFLOW); 25 | 26 | /* glCheckFramebufferStatus */ 27 | CASE(GL_FRAMEBUFFER_COMPLETE); 28 | CASE(GL_FRAMEBUFFER_UNDEFINED); 29 | CASE(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT); 30 | CASE(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT); 31 | CASE(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER); 32 | CASE(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER); 33 | CASE(GL_FRAMEBUFFER_UNSUPPORTED); 34 | CASE(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE); 35 | CASE(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS); 36 | 37 | default: return "(unknown)"; 38 | } 39 | #undef CASE 40 | } 41 | 42 | void gl_assert(const char *msg) 43 | { 44 | int code = glGetError(); 45 | if (code != GL_NO_ERROR) { 46 | warn("glGetError(%s): %s", msg, gl_error_string(code)); 47 | } 48 | } 49 | 50 | void gl_assert_framebuffer(GLenum target, const char *msg) 51 | { 52 | int code = glCheckFramebufferStatus(target); 53 | if (code != GL_FRAMEBUFFER_COMPLETE) { 54 | warn("glCheckFramebufferStatus(%s): %s", msg, gl_error_string(code)); 55 | warn("Fatal error!"); 56 | exit(1); 57 | } 58 | } 59 | 60 | static void print_shader_log(char *kind, int shader) 61 | { 62 | int len; 63 | glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len); 64 | char *log = malloc(len + 1); 65 | glGetShaderInfoLog(shader, len, NULL, log); 66 | warn("--- glsl %s shader compile results ---\n%s", kind, log); 67 | free(log); 68 | } 69 | 70 | static void print_program_log(int program) 71 | { 72 | int len; 73 | glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len); 74 | char *log = malloc(len + 1); 75 | glGetProgramInfoLog(program, len, NULL, log); 76 | warn("--- glsl program link results ---\n%s", log); 77 | free(log); 78 | } 79 | 80 | int compile_shader(const char *vert_src, const char *frag_src) 81 | { 82 | const char *vert_src_list[2]; 83 | const char *frag_src_list[2]; 84 | int status; 85 | 86 | if (!vert_src || !frag_src) 87 | return 0; 88 | 89 | vert_src_list[0] = GLSL_VERT_PROLOG; 90 | vert_src_list[1] = vert_src; 91 | 92 | int vert = glCreateShader(GL_VERTEX_SHADER); 93 | glShaderSource(vert, nelem(vert_src_list), vert_src_list, NULL); 94 | glCompileShader(vert); 95 | glGetShaderiv(vert, GL_COMPILE_STATUS, &status); 96 | if (!status) 97 | print_shader_log("vertex", vert); 98 | 99 | frag_src_list[0] = GLSL_FRAG_PROLOG; 100 | frag_src_list[1] = frag_src; 101 | 102 | int frag = glCreateShader(GL_FRAGMENT_SHADER); 103 | glShaderSource(frag, nelem(frag_src_list), frag_src_list, NULL); 104 | glCompileShader(frag); 105 | glGetShaderiv(frag, GL_COMPILE_STATUS, &status); 106 | if (!status) 107 | print_shader_log("fragment", frag); 108 | 109 | int prog = glCreateProgram(); 110 | 111 | glBindAttribLocation(prog, ATT_POSITION, "att_position"); 112 | glBindAttribLocation(prog, ATT_NORMAL, "att_normal"); 113 | glBindAttribLocation(prog, ATT_TANGENT, "att_tangent"); 114 | glBindAttribLocation(prog, ATT_TEXCOORD, "att_texcoord"); 115 | glBindAttribLocation(prog, ATT_COLOR, "att_color"); 116 | glBindAttribLocation(prog, ATT_BLEND_INDEX, "att_blend_index"); 117 | glBindAttribLocation(prog, ATT_BLEND_WEIGHT, "att_blend_weight"); 118 | glBindAttribLocation(prog, ATT_LIGHTMAP, "att_lightmap"); 119 | glBindAttribLocation(prog, ATT_SPLAT, "att_splat"); 120 | glBindAttribLocation(prog, ATT_WIND, "att_wind"); 121 | 122 | glBindFragDataLocation(prog, FRAG_COLOR, "frag_color"); 123 | glBindFragDataLocation(prog, FRAG_NORMAL, "frag_normal"); 124 | glBindFragDataLocation(prog, FRAG_ALBEDO, "frag_albedo"); 125 | 126 | glAttachShader(prog, vert); 127 | glAttachShader(prog, frag); 128 | 129 | glLinkProgram(prog); 130 | glGetProgramiv(prog, GL_LINK_STATUS, &status); 131 | if (!status) 132 | print_program_log(prog); 133 | 134 | glDetachShader(prog, vert); 135 | glDetachShader(prog, frag); 136 | 137 | glDeleteShader(vert); 138 | glDeleteShader(frag); 139 | 140 | glUseProgram(prog); 141 | glUniform1i(glGetUniformLocation(prog, "map_color"), MAP_COLOR - GL_TEXTURE0); 142 | glUniform1i(glGetUniformLocation(prog, "map_gloss"), MAP_GLOSS - GL_TEXTURE0); 143 | glUniform1i(glGetUniformLocation(prog, "map_normal"), MAP_NORMAL - GL_TEXTURE0); 144 | glUniform1i(glGetUniformLocation(prog, "map_shadow"), MAP_SHADOW - GL_TEXTURE0); 145 | glUniform1i(glGetUniformLocation(prog, "map_depth"), MAP_DEPTH - GL_TEXTURE0); 146 | glUniform1i(glGetUniformLocation(prog, "map_emission"), MAP_EMISSION - GL_TEXTURE0); 147 | glUniform1i(glGetUniformLocation(prog, "map_light"), MAP_LIGHT - GL_TEXTURE0); 148 | glUniform1i(glGetUniformLocation(prog, "map_splat"), MAP_SPLAT - GL_TEXTURE0); 149 | 150 | return prog; 151 | } 152 | -------------------------------------------------------------------------------- /strict.lua: -------------------------------------------------------------------------------- 1 | -- strict.lua 2 | -- 3 | -- Check uses of undeclared global variables. 4 | -- 5 | -- All global variables must be 'declared' through a regular assignment 6 | -- (even assigning nil will do) in a main chunk before being used 7 | -- anywhere or assigned to inside a function. 8 | 9 | local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget 10 | 11 | local mt = getmetatable(_G) 12 | if mt == nil then 13 | mt = {} 14 | setmetatable(_G, mt) 15 | end 16 | 17 | mt.__declared = {} 18 | 19 | local function what () 20 | local d = getinfo(3, "S") 21 | return d and d.what or "C" 22 | end 23 | 24 | mt.__newindex = function (t, n, v) 25 | if not mt.__declared[n] then 26 | local w = what() 27 | if w ~= "main" and w ~= "C" then 28 | error("assign to undeclared variable '"..n.."'", 2) 29 | end 30 | mt.__declared[n] = true 31 | end 32 | rawset(t, n, v) 33 | end 34 | 35 | mt.__index = function (t, n) 36 | if not mt.__declared[n] and what() ~= "C" then 37 | error("variable '"..n.."' is not declared", 2) 38 | end 39 | return rawget(t, n) 40 | end 41 | -------------------------------------------------------------------------------- /strlcpy.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char * 4 | xstrsep(char **stringp, const char *delim) 5 | { 6 | char *ret = *stringp; 7 | if (ret == NULL) return NULL; 8 | if ((*stringp = strpbrk(*stringp, delim)) != NULL) 9 | *((*stringp)++) = '\0'; 10 | return ret; 11 | } 12 | 13 | int 14 | xstrlcpy(char *dst, const char *src, int siz) 15 | { 16 | register char *d = dst; 17 | register const char *s = src; 18 | register int n = siz; 19 | 20 | /* Copy as many bytes as will fit */ 21 | if (n != 0 && --n != 0) { 22 | do { 23 | if ((*d++ = *s++) == 0) 24 | break; 25 | } while (--n != 0); 26 | } 27 | 28 | /* Not enough room in dst, add NUL and traverse rest of src */ 29 | if (n == 0) { 30 | if (siz != 0) 31 | *d = '\0'; /* NUL-terminate dst */ 32 | while (*s++) 33 | ; 34 | } 35 | 36 | return(s - src - 1); /* count does not include NUL */ 37 | } 38 | 39 | int 40 | xstrlcat(char *dst, const char *src, int siz) 41 | { 42 | register char *d = dst; 43 | register const char *s = src; 44 | register int n = siz; 45 | int dlen; 46 | 47 | /* Find the end of dst and adjust bytes left but don't go past end */ 48 | while (*d != '\0' && n-- != 0) 49 | d++; 50 | dlen = d - dst; 51 | n = siz - dlen; 52 | 53 | if (n == 0) 54 | return dlen + strlen(s); 55 | while (*s != '\0') { 56 | if (n != 1) { 57 | *d++ = *s; 58 | n--; 59 | } 60 | s++; 61 | } 62 | *d = '\0'; 63 | 64 | return dlen + (s - src); /* count does not include NUL */ 65 | } 66 | -------------------------------------------------------------------------------- /vector.h: -------------------------------------------------------------------------------- 1 | /* 4x4 column major matrices, vectors and quaternions */ 2 | 3 | typedef float vec2[2]; 4 | typedef float vec3[3]; 5 | typedef float vec4[4]; 6 | typedef float mat4[16]; 7 | 8 | void mat_identity(mat4 m); 9 | void mat_copy(mat4 p, const mat4 m); 10 | void mat_mix(mat4 m, const mat4 a, const mat4 b, float v); 11 | void mat_mul(mat4 m, const mat4 a, const mat4 b); 12 | void mat_mul44(mat4 m, const mat4 a, const mat4 b); 13 | void mat_frustum(mat4 m, float left, float right, float bottom, float top, float n, float f); 14 | void mat_perspective(mat4 m, float fov, float aspect, float near, float far); 15 | void mat_look(mat4 m, const vec3 origin, const vec3 forward, const vec3 up); 16 | void mat_look_at(mat4 m, const vec3 eye, const vec3 center, const vec3 up); 17 | void mat_ortho(mat4 m, float left, float right, float bottom, float top, float n, float f); 18 | void mat_scale(mat4 m, float x, float y, float z); 19 | void mat_rotate_x(mat4 m, float angle); 20 | void mat_rotate_y(mat4 m, float angle); 21 | void mat_rotate_z(mat4 m, float angle); 22 | void mat_translate(mat4 m, float x, float y, float z); 23 | void mat_transpose(mat4 to, const mat4 from); 24 | void mat_invert(mat4 out, const mat4 m); 25 | 26 | void mat_vec_mul(vec3 p, const mat4 m, const vec3 v); 27 | void mat_vec_mul_n(vec3 p, const mat4 m, const vec3 v); 28 | void mat_vec_mul_t(vec3 p, const mat4 m, const vec3 v); 29 | void vec_init(vec3 p, float x, float y, float z); 30 | void vec_scale(vec3 p, const vec3 v, float s); 31 | void vec_add(vec3 p, const vec3 a, const vec3 b); 32 | void vec_sub(vec3 p, const vec3 a, const vec3 b); 33 | void vec_mul(vec3 p, const vec3 a, const vec3 b); 34 | void vec_div(vec3 p, const vec3 a, const vec3 b); 35 | void vec_div_s(vec3 p, const vec3 a, float b); 36 | void vec_lerp(vec3 p, const vec3 a, const vec3 b, float t); 37 | void vec_average(vec3 p, const vec3 a, const vec3 b); 38 | void vec_cross(vec3 p, const vec3 a, const vec3 b); 39 | float vec_dot(const vec3 a, const vec3 b); 40 | float vec_length(const vec3 a); 41 | float vec_dist2(const vec3 a, const vec3 b); 42 | float vec_dist(const vec3 a, const vec3 b); 43 | void vec_normalize(vec3 v, const vec3 a); 44 | void vec_face_normal(vec3 n, const vec3 p0, const vec3 p1, const vec3 p2); 45 | void vec_negate(vec3 p, const vec3 a); 46 | void vec_invert(vec3 p, const vec3 a); 47 | void vec_yup_to_zup(vec3 v); 48 | 49 | void quat_init(vec4 p, float x, float y, float z, float w); 50 | float quat_dot(const vec4 a, const vec4 b); 51 | void quat_invert(vec4 out, const vec4 q); 52 | void quat_copy(vec4 out, const vec4 q); 53 | void quat_conjugate(vec4 out, const vec4 q); 54 | void quat_mul(vec4 q, const vec4 a, const vec4 b); 55 | void quat_normalize(vec4 q, const vec4 a); 56 | void quat_lerp(vec4 p, const vec4 a, const vec4 b, float t); 57 | void quat_lerp_normalize(vec4 p, const vec4 a, const vec4 b, float t); 58 | void quat_lerp_neighbor_normalize(vec4 p, const vec4 a, const vec4 b, float t); 59 | void mat_from_quat(mat4 m, const vec4 q); 60 | void mat_from_pose(mat4 m, const vec3 t, const vec4 q, const vec3 s); 61 | void quat_from_mat(vec4 q, const mat4 m); 62 | int mat_is_negative(const mat4 m); 63 | void mat_decompose(const mat4 m, vec3 t, vec4 q, vec3 s); 64 | -------------------------------------------------------------------------------- /zip.c: -------------------------------------------------------------------------------- 1 | #include "mio.h" 2 | 3 | // to get zlib decompressor prototypes 4 | #define STBI_NO_WRITE 5 | #define STBI_NO_HDR 6 | #define STBI_HEADER_FILE_ONLY 7 | #include "stb_image.c" 8 | 9 | #define ZIP_LOCAL_FILE_SIG 0x04034b50 10 | #define ZIP_CENTRAL_DIRECTORY_SIG 0x02014b50 11 | #define ZIP_END_OF_CENTRAL_DIRECTORY_SIG 0x06054b50 12 | 13 | struct entry { 14 | char *name; 15 | int offset; 16 | }; 17 | 18 | struct archive { 19 | FILE *file; 20 | int count; 21 | struct entry *table; 22 | struct archive *next; 23 | }; 24 | 25 | static inline int getshort(FILE *file) 26 | { 27 | int a = getc(file); 28 | int b = getc(file); 29 | return a | b << 8; 30 | } 31 | 32 | static inline int getlong(FILE *file) 33 | { 34 | int a = getc(file); 35 | int b = getc(file); 36 | int c = getc(file); 37 | int d = getc(file); 38 | return a | b << 8 | c << 16 | d << 24; 39 | } 40 | 41 | static int cmpentry(const void *a_, const void *b_) 42 | { 43 | const struct entry *a = a_; 44 | const struct entry *b = b_; 45 | return strcmp(a->name, b->name); 46 | } 47 | 48 | static unsigned char *read_zip_file(FILE *file, int offset, int *sizep) 49 | { 50 | int sig, method, csize, usize; 51 | int namelength, extralength; 52 | char *cdata, *udata; 53 | 54 | fseek(file, offset, 0); 55 | 56 | sig = getlong(file); 57 | if (sig != ZIP_LOCAL_FILE_SIG) { 58 | warn("zip: wrong signature for local file"); 59 | return NULL; 60 | } 61 | 62 | (void) getshort(file); /* version */ 63 | (void) getshort(file); /* general */ 64 | method = getshort(file); 65 | (void) getshort(file); /* file time */ 66 | (void) getshort(file); /* file date */ 67 | (void) getlong(file); /* crc-32 */ 68 | csize = getlong(file); /* csize */ 69 | usize = getlong(file); /* usize */ 70 | namelength = getshort(file); 71 | extralength = getshort(file); 72 | 73 | fseek(file, namelength + extralength, 1); 74 | 75 | if (method == 0 && csize == usize) { 76 | cdata = malloc(csize); 77 | fread(cdata, 1, csize, file); 78 | *sizep = csize; 79 | return (unsigned char*) cdata; 80 | } 81 | 82 | if (method == 8) { 83 | cdata = malloc(csize); 84 | fread(cdata, 1, csize, file); 85 | udata = malloc(usize); 86 | usize = stbi_zlib_decode_noheader_buffer(udata, usize, cdata, csize); 87 | free(cdata); 88 | if (usize < 0) { 89 | warn("zip: %s", stbi_failure_reason()); 90 | return NULL; 91 | } 92 | *sizep = usize; 93 | return (unsigned char*) udata; 94 | } 95 | 96 | warn("zip: unknown compression method"); 97 | return NULL; 98 | } 99 | 100 | static int read_zip_dir_imp(struct archive *zip, int startoffset) 101 | { 102 | FILE *file = zip->file; 103 | int sig, offset, count; 104 | int namesize, metasize, commentsize; 105 | int i, k; 106 | 107 | fseek(file, startoffset, 0); 108 | 109 | sig = getlong(file); 110 | if (sig != ZIP_END_OF_CENTRAL_DIRECTORY_SIG) { 111 | warn("zip: wrong signature for end of central directory"); 112 | return -1; 113 | } 114 | 115 | (void) getshort(file); /* this disk */ 116 | (void) getshort(file); /* start disk */ 117 | (void) getshort(file); /* entries in this disk */ 118 | count = getshort(file); /* entries in central directory disk */ 119 | (void) getlong(file); /* size of central directory */ 120 | offset = getlong(file); /* offset to central directory */ 121 | 122 | zip->count = count; 123 | zip->table = calloc(count, sizeof(struct entry)); 124 | 125 | fseek(file, offset, 0); 126 | 127 | for (i = 0; i < count; i++) 128 | { 129 | struct entry *entry = zip->table + i; 130 | 131 | sig = getlong(file); 132 | if (sig != ZIP_CENTRAL_DIRECTORY_SIG) { 133 | for (k = 0; k < i; k++) 134 | free(zip->table[k].name); 135 | free(zip->table); 136 | warn("zip: wrong signature for central directory"); 137 | return -1; 138 | } 139 | 140 | (void) getshort(file); /* version made by */ 141 | (void) getshort(file); /* version to extract */ 142 | (void) getshort(file); /* general */ 143 | (void) getshort(file); /* method */ 144 | (void) getshort(file); /* last mod file time */ 145 | (void) getshort(file); /* last mod file date */ 146 | (void) getlong(file); /* crc-32 */ 147 | (void) getlong(file); /* csize */ 148 | (void) getlong(file); /* usize */ 149 | namesize = getshort(file); 150 | metasize = getshort(file); 151 | commentsize = getshort(file); 152 | (void) getshort(file); /* disk number start */ 153 | (void) getshort(file); /* int file atts */ 154 | (void) getlong(file); /* ext file atts */ 155 | entry->offset = getlong(file); 156 | 157 | entry->name = malloc(namesize + 1); 158 | fread(entry->name, 1, namesize, file); 159 | entry->name[namesize] = 0; 160 | 161 | fseek(file, metasize, 1); 162 | fseek(file, commentsize, 1); 163 | } 164 | 165 | qsort(zip->table, count, sizeof(struct entry), cmpentry); 166 | 167 | return 0; 168 | } 169 | 170 | static int read_zip_dir(struct archive *zip) 171 | { 172 | FILE *file = zip->file; 173 | unsigned char buf[512]; 174 | int filesize, back, maxback; 175 | int i, n; 176 | 177 | fseek(file, 0, 2); 178 | filesize = ftell(file); 179 | 180 | maxback = MIN(filesize, 0xFFFF + sizeof buf); 181 | back = MIN(maxback, sizeof buf); 182 | 183 | while (back < maxback) { 184 | fseek(file, filesize - back, 0); 185 | n = fread(buf, 1, sizeof buf, file); 186 | if (n < 0) { 187 | warn("zip: cannot read end of central directory"); 188 | return -1; 189 | } 190 | 191 | for (i = n - 4; i > 0; i--) 192 | if (!memcmp(buf + i, "PK\5\6", 4)) 193 | return read_zip_dir_imp(zip, filesize - back + i); 194 | 195 | back += sizeof buf - 4; 196 | } 197 | 198 | warn("zip: cannot find end of central directory"); 199 | return -1; 200 | } 201 | 202 | struct archive *open_archive(const char *filename) 203 | { 204 | struct archive *zip; 205 | FILE *file; 206 | 207 | file = fopen(filename, "rb"); 208 | if (!file) { 209 | warn("cannot open archive: '%s'", filename); 210 | return NULL; 211 | } 212 | 213 | zip = malloc(sizeof(struct archive)); 214 | zip->file = file; 215 | zip->count = 0; 216 | zip->table = NULL; 217 | zip->next = NULL; 218 | 219 | if (read_zip_dir(zip) < 0) { 220 | free(zip); 221 | fclose(file); 222 | return NULL; 223 | } 224 | 225 | return zip; 226 | } 227 | 228 | void close_archive(struct archive *zip) 229 | { 230 | int i; 231 | fclose(zip->file); 232 | for (i = 0; i < zip->count; i++) 233 | free(zip->table[i].name); 234 | free(zip->table); 235 | free(zip); 236 | } 237 | 238 | unsigned char *read_archive(struct archive *zip, const char *filename, int *sizep) 239 | { 240 | int l = 0; 241 | int r = zip->count - 1; 242 | while (l <= r) { 243 | int m = (l + r) >> 1; 244 | int c = strcmp(filename, zip->table[m].name); 245 | if (c < 0) 246 | r = m - 1; 247 | else if (c > 0) 248 | l = m + 1; 249 | else 250 | return read_zip_file(zip->file, zip->table[m].offset, sizep); 251 | } 252 | return NULL; 253 | } 254 | 255 | unsigned char *read_file(const char *filename, int *lenp) 256 | { 257 | unsigned char *data; 258 | int len; 259 | FILE *file = fopen(filename, "rb"); 260 | if (!file) { 261 | return NULL; 262 | } 263 | fseek(file, 0, 2); 264 | len = ftell(file); 265 | fseek(file, 0, 0); 266 | data = malloc(len); 267 | fread(data, 1, len, file); 268 | fclose(file); 269 | if (lenp) *lenp = len; 270 | return data; 271 | } 272 | 273 | /* 274 | * Virtual filesystem -- look for files in registered directories and archives. 275 | */ 276 | 277 | struct directory 278 | { 279 | char *name; 280 | struct directory *next; 281 | }; 282 | 283 | static struct directory *dir_head = NULL; 284 | static struct archive *zip_head = NULL; 285 | 286 | void register_directory(const char *dirname) 287 | { 288 | char buf[512]; 289 | int n = strlen(dirname); 290 | struct directory *dir = malloc(sizeof(struct directory)); 291 | strlcpy(buf, dirname, sizeof buf); 292 | if (n > 0 && buf[n-1] != '/') 293 | strlcat(buf, "/", sizeof buf); 294 | dir->name = strdup(buf); 295 | dir->next = dir_head; 296 | dir_head = dir; 297 | } 298 | 299 | void register_archive(const char *zipname) 300 | { 301 | struct archive *zip = open_archive(zipname); 302 | if (zip) { 303 | zip->next = zip_head; 304 | zip_head = zip; 305 | } 306 | } 307 | 308 | unsigned char *load_file(const char *filename, int *lenp) 309 | { 310 | struct directory *dir = dir_head; 311 | struct archive *zip = zip_head; 312 | unsigned char *data; 313 | char buf[512]; 314 | 315 | data = read_file(filename, lenp); 316 | 317 | while (!data && dir) { 318 | strlcpy(buf, dir->name, sizeof buf); 319 | strlcat(buf, filename, sizeof buf); 320 | data = read_file(buf, lenp); 321 | dir = dir->next; 322 | } 323 | 324 | while (!data && zip) { 325 | data = read_archive(zip, filename, lenp); 326 | zip = zip->next; 327 | } 328 | 329 | return data; 330 | } 331 | --------------------------------------------------------------------------------