You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(136) |
Dec
(218) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(214) |
Feb
(208) |
Mar
(186) |
Apr
(15) |
May
(3) |
Jun
(35) |
Jul
(6) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2005 |
Jan
(1) |
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
(58) |
Aug
(123) |
Sep
(31) |
Oct
(9) |
Nov
|
Dec
(1) |
2006 |
Jan
(25) |
Feb
(10) |
Mar
(25) |
Apr
(61) |
May
|
Jun
(78) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2007 |
Jan
|
Feb
|
Mar
|
Apr
(12) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(10) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2013 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
2014 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <yu...@us...> - 2003-11-21 08:29:04
|
Update of /cvsroot/timewarp/source/games In directory sc8-pr-cvs1:/tmp/cvs-serv8945/games Modified Files: gmissions.cpp Added Files: dialog.cpp dialog.h Log Message: dialog support --- NEW FILE: dialog.cpp --- #include <string.h> extern "C" { #include <lua.h> #include <lualib.h> #include <lauxlib.h> } #include <allegro.h> #include "dialog.h" #include "../util/aautil.h" #include "../util/aastr.h" BITMAP* Dialog::btmAlien = NULL; BITMAP* Dialog::btmPScreen = NULL; int Dialog::alien_image_x = 0; int Dialog::alien_image_y = 0; Dialog::Dialog() { btmPScreen = create_bitmap(SCREEN_W, SCREEN_H); ASSERT(btmPScreen); blit(screen, btmPScreen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); clear(screen); L = lua_open(); ///////////////////////////////////////////////////////// // Register C function for using in lua //////////////////////////////////////////////////////// lua_register(L, "Write", l_Write); lua_register(L, "Answer", l_Answer); lua_register(L, "Fight", l_Fight); lua_register(L, "SetAlienImage", l_SetAilenImage); ///////////////////////////////////////////////////////// alien_image_x = SCREEN_W; alien_image_y = SCREEN_H/2; } Dialog::~Dialog() { lua_close(L); show_mouse(NULL); blit(btmPScreen, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); show_mouse(screen); destroy_bitmap(btmPScreen); btmPScreen = NULL; } //////////////////////////////////////////////////////////////////////////// //Lua function implementation /////////////////////////////////////////////////////////////////////////// int Dialog::l_Write(lua_State* ls) { if(btmAlien) { show_mouse(NULL); blit(btmAlien, screen, 0, 0, 0, 0, alien_image_x, alien_image_y); show_mouse(screen); } const char* text = lua_tostring(ls, 1); ASSERT(text); show_mouse(NULL); textout(screen, font, text, 10, 10, -1); show_mouse(screen); return 0; } int Dialog::l_Answer(lua_State* ls) { int i; int num = lua_gettop(ls); // number of argument MENU *pMenuAnswers = new MENU[num+1]; for(i=0;i<num;i++) { const char* ctext = lua_tostring(ls, i+1); ASSERT(ctext); char * text = strdup(ctext); pMenuAnswers[i].text = text; pMenuAnswers[i].proc = NULL; pMenuAnswers[i].child = NULL; pMenuAnswers[i].flags = 0; pMenuAnswers[i].dp = NULL; } pMenuAnswers[num].text = NULL; pMenuAnswers[num].proc = NULL; pMenuAnswers[num].child = NULL; pMenuAnswers[num].flags = 0; pMenuAnswers[num].dp = NULL; int ret = -1; while( ret == -1 ) ret = do_menu(pMenuAnswers, 0, screen->h/2); ret++; /////////////////////////////////////////////// //Free memory for(i=0;i<num;i++) free(pMenuAnswers[num].text); delete[] pMenuAnswers; lua_pushnumber(ls, ret); return 1; } int Dialog::l_Fight(lua_State* ls) { return 0; } int Dialog::l_SetAilenImage(lua_State* ls) { const char* text = lua_tostring(ls, 1); if(btmAlien) { destroy_bitmap(btmAlien); btmAlien = NULL; } BITMAP *temp = load_bitmap( text, NULL); aa_set_mode(AA_DITHER); ASSERT(temp); btmAlien = create_bitmap(alien_image_x, alien_image_y); aa_stretch_blit(temp, btmAlien, 0, 0, temp->w, temp->h, 0, 0, alien_image_x, alien_image_y); destroy_bitmap(temp); show_mouse(NULL); blit(btmAlien, screen, 0, 0, 0, 0, alien_image_x, alien_image_y); show_mouse(screen); return 0; } void Dialog::Conversate(const char *dialogfile) { lua_dofile(L, dialogfile); } --- NEW FILE: dialog.h --- ////////////////////////////////////////////////////////////////////////// // // // Test Dialog module for TimeWarp // // (c) Yura Semashko aka Yurand <yu...@la...> // // // ////////////////////////////////////////////////////////////////////////// #ifndef __DIALOG_MODULE__ #define __DIALOG_MODULE__ #include <lua.h> #include <allegro.h> /*! \brief Communicatin */ class Dialog { private: /*! \brief Alien creature image */ static BITMAP * btmAlien; /*! \brief width of Alien creature */ static int alien_image_x; /*! \brief height of Alien creature */ static int alien_image_y; /*! \brief screen image before dialog */ static BITMAP * btmPScreen; lua_State * L; /*! \brief Write text from lua to screen */ static int l_Write(lua_State* ls); /*! \brief Decision module */ static int l_Answer(lua_State* ls); /*! \brief Fight module */ static int l_Fight(lua_State* ls); static int l_SetAilenImage(lua_State* ls); public: /*! \brief Talk function */ void Conversate(const char *dialogfile); Dialog(); ~Dialog(); }; #endif // __DIALOG_MODULE__ Index: gmissions.cpp =================================================================== RCS file: /cvsroot/timewarp/source/games/gmissions.cpp,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** gmissions.cpp 19 Nov 2003 22:07:48 -0000 1.12 --- gmissions.cpp 21 Nov 2003 08:29:01 -0000 1.13 *************** *** 27,30 **** --- 27,31 ---- #include "gplexplr.h" + #include "dialog.h" #include <string.h> *************** *** 816,819 **** --- 817,823 ---- // start the mission // ok .. when a mission is played, it's deleted, and can't be played again ... what to do about that ?! + Dialog* dialog = new Dialog; + dialog->Conversate("dialog.lua"); + delete dialog; SubGame *g; g = missionlist[k]->initgame(); |
From: <yu...@us...> - 2003-11-21 08:29:04
|
Update of /cvsroot/timewarp/source/gamex In directory sc8-pr-cvs1:/tmp/cvs-serv8945/gamex Modified Files: gamemelee.cpp projectx.cpp Log Message: dialog support Index: gamemelee.cpp =================================================================== RCS file: /cvsroot/timewarp/source/gamex/gamemelee.cpp,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** gamemelee.cpp 18 Nov 2003 17:18:49 -0000 1.1.1.1 --- gamemelee.cpp 21 Nov 2003 08:29:01 -0000 1.2 *************** *** 23,27 **** #include "gamesolarview.h" ! #include "GameMelee.h" #include "gameplanetscan.h" #include "gamemelee.h" --- 23,27 ---- #include "gamesolarview.h" ! #include "gamemelee.h" #include "gameplanetscan.h" #include "gamemelee.h" Index: projectx.cpp =================================================================== RCS file: /cvsroot/timewarp/source/gamex/projectx.cpp,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** projectx.cpp 18 Nov 2003 17:18:50 -0000 1.1.1.1 --- projectx.cpp 21 Nov 2003 08:29:01 -0000 1.2 *************** *** 15,19 **** #include "gamemelee.h" #include "edit/edit_dialogue.h" - #include "edit/edit_trigger.h" #include "gamedialogue.h" --- 15,18 ---- |
From: <geo...@us...> - 2003-11-20 18:34:45
|
Update of /cvsroot/timewarp In directory sc8-pr-cvs1:/tmp/cvs-serv758 Modified Files: twwin.dsp Log Message: woops, included an unfinished ship |
From: <geo...@us...> - 2003-11-20 17:43:41
|
Update of /cvsroot/timewarp In directory sc8-pr-cvs1:/tmp/cvs-serv23750 Modified Files: twwin.dsp Log Message: removed the gamex trigger editor, cause I took it for more general dev. to the games/ directory |
From: <geo...@us...> - 2003-11-20 17:42:48
|
Update of /cvsroot/timewarp/source/gamex/edit In directory sc8-pr-cvs1:/tmp/cvs-serv23583 Removed Files: edit_trigger.cpp edit_trigger.h Log Message: removing redundant files --- edit_trigger.cpp DELETED --- --- edit_trigger.h DELETED --- |
From: <geo...@us...> - 2003-11-20 17:33:26
|
Update of /cvsroot/timewarp/source/gamex In directory sc8-pr-cvs1:/tmp/cvs-serv21811 Removed Files: files.txt license.txt Log Message: removing redundant files --- files.txt DELETED --- --- license.txt DELETED --- |
From: <yu...@us...> - 2003-11-19 23:52:28
|
Update of /cvsroot/timewarp In directory sc8-pr-cvs1:/tmp/cvs-serv15942 Modified Files: makefile Log Message: fixed GCC compilation |
From: <yu...@us...> - 2003-11-19 23:52:28
|
Update of /cvsroot/timewarp/source/gamex/edit In directory sc8-pr-cvs1:/tmp/cvs-serv15942/source/gamex/edit Modified Files: edit_trigger.cpp edit_trigger.h Log Message: fixed GCC compilation Index: edit_trigger.cpp =================================================================== RCS file: /cvsroot/timewarp/source/gamex/edit/edit_trigger.cpp,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** edit_trigger.cpp 18 Nov 2003 17:18:51 -0000 1.1.1.1 --- edit_trigger.cpp 19 Nov 2003 23:51:45 -0000 1.2 *************** *** 310,314 **** } ! void GameTriggerEdit::init() { int i; --- 310,314 ---- } ! void XGameTriggerEdit::init() { int i; *************** *** 409,413 **** ! void GameTriggerEdit::quit() { --- 409,413 ---- ! void XGameTriggerEdit::quit() { *************** *** 426,430 **** ! void GameTriggerEdit::calculate() { if (next) --- 426,430 ---- ! void XGameTriggerEdit::calculate() { if (next) *************** *** 440,444 **** ! void GameTriggerEdit::animate(Frame *frame) { if (next) --- 440,444 ---- ! void XGameTriggerEdit::animate(Frame *frame) { if (next) Index: edit_trigger.h =================================================================== RCS file: /cvsroot/timewarp/source/gamex/edit/edit_trigger.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** edit_trigger.h 18 Nov 2003 17:18:51 -0000 1.1.1.1 --- edit_trigger.h 19 Nov 2003 23:51:45 -0000 1.2 *************** *** 11,15 **** ! class GameTriggerEdit : public GameBare { BlockStore dstore; --- 11,15 ---- ! class XGameTriggerEdit : public GameBare { BlockStore dstore; |
From: <yu...@us...> - 2003-11-19 23:52:28
|
Update of /cvsroot/timewarp/source/gamex/general In directory sc8-pr-cvs1:/tmp/cvs-serv15942/source/gamex/general Modified Files: sprites.cpp sprites.h Log Message: fixed GCC compilation Index: sprites.cpp =================================================================== RCS file: /cvsroot/timewarp/source/gamex/general/sprites.cpp,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** sprites.cpp 18 Nov 2003 17:18:52 -0000 1.1.1.1 --- sprites.cpp 19 Nov 2003 23:51:45 -0000 1.2 *************** *** 108,112 **** - // all the sprite-relevant information (and nothing else). SpaceSprite::SpaceSprite(BITMAP **bmplist, int sprite_count, int rotations, int _attributes) --- 108,111 ---- Index: sprites.h =================================================================== RCS file: /cvsroot/timewarp/source/gamex/general/sprites.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** sprites.h 18 Nov 2003 17:18:52 -0000 1.1.1.1 --- sprites.h 19 Nov 2003 23:51:45 -0000 1.2 *************** *** 12,16 **** // all the sprite-relevant information (and nothing else). ! SpaceSprite::SpaceSprite(BITMAP **bmplist, int sprite_count, int rotations, int _attributes); #endif --- 12,16 ---- // all the sprite-relevant information (and nothing else). ! //SpaceSprite::SpaceSprite(BITMAP **bmplist, int sprite_count, int rotations, int _attributes); #endif |
From: <geo...@us...> - 2003-11-19 22:13:26
|
Update of /cvsroot/timewarp/source/sc2ships In directory sc8-pr-cvs1:/tmp/cvs-serv29085/source/sc2ships Modified Files: shpmeltr.cpp Log Message: melnorme red ball does not die on non-shots Index: shpmeltr.cpp =================================================================== RCS file: /cvsroot/timewarp/source/sc2ships/shpmeltr.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** shpmeltr.cpp 6 Oct 2003 21:56:59 -0000 1.5 --- shpmeltr.cpp 19 Nov 2003 22:13:23 -0000 1.6 *************** *** 24,27 **** --- 24,28 ---- virtual void animateExplosion(); virtual int handle_damage(SpaceLocation *source, double normal, double direct); + virtual void inflict_damage(SpaceObject *other); }; *************** *** 182,185 **** --- 183,202 ---- if (!released && (armour > 0)) armour = old; return old - armour; + } + + void MelnormeShot::inflict_damage(SpaceObject *other) + { + if (!other->exists()) return; + damage(other, damage_factor); + + // this can only die on enemy non-shots, if it's not red ... + if (charge_phase < 3) + if (other->isblockingweapons) state = 0; + + if (state == 0) { + animateExplosion(); + soundExplosion(); + } + return; } |
From: <geo...@us...> - 2003-11-19 22:10:59
|
Update of /cvsroot/timewarp/source In directory sc8-pr-cvs1:/tmp/cvs-serv28693/source Modified Files: scp.cpp Log Message: game that was selected is preserved in client.ini Index: scp.cpp =================================================================== RCS file: /cvsroot/timewarp/source/scp.cpp,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** scp.cpp 18 Nov 2003 17:21:11 -0000 1.25 --- scp.cpp 19 Nov 2003 22:10:56 -0000 1.26 *************** *** 880,886 **** const char *select_game_menu () {STACKTRACE select_game_dialog[2].dp3 = game_names; int i = tw_popup_dialog(NULL, select_game_dialog, 2); if (i == -1) return NULL; ! else return game_names[select_game_dialog[2].d1]; } --- 880,891 ---- const char *select_game_menu () {STACKTRACE select_game_dialog[2].dp3 = game_names; + set_config_file("client.ini"); + select_game_dialog[2].d1 = get_config_int("Menu", "SelectGame", 0); int i = tw_popup_dialog(NULL, select_game_dialog, 2); if (i == -1) return NULL; ! else { ! set_config_int("Menu", "SelectGame", select_game_dialog[2].d1); ! return game_names[select_game_dialog[2].d1]; ! } } |
From: <geo...@us...> - 2003-11-19 22:07:51
|
Update of /cvsroot/timewarp/source/games In directory sc8-pr-cvs1:/tmp/cvs-serv28025/source/games Modified Files: gmissions.cpp Log Message: game that was selected is preserved in client.ini Index: gmissions.cpp =================================================================== RCS file: /cvsroot/timewarp/source/games/gmissions.cpp,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** gmissions.cpp 15 Nov 2003 20:48:06 -0000 1.11 --- gmissions.cpp 19 Nov 2003 22:07:48 -0000 1.12 *************** *** 1080,1084 **** { Ship *s; ! s = Game::create_ship(channel_server, shpid, c, map_size*Vector2(relx, rely), random(2*PI), team); add(s->get_ship_phaser()); add(new HealthBar(s, &healthtoggle)); --- 1080,1085 ---- { Ship *s; ! s = Game::create_ship(channel_none, shpid, c, map_size*Vector2(relx, rely), random(2*PI), team); ! // don't use channel_server for AI players... add(s->get_ship_phaser()); add(new HealthBar(s, &healthtoggle)); |
From: <yu...@us...> - 2003-11-19 08:20:10
|
Update of /cvsroot/timewarp/include In directory sc8-pr-cvs1:/tmp/cvs-serv15407 Added Files: lauxlib.h lua.h lualib.h Log Message: lua support --- NEW FILE: lauxlib.h --- /* ** $Id: lauxlib.h,v 1.1 2003/11/19 08:20:04 yurand Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ #ifndef lauxlib_h #define lauxlib_h #include <stddef.h> #include <stdio.h> #include "lua.h" #ifndef LUALIB_API #define LUALIB_API LUA_API #endif typedef struct luaL_reg { const char *name; lua_CFunction func; } luaL_reg; LUALIB_API void luaL_openlib (lua_State *L, const char *libname, const luaL_reg *l, int nup); LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *e); LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *e); LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname); LUALIB_API int luaL_argerror (lua_State *L, int numarg, const char *extramsg); LUALIB_API const char *luaL_checklstring (lua_State *L, int numArg, size_t *l); LUALIB_API const char *luaL_optlstring (lua_State *L, int numArg, const char *def, size_t *l); LUALIB_API lua_Number luaL_checknumber (lua_State *L, int numArg); LUALIB_API lua_Number luaL_optnumber (lua_State *L, int nArg, lua_Number def); LUALIB_API void luaL_checkstack (lua_State *L, int sz, const char *msg); LUALIB_API void luaL_checktype (lua_State *L, int narg, int t); LUALIB_API void luaL_checkany (lua_State *L, int narg); LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname); LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname); LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname); LUALIB_API void luaL_where (lua_State *L, int lvl); LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...); LUALIB_API int luaL_findstring (const char *st, const char *const lst[]); LUALIB_API int luaL_ref (lua_State *L, int t); LUALIB_API void luaL_unref (lua_State *L, int t, int ref); LUALIB_API int luaL_getn (lua_State *L, int t); LUALIB_API void luaL_setn (lua_State *L, int t, int n); LUALIB_API int luaL_loadfile (lua_State *L, const char *filename); LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz, const char *name); /* ** =============================================================== ** some useful macros ** =============================================================== */ #define luaL_argcheck(L, cond,numarg,extramsg) if (!(cond)) \ luaL_argerror(L, numarg,extramsg) #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) #define luaL_checkint(L,n) ((int)luaL_checknumber(L, n)) #define luaL_checklong(L,n) ((long)luaL_checknumber(L, n)) #define luaL_optint(L,n,d) ((int)luaL_optnumber(L, n,(lua_Number)(d))) #define luaL_optlong(L,n,d) ((long)luaL_optnumber(L, n,(lua_Number)(d))) /* ** {====================================================== ** Generic Buffer manipulation ** ======================================================= */ #ifndef LUAL_BUFFERSIZE #define LUAL_BUFFERSIZE BUFSIZ #endif typedef struct luaL_Buffer { char *p; /* current position in buffer */ int lvl; /* number of strings in the stack (level) */ lua_State *L; char buffer[LUAL_BUFFERSIZE]; } luaL_Buffer; #define luaL_putchar(B,c) \ ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ (*(B)->p++ = (char)(c))) #define luaL_addsize(B,n) ((B)->p += (n)) LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B); LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B); LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l); LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s); LUALIB_API void luaL_addvalue (luaL_Buffer *B); LUALIB_API void luaL_pushresult (luaL_Buffer *B); /* }====================================================== */ /* ** Compatibility macros and functions */ LUALIB_API int lua_dofile (lua_State *L, const char *filename); LUALIB_API int lua_dostring (lua_State *L, const char *str); LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t sz, const char *n); #define luaL_check_lstr luaL_checklstring #define luaL_opt_lstr luaL_optlstring #define luaL_check_number luaL_checknumber #define luaL_opt_number luaL_optnumber #define luaL_arg_check luaL_argcheck #define luaL_check_string luaL_checkstring #define luaL_opt_string luaL_optstring #define luaL_check_int luaL_checkint #define luaL_check_long luaL_checklong #define luaL_opt_int luaL_optint #define luaL_opt_long luaL_optlong #endif --- NEW FILE: lua.h --- /* ** $Id: lua.h,v 1.1 2003/11/19 08:20:05 yurand Exp $ ** Lua - An Extensible Extension Language ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil ** http://www.lua.org mailto:in...@lu... ** See Copyright Notice at the end of this file */ #ifndef lua_h #define lua_h #include <stdarg.h> #include <stddef.h> #define LUA_VERSION "Lua 5.0" #define LUA_COPYRIGHT "Copyright (C) 1994-2003 Tecgraf, PUC-Rio" #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" /* option for multiple returns in `lua_pcall' and `lua_call' */ #define LUA_MULTRET (-1) /* ** pseudo-indices */ #define LUA_REGISTRYINDEX (-10000) #define LUA_GLOBALSINDEX (-10001) #define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) /* error codes for `lua_load' and `lua_pcall' */ #define LUA_ERRRUN 1 #define LUA_ERRFILE 2 #define LUA_ERRSYNTAX 3 #define LUA_ERRMEM 4 #define LUA_ERRERR 5 typedef struct lua_State lua_State; typedef int (*lua_CFunction) (lua_State *L); /* ** functions that read/write blocks when loading/dumping Lua chunks */ typedef const char * (*lua_Chunkreader) (lua_State *L, void *ud, size_t *sz); typedef int (*lua_Chunkwriter) (lua_State *L, const void* p, size_t sz, void* ud); /* ** basic types */ #define LUA_TNONE (-1) #define LUA_TNIL 0 #define LUA_TBOOLEAN 1 #define LUA_TLIGHTUSERDATA 2 #define LUA_TNUMBER 3 #define LUA_TSTRING 4 #define LUA_TTABLE 5 #define LUA_TFUNCTION 6 #define LUA_TUSERDATA 7 #define LUA_TTHREAD 8 /* minimum Lua stack available to a C function */ #define LUA_MINSTACK 20 /* ** generic extra include file */ #ifdef LUA_USER_H #include LUA_USER_H #endif /* type of numbers in Lua */ #ifndef LUA_NUMBER typedef double lua_Number; #else typedef LUA_NUMBER lua_Number; #endif /* mark for all API functions */ #ifndef LUA_API #define LUA_API extern #endif /* ** state manipulation */ LUA_API lua_State *lua_open (void); LUA_API void lua_close (lua_State *L); LUA_API lua_State *lua_newthread (lua_State *L); LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf); /* ** basic stack manipulation */ LUA_API int lua_gettop (lua_State *L); LUA_API void lua_settop (lua_State *L, int idx); LUA_API void lua_pushvalue (lua_State *L, int idx); LUA_API void lua_remove (lua_State *L, int idx); LUA_API void lua_insert (lua_State *L, int idx); LUA_API void lua_replace (lua_State *L, int idx); LUA_API int lua_checkstack (lua_State *L, int sz); LUA_API void lua_xmove (lua_State *from, lua_State *to, int n); /* ** access functions (stack -> C) */ LUA_API int lua_isnumber (lua_State *L, int idx); LUA_API int lua_isstring (lua_State *L, int idx); LUA_API int lua_iscfunction (lua_State *L, int idx); LUA_API int lua_isuserdata (lua_State *L, int idx); LUA_API int lua_type (lua_State *L, int idx); LUA_API const char *lua_typename (lua_State *L, int tp); LUA_API int lua_equal (lua_State *L, int idx1, int idx2); LUA_API int lua_rawequal (lua_State *L, int idx1, int idx2); LUA_API int lua_lessthan (lua_State *L, int idx1, int idx2); LUA_API lua_Number lua_tonumber (lua_State *L, int idx); LUA_API int lua_toboolean (lua_State *L, int idx); LUA_API const char *lua_tostring (lua_State *L, int idx); LUA_API size_t lua_strlen (lua_State *L, int idx); LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx); LUA_API void *lua_touserdata (lua_State *L, int idx); LUA_API lua_State *lua_tothread (lua_State *L, int idx); LUA_API const void *lua_topointer (lua_State *L, int idx); /* ** push functions (C -> stack) */ LUA_API void lua_pushnil (lua_State *L); LUA_API void lua_pushnumber (lua_State *L, lua_Number n); LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t l); LUA_API void lua_pushstring (lua_State *L, const char *s); LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp); LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...); LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); LUA_API void lua_pushboolean (lua_State *L, int b); LUA_API void lua_pushlightuserdata (lua_State *L, void *p); /* ** get functions (Lua -> stack) */ LUA_API void lua_gettable (lua_State *L, int idx); LUA_API void lua_rawget (lua_State *L, int idx); LUA_API void lua_rawgeti (lua_State *L, int idx, int n); LUA_API void lua_newtable (lua_State *L); LUA_API void *lua_newuserdata (lua_State *L, size_t sz); LUA_API int lua_getmetatable (lua_State *L, int objindex); LUA_API void lua_getfenv (lua_State *L, int idx); /* ** set functions (stack -> Lua) */ LUA_API void lua_settable (lua_State *L, int idx); LUA_API void lua_rawset (lua_State *L, int idx); LUA_API void lua_rawseti (lua_State *L, int idx, int n); LUA_API int lua_setmetatable (lua_State *L, int objindex); LUA_API int lua_setfenv (lua_State *L, int idx); /* ** `load' and `call' functions (load and run Lua code) */ LUA_API void lua_call (lua_State *L, int nargs, int nresults); LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc); LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud); LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *dt, const char *chunkname); LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data); /* ** coroutine functions */ LUA_API int lua_yield (lua_State *L, int nresults); LUA_API int lua_resume (lua_State *L, int narg); /* ** garbage-collection functions */ LUA_API int lua_getgcthreshold (lua_State *L); LUA_API int lua_getgccount (lua_State *L); LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold); /* ** miscellaneous functions */ LUA_API const char *lua_version (void); LUA_API int lua_error (lua_State *L); LUA_API int lua_next (lua_State *L, int idx); LUA_API void lua_concat (lua_State *L, int n); /* ** =============================================================== ** some useful macros ** =============================================================== */ #define lua_boxpointer(L,u) \ (*(void **)(lua_newuserdata(L, sizeof(void *))) = (u)) #define lua_unboxpointer(L,i) (*(void **)(lua_touserdata(L, i))) #define lua_pop(L,n) lua_settop(L, -(n)-1) #define lua_register(L,n,f) \ (lua_pushstring(L, n), \ lua_pushcfunction(L, f), \ lua_settable(L, LUA_GLOBALSINDEX)) #define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0) #define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION) #define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE) #define lua_islightuserdata(L,n) (lua_type(L,n) == LUA_TLIGHTUSERDATA) #define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL) #define lua_isboolean(L,n) (lua_type(L,n) == LUA_TBOOLEAN) #define lua_isnone(L,n) (lua_type(L,n) == LUA_TNONE) #define lua_isnoneornil(L, n) (lua_type(L,n) <= 0) #define lua_pushliteral(L, s) \ lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) /* ** compatibility macros and functions */ LUA_API int lua_pushupvalues (lua_State *L); #define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) #define lua_setglobal(L,s) \ (lua_pushstring(L, s), lua_insert(L, -2), lua_settable(L, LUA_GLOBALSINDEX)) #define lua_getglobal(L,s) \ (lua_pushstring(L, s), lua_gettable(L, LUA_GLOBALSINDEX)) /* compatibility with ref system */ /* pre-defined references */ #define LUA_NOREF (-2) #define LUA_REFNIL (-1) #define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) #define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) #define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, ref) /* ** {====================================================================== ** useful definitions for Lua kernel and libraries ** ======================================================================= */ /* formats for Lua numbers */ #ifndef LUA_NUMBER_SCAN #define LUA_NUMBER_SCAN "%lf" #endif #ifndef LUA_NUMBER_FMT #define LUA_NUMBER_FMT "%.14g" #endif /* }====================================================================== */ /* ** {====================================================================== ** Debug API ** ======================================================================= */ /* ** Event codes */ #define LUA_HOOKCALL 0 #define LUA_HOOKRET 1 #define LUA_HOOKLINE 2 #define LUA_HOOKCOUNT 3 #define LUA_HOOKTAILRET 4 /* ** Event masks */ #define LUA_MASKCALL (1 << LUA_HOOKCALL) #define LUA_MASKRET (1 << LUA_HOOKRET) #define LUA_MASKLINE (1 << LUA_HOOKLINE) #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) typedef struct lua_Debug lua_Debug; /* activation record */ typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); LUA_API lua_Hook lua_gethook (lua_State *L); LUA_API int lua_gethookmask (lua_State *L); LUA_API int lua_gethookcount (lua_State *L); #define LUA_IDSIZE 60 struct lua_Debug { int event; const char *name; /* (n) */ const char *namewhat; /* (n) `global', `local', `field', `method' */ const char *what; /* (S) `Lua', `C', `main', `tail' */ const char *source; /* (S) */ int currentline; /* (l) */ int nups; /* (u) number of upvalues */ int linedefined; /* (S) */ char short_src[LUA_IDSIZE]; /* (S) */ /* private part */ int i_ci; /* active function */ }; /* }====================================================================== */ /****************************************************************************** * Copyright (C) 1994-2003 Tecgraf, PUC-Rio. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ #endif --- NEW FILE: lualib.h --- /* ** $Id: lualib.h,v 1.1 2003/11/19 08:20:05 yurand Exp $ ** Lua standard libraries ** See Copyright Notice in lua.h */ #ifndef lualib_h #define lualib_h #include "lua.h" #ifndef LUALIB_API #define LUALIB_API LUA_API #endif #define LUA_COLIBNAME "coroutine" LUALIB_API int luaopen_base (lua_State *L); #define LUA_TABLIBNAME "table" LUALIB_API int luaopen_table (lua_State *L); #define LUA_IOLIBNAME "io" #define LUA_OSLIBNAME "os" LUALIB_API int luaopen_io (lua_State *L); #define LUA_STRLIBNAME "string" LUALIB_API int luaopen_string (lua_State *L); #define LUA_MATHLIBNAME "math" LUALIB_API int luaopen_math (lua_State *L); #define LUA_DBLIBNAME "debug" LUALIB_API int luaopen_debug (lua_State *L); LUALIB_API int luaopen_loadlib (lua_State *L); /* to help testing the libraries */ #ifndef lua_assert #define lua_assert(c) /* empty */ #endif /* compatibility code */ #define lua_baselibopen luaopen_base #define lua_tablibopen luaopen_table #define lua_iolibopen luaopen_io #define lua_strlibopen luaopen_string #define lua_mathlibopen luaopen_math #define lua_dblibopen luaopen_debug #endif |
Update of /cvsroot/timewarp/source/util/lua/lib In directory sc8-pr-cvs1:/tmp/cvs-serv15221 Added Files: lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loadlib.c lstrlib.c ltablib.c README Log Message: lua support --- NEW FILE: lauxlib.c --- /* ** $Id: lauxlib.c,v 1.1 2003/11/19 08:18:34 yurand Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ #include <ctype.h> #include <errno.h> #include <stdarg.h> #include <stdio.h> #include <string.h> /* This file uses only the official API of Lua. ** Any function declared here could be written as an application function. */ #define lauxlib_c #include "lua.h" #include "lauxlib.h" /* number of prereserved references (for internal use) */ #define RESERVED_REFS 2 /* reserved references */ #define FREELIST_REF 1 /* free list of references */ #define ARRAYSIZE_REF 2 /* array sizes */ /* convert a stack index to positive */ #define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ lua_gettop(L) + (i) + 1) /* ** {====================================================== ** Error-report functions ** ======================================================= */ LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { lua_Debug ar; lua_getstack(L, 0, &ar); lua_getinfo(L, "n", &ar); if (strcmp(ar.namewhat, "method") == 0) { narg--; /* do not count `self' */ if (narg == 0) /* error is in the self argument itself? */ return luaL_error(L, "calling `%s' on bad self (%s)", ar.name, extramsg); } if (ar.name == NULL) ar.name = "?"; return luaL_error(L, "bad argument #%d to `%s' (%s)", narg, ar.name, extramsg); } LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { const char *msg = lua_pushfstring(L, "%s expected, got %s", tname, lua_typename(L, lua_type(L,narg))); return luaL_argerror(L, narg, msg); } static void tag_error (lua_State *L, int narg, int tag) { luaL_typerror(L, narg, lua_typename(L, tag)); } LUALIB_API void luaL_where (lua_State *L, int level) { lua_Debug ar; if (lua_getstack(L, level, &ar)) { /* check function at level */ lua_getinfo(L, "Snl", &ar); /* get info about it */ if (ar.currentline > 0) { /* is there info? */ lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); return; } } lua_pushliteral(L, ""); /* else, no information available... */ } LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { va_list argp; va_start(argp, fmt); luaL_where(L, 1); lua_pushvfstring(L, fmt, argp); va_end(argp); lua_concat(L, 2); return lua_error(L); } /* }====================================================== */ LUALIB_API int luaL_findstring (const char *name, const char *const list[]) { int i; for (i=0; list[i]; i++) if (strcmp(list[i], name) == 0) return i; return -1; /* name not found */ } LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { lua_pushstring(L, tname); lua_rawget(L, LUA_REGISTRYINDEX); /* get registry.name */ if (!lua_isnil(L, -1)) /* name already in use? */ return 0; /* leave previous value on top, but return 0 */ lua_pop(L, 1); lua_newtable(L); /* create metatable */ lua_pushstring(L, tname); lua_pushvalue(L, -2); lua_rawset(L, LUA_REGISTRYINDEX); /* registry.name = metatable */ lua_pushvalue(L, -1); lua_pushstring(L, tname); lua_rawset(L, LUA_REGISTRYINDEX); /* registry[metatable] = name */ return 1; } LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname) { lua_pushstring(L, tname); lua_rawget(L, LUA_REGISTRYINDEX); } LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { const char *tn; if (!lua_getmetatable(L, ud)) return NULL; /* no metatable? */ lua_rawget(L, LUA_REGISTRYINDEX); /* get registry[metatable] */ tn = lua_tostring(L, -1); if (tn && (strcmp(tn, tname) == 0)) { lua_pop(L, 1); return lua_touserdata(L, ud); } else { lua_pop(L, 1); return NULL; } } LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { if (!lua_checkstack(L, space)) luaL_error(L, "stack overflow (%s)", mes); } LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { if (lua_type(L, narg) != t) tag_error(L, narg, t); } LUALIB_API void luaL_checkany (lua_State *L, int narg) { if (lua_type(L, narg) == LUA_TNONE) luaL_argerror(L, narg, "value expected"); } LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { const char *s = lua_tostring(L, narg); if (!s) tag_error(L, narg, LUA_TSTRING); if (len) *len = lua_strlen(L, narg); return s; } LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, const char *def, size_t *len) { if (lua_isnoneornil(L, narg)) { if (len) *len = (def ? strlen(def) : 0); return def; } else return luaL_checklstring(L, narg, len); } LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { lua_Number d = lua_tonumber(L, narg); if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ tag_error(L, narg, LUA_TNUMBER); return d; } LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { if (lua_isnoneornil(L, narg)) return def; else return luaL_checknumber(L, narg); } LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { if (!lua_getmetatable(L, obj)) /* no metatable? */ return 0; lua_pushstring(L, event); lua_rawget(L, -2); if (lua_isnil(L, -1)) { lua_pop(L, 2); /* remove metatable and metafield */ return 0; } else { lua_remove(L, -2); /* remove only metatable */ return 1; } } LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { obj = abs_index(L, obj); if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ return 0; lua_pushvalue(L, obj); lua_call(L, 1, 1); return 1; } LUALIB_API void luaL_openlib (lua_State *L, const char *libname, const luaL_reg *l, int nup) { if (libname) { lua_pushstring(L, libname); lua_gettable(L, LUA_GLOBALSINDEX); /* check whether lib already exists */ if (lua_isnil(L, -1)) { /* no? */ lua_pop(L, 1); lua_newtable(L); /* create it */ lua_pushstring(L, libname); lua_pushvalue(L, -2); lua_settable(L, LUA_GLOBALSINDEX); /* register it with given name */ } lua_insert(L, -(nup+1)); /* move library table to below upvalues */ } for (; l->name; l++) { int i; lua_pushstring(L, l->name); for (i=0; i<nup; i++) /* copy upvalues to the top */ lua_pushvalue(L, -(nup+1)); lua_pushcclosure(L, l->func, nup); lua_settable(L, -(nup+3)); } lua_pop(L, nup); /* remove upvalues */ } /* ** {====================================================== ** getn-setn: size for arrays ** ======================================================= */ static int checkint (lua_State *L, int topop) { int n = (int)lua_tonumber(L, -1); if (n == 0 && !lua_isnumber(L, -1)) n = -1; lua_pop(L, topop); return n; } static void getsizes (lua_State *L) { lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); if (lua_isnil(L, -1)) { /* no `size' table? */ lua_pop(L, 1); /* remove nil */ lua_newtable(L); /* create it */ lua_pushvalue(L, -1); /* `size' will be its own metatable */ lua_setmetatable(L, -2); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "k"); lua_rawset(L, -3); /* metatable(N).__mode = "k" */ lua_pushvalue(L, -1); lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */ } } void luaL_setn (lua_State *L, int t, int n) { t = abs_index(L, t); lua_pushliteral(L, "n"); lua_rawget(L, t); if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ lua_pushliteral(L, "n"); /* use it */ lua_pushnumber(L, (lua_Number)n); lua_rawset(L, t); } else { /* use `sizes' */ getsizes(L); lua_pushvalue(L, t); lua_pushnumber(L, (lua_Number)n); lua_rawset(L, -3); /* sizes[t] = n */ lua_pop(L, 1); /* remove `sizes' */ } } int luaL_getn (lua_State *L, int t) { int n; t = abs_index(L, t); lua_pushliteral(L, "n"); /* try t.n */ lua_rawget(L, t); if ((n = checkint(L, 1)) >= 0) return n; getsizes(L); /* else try sizes[t] */ lua_pushvalue(L, t); lua_rawget(L, -2); if ((n = checkint(L, 2)) >= 0) return n; for (n = 1; ; n++) { /* else must count elements */ lua_rawgeti(L, t, n); if (lua_isnil(L, -1)) break; lua_pop(L, 1); } lua_pop(L, 1); return n - 1; } /* }====================================================== */ /* ** {====================================================== ** Generic Buffer manipulation ** ======================================================= */ #define bufflen(B) ((B)->p - (B)->buffer) #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) #define LIMIT (LUA_MINSTACK/2) static int emptybuffer (luaL_Buffer *B) { size_t l = bufflen(B); if (l == 0) return 0; /* put nothing on stack */ else { lua_pushlstring(B->L, B->buffer, l); B->p = B->buffer; B->lvl++; return 1; } } static void adjuststack (luaL_Buffer *B) { if (B->lvl > 1) { lua_State *L = B->L; int toget = 1; /* number of levels to concat */ size_t toplen = lua_strlen(L, -1); do { size_t l = lua_strlen(L, -(toget+1)); if (B->lvl - toget + 1 >= LIMIT || toplen > l) { toplen += l; toget++; } else break; } while (toget < B->lvl); lua_concat(L, toget); B->lvl = B->lvl - toget + 1; } } LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { if (emptybuffer(B)) adjuststack(B); return B->buffer; } LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { while (l--) luaL_putchar(B, *s++); } LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { luaL_addlstring(B, s, strlen(s)); } LUALIB_API void luaL_pushresult (luaL_Buffer *B) { emptybuffer(B); lua_concat(B->L, B->lvl); B->lvl = 1; } LUALIB_API void luaL_addvalue (luaL_Buffer *B) { lua_State *L = B->L; size_t vl = lua_strlen(L, -1); if (vl <= bufffree(B)) { /* fit into buffer? */ memcpy(B->p, lua_tostring(L, -1), vl); /* put it there */ B->p += vl; lua_pop(L, 1); /* remove from stack */ } else { if (emptybuffer(B)) lua_insert(L, -2); /* put buffer before new value */ B->lvl++; /* add new value into B stack */ adjuststack(B); } } LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { B->L = L; B->p = B->buffer; B->lvl = 0; } /* }====================================================== */ LUALIB_API int luaL_ref (lua_State *L, int t) { int ref; t = abs_index(L, t); if (lua_isnil(L, -1)) { lua_pop(L, 1); /* remove from stack */ return LUA_REFNIL; /* `nil' has a unique fixed reference */ } lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ ref = (int)lua_tonumber(L, -1); /* ref = t[FREELIST_REF] */ lua_pop(L, 1); /* remove it from stack */ if (ref != 0) { /* any free element? */ lua_rawgeti(L, t, ref); /* remove it from list */ lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ } else { /* no free elements */ ref = luaL_getn(L, t); if (ref < RESERVED_REFS) ref = RESERVED_REFS; /* skip reserved references */ ref++; /* create new reference */ luaL_setn(L, t, ref); } lua_rawseti(L, t, ref); return ref; } LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { if (ref >= 0) { t = abs_index(L, t); lua_rawgeti(L, t, FREELIST_REF); lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ lua_pushnumber(L, (lua_Number)ref); lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ } } /* ** {====================================================== ** Load functions ** ======================================================= */ typedef struct LoadF { FILE *f; char buff[LUAL_BUFFERSIZE]; } LoadF; static const char *getF (lua_State *L, void *ud, size_t *size) { LoadF *lf = (LoadF *)ud; (void)L; if (feof(lf->f)) return NULL; *size = fread(lf->buff, 1, LUAL_BUFFERSIZE, lf->f); return (*size > 0) ? lf->buff : NULL; } static int errfile (lua_State *L, int fnameindex) { const char *filename = lua_tostring(L, fnameindex) + 1; lua_pushfstring(L, "cannot read %s: %s", filename, strerror(errno)); lua_remove(L, fnameindex); return LUA_ERRFILE; } LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { LoadF lf; int status, readstatus; int c; int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ if (filename == NULL) { lua_pushliteral(L, "=stdin"); lf.f = stdin; } else { lua_pushfstring(L, "@%s", filename); lf.f = fopen(filename, "r"); } if (lf.f == NULL) return errfile(L, fnameindex); /* unable to open file */ c = ungetc(getc(lf.f), lf.f); if (!(isspace(c) || isprint(c)) && lf.f != stdin) { /* binary file? */ fclose(lf.f); lf.f = fopen(filename, "rb"); /* reopen in binary mode */ if (lf.f == NULL) return errfile(L, fnameindex); /* unable to reopen file */ } status = lua_load(L, getF, &lf, lua_tostring(L, -1)); readstatus = ferror(lf.f); if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */ if (readstatus) { lua_settop(L, fnameindex); /* ignore results from `lua_load' */ return errfile(L, fnameindex); } lua_remove(L, fnameindex); return status; } typedef struct LoadS { const char *s; size_t size; } LoadS; static const char *getS (lua_State *L, void *ud, size_t *size) { LoadS *ls = (LoadS *)ud; (void)L; if (ls->size == 0) return NULL; *size = ls->size; ls->size = 0; return ls->s; } LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, const char *name) { LoadS ls; ls.s = buff; ls.size = size; return lua_load(L, getS, &ls, name); } /* }====================================================== */ /* ** {====================================================== ** compatibility code ** ======================================================= */ static void callalert (lua_State *L, int status) { if (status != 0) { lua_getglobal(L, "_ALERT"); if (lua_isfunction(L, -1)) { lua_insert(L, -2); lua_call(L, 1, 0); } else { /* no _ALERT function; print it on stderr */ fprintf(stderr, "%s\n", lua_tostring(L, -2)); lua_pop(L, 2); /* remove error message and _ALERT */ } } } static int aux_do (lua_State *L, int status) { if (status == 0) { /* parse OK? */ status = lua_pcall(L, 0, LUA_MULTRET, 0); /* call main */ } callalert(L, status); return status; } LUALIB_API int lua_dofile (lua_State *L, const char *filename) { return aux_do(L, luaL_loadfile(L, filename)); } LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name) { return aux_do(L, luaL_loadbuffer(L, buff, size, name)); } LUALIB_API int lua_dostring (lua_State *L, const char *str) { return lua_dobuffer(L, str, strlen(str), str); } /* }====================================================== */ --- NEW FILE: lbaselib.c --- /* ** $Id: lbaselib.c,v 1.1 2003/11/19 08:18:34 yurand Exp $ ** Basic library ** See Copyright Notice in lua.h */ #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define lbaselib_c #include "lua.h" #include "lauxlib.h" #include "lualib.h" /* ** If your system does not support `stdout', you can just remove this function. ** If you need, you can define your own `print' function, following this ** model but changing `fputs' to put the strings at a proper place ** (a console window or a log file, for instance). */ static int luaB_print (lua_State *L) { int n = lua_gettop(L); /* number of arguments */ int i; lua_getglobal(L, "tostring"); for (i=1; i<=n; i++) { const char *s; lua_pushvalue(L, -1); /* function to be called */ lua_pushvalue(L, i); /* value to print */ lua_call(L, 1, 1); s = lua_tostring(L, -1); /* get result */ if (s == NULL) return luaL_error(L, "`tostring' must return a string to `print'"); if (i>1) fputs("\t", stdout); fputs(s, stdout); lua_pop(L, 1); /* pop result */ } fputs("\n", stdout); return 0; } static int luaB_tonumber (lua_State *L) { int base = luaL_optint(L, 2, 10); if (base == 10) { /* standard conversion */ luaL_checkany(L, 1); if (lua_isnumber(L, 1)) { lua_pushnumber(L, lua_tonumber(L, 1)); return 1; } } else { const char *s1 = luaL_checkstring(L, 1); char *s2; unsigned long n; luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); n = strtoul(s1, &s2, base); if (s1 != s2) { /* at least one valid digit? */ while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ if (*s2 == '\0') { /* no invalid trailing characters? */ lua_pushnumber(L, (lua_Number)n); return 1; } } } lua_pushnil(L); /* else not a number */ return 1; } static int luaB_error (lua_State *L) { int level = luaL_optint(L, 2, 1); luaL_checkany(L, 1); if (!lua_isstring(L, 1) || level == 0) lua_pushvalue(L, 1); /* propagate error message without changes */ else { /* add extra information */ luaL_where(L, level); lua_pushvalue(L, 1); lua_concat(L, 2); } return lua_error(L); } static int luaB_getmetatable (lua_State *L) { luaL_checkany(L, 1); if (!lua_getmetatable(L, 1)) { lua_pushnil(L); return 1; /* no metatable */ } luaL_getmetafield(L, 1, "__metatable"); return 1; /* returns either __metatable field (if present) or metatable */ } static int luaB_setmetatable (lua_State *L) { int t = lua_type(L, 2); luaL_checktype(L, 1, LUA_TTABLE); luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table expected"); if (luaL_getmetafield(L, 1, "__metatable")) luaL_error(L, "cannot change a protected metatable"); lua_settop(L, 2); lua_setmetatable(L, 1); return 1; } static void getfunc (lua_State *L) { if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); else { lua_Debug ar; int level = luaL_optint(L, 1, 1); luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); if (lua_getstack(L, level, &ar) == 0) luaL_argerror(L, 1, "invalid level"); lua_getinfo(L, "f", &ar); if (lua_isnil(L, -1)) luaL_error(L, "no function environment for tail call at level %d", level); } } static int aux_getfenv (lua_State *L) { lua_getfenv(L, -1); lua_pushliteral(L, "__fenv"); lua_rawget(L, -2); return !lua_isnil(L, -1); } static int luaB_getfenv (lua_State *L) { getfunc(L); if (!aux_getfenv(L)) /* __fenv not defined? */ lua_pop(L, 1); /* remove it, to return real environment */ return 1; } static int luaB_setfenv (lua_State *L) { luaL_checktype(L, 2, LUA_TTABLE); getfunc(L); if (aux_getfenv(L)) /* __fenv defined? */ luaL_error(L, "`setfenv' cannot change a protected environment"); else lua_pop(L, 2); /* remove __fenv and real environment table */ lua_pushvalue(L, 2); if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) lua_replace(L, LUA_GLOBALSINDEX); else if (lua_setfenv(L, -2) == 0) luaL_error(L, "`setfenv' cannot change environment of given function"); return 0; } static int luaB_rawequal (lua_State *L) { luaL_checkany(L, 1); luaL_checkany(L, 2); lua_pushboolean(L, lua_rawequal(L, 1, 2)); return 1; } static int luaB_rawget (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_checkany(L, 2); lua_rawget(L, 1); return 1; } static int luaB_rawset (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_checkany(L, 2); luaL_checkany(L, 3); lua_rawset(L, 1); return 1; } static int luaB_gcinfo (lua_State *L) { lua_pushnumber(L, (lua_Number)lua_getgccount(L)); lua_pushnumber(L, (lua_Number)lua_getgcthreshold(L)); return 2; } static int luaB_collectgarbage (lua_State *L) { lua_setgcthreshold(L, luaL_optint(L, 1, 0)); return 0; } static int luaB_type (lua_State *L) { luaL_checkany(L, 1); lua_pushstring(L, lua_typename(L, lua_type(L, 1))); return 1; } static int luaB_next (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 2); /* create a 2nd argument if there isn't one */ if (lua_next(L, 1)) return 2; else { lua_pushnil(L); return 1; } } static int luaB_pairs (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); lua_pushliteral(L, "next"); lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */ lua_pushvalue(L, 1); /* state, */ lua_pushnil(L); /* and initial value */ return 3; } static int luaB_ipairs (lua_State *L) { lua_Number i = lua_tonumber(L, 2); luaL_checktype(L, 1, LUA_TTABLE); if (i == 0 && lua_isnone(L, 2)) { /* `for' start? */ lua_pushliteral(L, "ipairs"); lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */ lua_pushvalue(L, 1); /* state, */ lua_pushnumber(L, 0); /* and initial value */ return 3; } else { /* `for' step */ i++; /* next value */ lua_pushnumber(L, i); lua_rawgeti(L, 1, (int)i); return (lua_isnil(L, -1)) ? 0 : 2; } } static int load_aux (lua_State *L, int status) { if (status == 0) /* OK? */ return 1; else { lua_pushnil(L); lua_insert(L, -2); /* put before error message */ return 2; /* return nil plus error message */ } } static int luaB_loadstring (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); const char *chunkname = luaL_optstring(L, 2, s); return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); } static int luaB_loadfile (lua_State *L) { const char *fname = luaL_optstring(L, 1, NULL); return load_aux(L, luaL_loadfile(L, fname)); } static int luaB_dofile (lua_State *L) { const char *fname = luaL_optstring(L, 1, NULL); int status = luaL_loadfile(L, fname); if (status != 0) lua_error(L); lua_call(L, 0, LUA_MULTRET); return lua_gettop(L) - 1; } static int luaB_assert (lua_State *L) { luaL_checkany(L, 1); if (!lua_toboolean(L, 1)) return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); lua_settop(L, 1); return 1; } static int luaB_unpack (lua_State *L) { int n, i; luaL_checktype(L, 1, LUA_TTABLE); n = luaL_getn(L, 1); luaL_checkstack(L, n, "table too big to unpack"); for (i=1; i<=n; i++) /* push arg[1...n] */ lua_rawgeti(L, 1, i); return n; } static int luaB_pcall (lua_State *L) { int status; luaL_checkany(L, 1); status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); lua_pushboolean(L, (status == 0)); lua_insert(L, 1); return lua_gettop(L); /* return status + all results */ } static int luaB_xpcall (lua_State *L) { int status; luaL_checkany(L, 2); lua_settop(L, 2); lua_insert(L, 1); /* put error function under function to be called */ status = lua_pcall(L, 0, LUA_MULTRET, 1); lua_pushboolean(L, (status == 0)); lua_replace(L, 1); return lua_gettop(L); /* return status + all results */ } static int luaB_tostring (lua_State *L) { char buff[64]; luaL_checkany(L, 1); if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ return 1; /* use its value */ switch (lua_type(L, 1)) { case LUA_TNUMBER: lua_pushstring(L, lua_tostring(L, 1)); return 1; case LUA_TSTRING: lua_pushvalue(L, 1); return 1; case LUA_TBOOLEAN: lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); return 1; case LUA_TTABLE: sprintf(buff, "table: %p", lua_topointer(L, 1)); break; case LUA_TFUNCTION: sprintf(buff, "function: %p", lua_topointer(L, 1)); break; case LUA_TUSERDATA: case LUA_TLIGHTUSERDATA: sprintf(buff, "userdata: %p", lua_touserdata(L, 1)); break; case LUA_TTHREAD: sprintf(buff, "thread: %p", (void *)lua_tothread(L, 1)); break; case LUA_TNIL: lua_pushliteral(L, "nil"); return 1; } lua_pushstring(L, buff); return 1; } static int luaB_newproxy (lua_State *L) { lua_settop(L, 1); lua_newuserdata(L, 0); /* create proxy */ if (lua_toboolean(L, 1) == 0) return 1; /* no metatable */ else if (lua_isboolean(L, 1)) { lua_newtable(L); /* create a new metatable `m' ... */ lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ lua_pushboolean(L, 1); lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ } else { int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ if (lua_getmetatable(L, 1)) { lua_rawget(L, lua_upvalueindex(1)); validproxy = lua_toboolean(L, -1); lua_pop(L, 1); /* remove value */ } luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); lua_getmetatable(L, 1); /* metatable is valid; get it */ } lua_setmetatable(L, 2); return 1; } /* ** {====================================================== ** `require' function ** ======================================================= */ /* name of global that holds table with loaded packages */ #define REQTAB "_LOADED" /* name of global that holds the search path for packages */ #define LUA_PATH "LUA_PATH" #ifndef LUA_PATH_SEP #define LUA_PATH_SEP ';' #endif #ifndef LUA_PATH_MARK #define LUA_PATH_MARK '?' #endif #ifndef LUA_PATH_DEFAULT #define LUA_PATH_DEFAULT "?;?.lua" #endif static const char *getpath (lua_State *L) { const char *path; lua_getglobal(L, LUA_PATH); /* try global variable */ path = lua_tostring(L, -1); lua_pop(L, 1); if (path) return path; path = getenv(LUA_PATH); /* else try environment variable */ if (path) return path; return LUA_PATH_DEFAULT; /* else use default */ } static const char *pushnextpath (lua_State *L, const char *path) { const char *l; if (*path == '\0') return NULL; /* no more paths */ if (*path == LUA_PATH_SEP) path++; /* skip separator */ l = strchr(path, LUA_PATH_SEP); /* find next separator */ if (l == NULL) l = path+strlen(path); lua_pushlstring(L, path, l - path); /* directory name */ return l; } static void pushcomposename (lua_State *L) { const char *path = lua_tostring(L, -1); const char *wild; int n = 1; while ((wild = strchr(path, LUA_PATH_MARK)) != NULL) { /* is there stack space for prefix, name, and eventual last sufix? */ luaL_checkstack(L, 3, "too many marks in a path component"); lua_pushlstring(L, path, wild - path); /* push prefix */ lua_pushvalue(L, 1); /* push package name (in place of MARK) */ path = wild + 1; /* continue after MARK */ n += 2; } lua_pushstring(L, path); /* push last sufix (`n' already includes this) */ lua_concat(L, n); } static int luaB_require (lua_State *L) { const char *path; int status = LUA_ERRFILE; /* not found (yet) */ luaL_checkstring(L, 1); lua_settop(L, 1); lua_getglobal(L, REQTAB); if (!lua_istable(L, 2)) return luaL_error(L, "`" REQTAB "' is not a table"); path = getpath(L); lua_pushvalue(L, 1); /* check package's name in book-keeping table */ lua_rawget(L, 2); if (lua_toboolean(L, -1)) /* is it there? */ return 1; /* package is already loaded; return its result */ else { /* must load it */ while (status == LUA_ERRFILE) { lua_settop(L, 3); /* reset stack position */ if ((path = pushnextpath(L, path)) == NULL) break; pushcomposename(L); status = luaL_loadfile(L, lua_tostring(L, -1)); /* try to load it */ } } switch (status) { case 0: { lua_getglobal(L, "_REQUIREDNAME"); /* save previous name */ lua_insert(L, -2); /* put it below function */ lua_pushvalue(L, 1); lua_setglobal(L, "_REQUIREDNAME"); /* set new name */ lua_call(L, 0, 1); /* run loaded module */ lua_insert(L, -2); /* put result below previous name */ lua_setglobal(L, "_REQUIREDNAME"); /* reset to previous name */ if (lua_isnil(L, -1)) { /* no/nil return? */ lua_pushboolean(L, 1); lua_replace(L, -2); /* replace to true */ } lua_pushvalue(L, 1); lua_pushvalue(L, -2); lua_rawset(L, 2); /* mark it as loaded */ return 1; /* return value */ } case LUA_ERRFILE: { /* file not found */ return luaL_error(L, "could not load package `%s' from path `%s'", lua_tostring(L, 1), getpath(L)); } default: { return luaL_error(L, "error loading package `%s' (%s)", lua_tostring(L, 1), lua_tostring(L, -1)); } } } /* }====================================================== */ static const luaL_reg base_funcs[] = { {"error", luaB_error}, {"getmetatable", luaB_getmetatable}, {"setmetatable", luaB_setmetatable}, {"getfenv", luaB_getfenv}, {"setfenv", luaB_setfenv}, {"next", luaB_next}, {"ipairs", luaB_ipairs}, {"pairs", luaB_pairs}, {"print", luaB_print}, {"tonumber", luaB_tonumber}, {"tostring", luaB_tostring}, {"type", luaB_type}, {"assert", luaB_assert}, {"unpack", luaB_unpack}, {"rawequal", luaB_rawequal}, {"rawget", luaB_rawget}, {"rawset", luaB_rawset}, {"pcall", luaB_pcall}, {"xpcall", luaB_xpcall}, {"collectgarbage", luaB_collectgarbage}, {"gcinfo", luaB_gcinfo}, {"loadfile", luaB_loadfile}, {"dofile", luaB_dofile}, {"loadstring", luaB_loadstring}, {"require", luaB_require}, {NULL, NULL} }; /* ** {====================================================== ** Coroutine library ** ======================================================= */ static int auxresume (lua_State *L, lua_State *co, int narg) { int status; if (!lua_checkstack(co, narg)) luaL_error(L, "too many arguments to resume"); lua_xmove(L, co, narg); status = lua_resume(co, narg); if (status == 0) { int nres = lua_gettop(co); if (!lua_checkstack(L, nres)) luaL_error(L, "too many results to resume"); lua_xmove(co, L, nres); /* move yielded values */ return nres; } else { lua_xmove(co, L, 1); /* move error message */ return -1; /* error flag */ } } static int luaB_coresume (lua_State *L) { lua_State *co = lua_tothread(L, 1); int r; luaL_argcheck(L, co, 1, "coroutine expected"); r = auxresume(L, co, lua_gettop(L) - 1); if (r < 0) { lua_pushboolean(L, 0); lua_insert(L, -2); return 2; /* return false + error message */ } else { lua_pushboolean(L, 1); lua_insert(L, -(r + 1)); return r + 1; /* return true + `resume' returns */ } } static int luaB_auxwrap (lua_State *L) { lua_State *co = lua_tothread(L, lua_upvalueindex(1)); int r = auxresume(L, co, lua_gettop(L)); if (r < 0) { if (lua_isstring(L, -1)) { /* error object is a string? */ luaL_where(L, 1); /* add extra info */ lua_insert(L, -2); lua_concat(L, 2); } lua_error(L); /* propagate error */ } return r; } static int luaB_cocreate (lua_State *L) { lua_State *NL = lua_newthread(L); luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, "Lua function expected"); lua_pushvalue(L, 1); /* move function to top */ lua_xmove(L, NL, 1); /* move function from L to NL */ return 1; } static int luaB_cowrap (lua_State *L) { luaB_cocreate(L); lua_pushcclosure(L, luaB_auxwrap, 1); return 1; } static int luaB_yield (lua_State *L) { return lua_yield(L, lua_gettop(L)); } static int luaB_costatus (lua_State *L) { lua_State *co = lua_tothread(L, 1); luaL_argcheck(L, co, 1, "coroutine expected"); if (L == co) lua_pushliteral(L, "running"); else { lua_Debug ar; if (lua_getstack(co, 0, &ar) == 0 && lua_gettop(co) == 0) lua_pushliteral(L, "dead"); else lua_pushliteral(L, "suspended"); } return 1; } static const luaL_reg co_funcs[] = { {"create", luaB_cocreate}, {"wrap", luaB_cowrap}, {"resume", luaB_coresume}, {"yield", luaB_yield}, {"status", luaB_costatus}, {NULL, NULL} }; /* }====================================================== */ static void base_open (lua_State *L) { lua_pushliteral(L, "_G"); lua_pushvalue(L, LUA_GLOBALSINDEX); luaL_openlib(L, NULL, base_funcs, 0); /* open lib into global table */ lua_pushliteral(L, "_VERSION"); lua_pushliteral(L, LUA_VERSION); lua_rawset(L, -3); /* set global _VERSION */ /* `newproxy' needs a weaktable as upvalue */ lua_pushliteral(L, "newproxy"); lua_newtable(L); /* new table `w' */ lua_pushvalue(L, -1); /* `w' will be its own metatable */ lua_setmetatable(L, -2); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "k"); lua_rawset(L, -3); /* metatable(w).__mode = "k" */ lua_pushcclosure(L, luaB_newproxy, 1); lua_rawset(L, -3); /* set global `newproxy' */ lua_rawset(L, -1); /* set global _G */ } LUALIB_API int luaopen_base (lua_State *L) { base_open(L); luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0); lua_newtable(L); lua_setglobal(L, REQTAB); return 0; } --- NEW FILE: ldblib.c --- /* ** $Id: ldblib.c,v 1.1 2003/11/19 08:18:34 yurand Exp $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define ldblib_c #include "lua.h" #include "lauxlib.h" #include "lualib.h" static void settabss (lua_State *L, const char *i, const char *v) { lua_pushstring(L, i); lua_pushstring(L, v); lua_rawset(L, -3); } static void settabsi (lua_State *L, const char *i, int v) { lua_pushstring(L, i); lua_pushnumber(L, (lua_Number)v); lua_rawset(L, -3); } static int getinfo (lua_State *L) { lua_Debug ar; const char *options = luaL_optstring(L, 2, "flnSu"); if (lua_isnumber(L, 1)) { if (!lua_getstack(L, (int)(lua_tonumber(L, 1)), &ar)) { lua_pushnil(L); /* level out of range */ return 1; } } else if (lua_isfunction(L, 1)) { lua_pushfstring(L, ">%s", options); options = lua_tostring(L, -1); lua_pushvalue(L, 1); } else return luaL_argerror(L, 1, "function or level expected"); if (!lua_getinfo(L, options, &ar)) return luaL_argerror(L, 2, "invalid option"); lua_newtable(L); for (; *options; options++) { switch (*options) { case 'S': settabss(L, "source", ar.source); settabss(L, "short_src", ar.short_src); settabsi(L, "linedefined", ar.linedefined); settabss(L, "what", ar.what); break; case 'l': settabsi(L, "currentline", ar.currentline); break; case 'u': settabsi(L, "nups", ar.nups); break; case 'n': settabss(L, "name", ar.name); settabss(L, "namewhat", ar.namewhat); break; case 'f': lua_pushliteral(L, "func"); lua_pushvalue(L, -3); lua_rawset(L, -3); break; } } return 1; /* return table */ } static int getlocal (lua_State *L) { lua_Debug ar; const char *name; if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */ return luaL_argerror(L, 1, "level out of range"); name = lua_getlocal(L, &ar, luaL_checkint(L, 2)); if (name) { lua_pushstring(L, name); lua_pushvalue(L, -2); return 2; } else { lua_pushnil(L); return 1; } } static int setlocal (lua_State *L) { lua_Debug ar; if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */ return luaL_argerror(L, 1, "level out of range"); luaL_checkany(L, 3); lua_pushstring(L, lua_setlocal(L, &ar, luaL_checkint(L, 2))); return 1; } static int auxupvalue (lua_State *L, int get) { const char *name; int n = luaL_checkint(L, 2); luaL_checktype(L, 1, LUA_TFUNCTION); if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); if (name == NULL) return 0; lua_pushstring(L, name); lua_insert(L, -(get+1)); return get + 1; } static int getupvalue (lua_State *L) { return auxupvalue(L, 1); } static int setupvalue (lua_State *L) { luaL_checkany(L, 3); return auxupvalue(L, 0); } static const char KEY_HOOK = 'h'; static void hookf (lua_State *L, lua_Debug *ar) { static const char *const hooknames[] = {"call", "return", "line", "count", "tail return"}; lua_pushlightuserdata(L, (void *)&KEY_HOOK); lua_rawget(L, LUA_REGISTRYINDEX); if (lua_isfunction(L, -1)) { lua_pushstring(L, hooknames[(int)ar->event]); if (ar->currentline >= 0) lua_pushnumber(L, (lua_Number)ar->currentline); else lua_pushnil(L); lua_assert(lua_getinfo(L, "lS", ar)); lua_call(L, 2, 0); } else lua_pop(L, 1); /* pop result from gettable */ } static int makemask (const char *smask, int count) { int mask = 0; if (strchr(smask, 'c')) mask |= LUA_MASKCALL; if (strchr(smask, 'r')) mask |= LUA_MASKRET; if (strchr(smask, 'l')) mask |= LUA_MASKLINE; if (count > 0) mask |= LUA_MASKCOUNT; return mask; } static char *unmakemask (int mask, char *smask) { int i = 0; if (mask & LUA_MASKCALL) smask[i++] = 'c'; if (mask & LUA_MASKRET) smask[i++] = 'r'; if (mask & LUA_MASKLINE) smask[i++] = 'l'; smask[i] = '\0'; return smask; } static int sethook (lua_State *L) { if (lua_isnoneornil(L, 1)) { lua_settop(L, 1); lua_sethook(L, NULL, 0, 0); /* turn off hooks */ } else { const char *smask = luaL_checkstring(L, 2); int count = luaL_optint(L, 3, 0); luaL_checktype(L, 1, LUA_TFUNCTION); lua_sethook(L, hookf, makemask(smask, count), count); } lua_pushlightuserdata(L, (void *)&KEY_HOOK); lua_pushvalue(L, 1); lua_rawset(L, LUA_REGISTRYINDEX); /* set new hook */ return 0; } static int gethook (lua_State *L) { char buff[5]; int mask = lua_gethookmask(L); lua_Hook hook = lua_gethook(L); if (hook != NULL && hook != hookf) /* external hook? */ lua_pushliteral(L, "external hook"); else { lua_pushlightuserdata(L, (void *)&KEY_HOOK); lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */ } lua_pushstring(L, unmakemask(mask, buff)); lua_pushnumber(L, (lua_Number)lua_gethookcount(L)); return 3; } static int debug (lua_State *L) { for (;;) { char buffer[250]; fputs("lua_debug> ", stderr); if (fgets(buffer, sizeof(buffer), stdin) == 0 || strcmp(buffer, "cont\n") == 0) return 0; lua_dostring(L, buffer); lua_settop(L, 0); /* remove eventual returns */ } } #define LEVELS1 12 /* size of the first part of the stack */ #define LEVELS2 10 /* size of the second part of the stack */ static int errorfb (lua_State *L) { int level = 1; /* skip level 0 (it's this function) */ int firstpart = 1; /* still before eventual `...' */ lua_Debug ar; if (lua_gettop(L) == 0) lua_pushliteral(L, ""); else if (!lua_isstring(L, 1)) return 1; /* no string message */ else lua_pushliteral(L, "\n"); lua_pushliteral(L, "stack traceback:"); while (lua_getstack(L, level++, &ar)) { if (level > LEVELS1 && firstpart) { /* no more than `LEVELS2' more levels? */ if (!lua_getstack(L, level+LEVELS2, &ar)) level--; /* keep going */ else { lua_pushliteral(L, "\n\t..."); /* too many levels */ while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */ level++; } firstpart = 0; continue; } lua_pushliteral(L, "\n\t"); lua_getinfo(L, "Snl", &ar); lua_pushfstring(L, "%s:", ar.short_src); if (ar.currentline > 0) lua_pushfstring(L, "%d:", ar.currentline); switch (*ar.namewhat) { case 'g': /* global */ case 'l': /* local */ case 'f': /* field */ case 'm': /* method */ lua_pushfstring(L, " in function `%s'", ar.name); break; default: { if (*ar.what == 'm') /* main? */ lua_pushfstring(L, " in main chunk"); else if (*ar.what == 'C' || *ar.what == 't') lua_pushliteral(L, " ?"); /* C function or tail call */ else lua_pushfstring(L, " in function <%s:%d>", ar.short_src, ar.linedefined); } } lua_concat(L, lua_gettop(L)); } lua_concat(L, lua_gettop(L)); return 1; } static const luaL_reg dblib[] = { {"getlocal", getlocal}, {"getinfo", getinfo}, {"gethook", gethook}, {"getupvalue", getupvalue}, {"sethook", sethook}, {"setlocal", setlocal}, {"setupvalue", setupvalue}, {"debug", debug}, {"traceback", errorfb}, {NULL, NULL} }; LUALIB_API int luaopen_debug (lua_State *L) { luaL_openlib(L, LUA_DBLIBNAME, dblib, 0); lua_pushliteral(L, "_TRACEBACK"); lua_pushcfunction(L, errorfb); lua_settable(L, LUA_GLOBALSINDEX); return 1; } --- NEW FILE: liolib.c --- /* ** $Id: liolib.c,v 1.1 2003/11/19 08:18:34 yurand Exp $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ #include <errno.h> #include <locale.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define liolib_c #include "lua.h" #include "lauxlib.h" #include "lualib.h" /* ** by default, gcc does not get `tmpname' */ #ifndef USE_TMPNAME #ifdef __GNUC__ #define USE_TMPNAME 0 #else #define USE_TMPNAME 1 #endif #endif /* ** by default, posix systems get `popen' */ #ifndef USE_POPEN #ifdef _POSIX_C_SOURCE #if _POSIX_C_SOURCE >= 2 #define USE_POPEN 1 #endif #endif #endif #ifndef USE_POPEN #define USE_POPEN 0 #endif /* ** {====================================================== ** FILE Operations ** ======================================================= */ #if !USE_POPEN #define pclose(f) (-1) #endif #define FILEHANDLE "FILE*" #define IO_INPUT "_input" #define IO_OUTPUT "_output" static int pushresult (lua_State *L, int i, const char *filename) { if (i) { lua_pushboolean(L, 1); return 1; } else { lua_pushnil(L); if (filename) lua_pushfstring(L, "%s: %s", filename, strerror(errno)); else lua_pushfstring(L, "%s", strerror(errno)); lua_pushnumber(L, errno); return 3; } } static FILE **topfile (lua_State *L, int findex) { FILE **f = (FILE **)luaL_checkudata(L, findex, FILEHANDLE); if (f == NULL) luaL_argerror(L, findex, "bad file"); return f; } static int io_type (lua_State *L) { FILE **f = (FILE **)luaL_checkudata(L, 1, FILEHANDLE); if (f == NULL) lua_pushnil(L); else if (*f == NULL) lua_pushliteral(L, "closed file"); else lua_pushliteral(L, "file"); return 1; } static FILE *tofile (lua_State *L, int findex) { FILE **f = topfile(L, findex); if (*f == NULL) luaL_error(L, "attempt to use a closed file"); return *f; } /* ** When creating file handles, always creates a `closed' file handle ** before opening the actual file; so, if there is a memory error, the ** file is not left opened. */ static FILE **newfile (lua_State *L) { FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); *pf = NULL; /* file handle is currently `closed' */ luaL_getmetatable(L, FILEHANDLE); lua_setmetatable(L, -2); return pf; } /* ** assumes that top of the stack is the `io' library, and next is ** the `io' metatable */ static void registerfile (lua_State *L, FILE *f, const char *name, const char *impname) { lua_pushstring(L, name); *newfile(L) = f; if (impname) { lua_pushstring(L, impname); lua_pushvalue(L, -2); lua_settable(L, -6); /* metatable[impname] = file */ } lua_settable(L, -3); /* io[name] = file */ } static int aux_close (lua_State *L) { FILE *f = tofile(L, 1); if (f == stdin || f == stdout || f == stderr) return 0; /* file cannot be closed */ else { int ok = (pclose(f) != -1) || (fclose(f) == 0); if (ok) *(FILE **)lua_touserdata(L, 1) = NULL; /* mark file as closed */ return ok; } } static int io_close (lua_State *L) { if (lua_isnone(L, 1)) { lua_pushstring(L, IO_OUTPUT); lua_rawget(L, lua_upvalueindex(1)); } return pushresult(L, aux_close(L), NULL); } static int io_gc (lua_State *L) { FILE **f = topfile(L, 1); if (*f != NULL) /* ignore closed files */ aux_close(L); return 0; } static int io_tostring (lua_State *L) { char buff[32]; FILE **f = topfile(L, 1); if (*f == NULL) strcpy(buff, "closed"); else sprintf(buff, "%p", lua_touserdata(L, 1)); lua_pushfstring(L, "file (%s)", buff); return 1; } static int io_open (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); FILE **pf = newfile(L); *pf = fopen(filename, mode); return (*pf == NULL) ? pushresult(L, 0, filename) : 1; } static int io_popen (lua_State *L) { #if !USE_POPEN luaL_error(L, "`popen' not supported"); return 0; #else const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); FILE **pf = newfile(L); *pf = popen(filename, mode); return (*pf == NULL) ? pushresult(L, 0, filename) : 1; #endif } static int io_tmpfile (lua_State *L) { FILE **pf = newfile(L); *pf = tmpfile(); return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; } static FILE *getiofile (lua_State *L, const char *name) { lua_pushstring(L, name); lua_rawget(L, lua_upvalueindex(1)); return tofile(L, -1); } static int g_iofile (lua_State *L, const char *name, const char *mode) { if (!lua_isnoneornil(L, 1)) { const char *filename = lua_tostring(L, 1); lua_pushstring(L, name); if (filename) { FILE **pf = newfile(L); *pf = fopen(filename, mode); if (*pf == NULL) { lua_pushfstring(L, "%s: %s", filename, strerror(errno)); luaL_argerror(L, 1, lua_tostring(L, -1)); } } else { tofile(L, 1); /* check that it's a valid file handle */ lua_pushvalue(L, 1); } lua_rawset(L, lua_upvalueindex(1)); } /* return current value */ lua_pushstring(L, name); lua_rawget(L, lua_upvalueindex(1)); return 1; } static int io_input (lua_State *L) { return g_iofile(L, IO_INPUT, "r"); } static int io_output (lua_State *L) { return g_iofile(L, IO_OUTPUT, "w"); } static int io_readline (lua_State *L); static void aux_lines (lua_State *L, int idx, int close) { lua_pushliteral(L, FILEHANDLE); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushvalue(L, idx); lua_pushboolean(L, close); /* close/not close file when finished */ lua_pushcclosure(L, io_readline, 3); } static int f_lines (lua_State *L) { tofile(L, 1); /* check that it's a valid file handle */ aux_lines(L, 1, 0); return 1; } static int io_lines (lua_State *L) { if (lua_isnoneornil(L, 1)) { /* no arguments? */ lua_pushstring(L, IO_INPUT); lua_rawget(L, lua_upvalueindex(1)); /* will iterate over default input */ return f_lines(L); } else { const char *filename = luaL_checkstring(L, 1); FILE **pf = newfile(L); *pf = fopen(filename, "r"); luaL_argcheck(L, *pf, 1, strerror(errno)); aux_lines(L, lua_gettop(L), 1); return 1; } } /* ** {====================================================== ** READ ** ======================================================= */ static int read_number (lua_State *L, FILE *f) { lua_Number d; if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { lua_pushnumber(L, d); return 1; } else return 0; /* read fails */ } static int test_eof (lua_State *L, FILE *f) { int c = getc(f); ungetc(c, f); lua_pushlstring(L, NULL, 0); return (c != EOF); } static int read_line (lua_State *L, FILE *f) { luaL_Buffer b; luaL_buffinit(L, &b); for (;;) { size_t l; char *p = luaL_prepbuffer(&b); if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ luaL_pushresult(&b); /* close buffer */ return (lua_strlen(L, -1) > 0); /* check whether read something */ } l = strlen(p); if (p[l-1] != '\n') luaL_addsize(&b, l); else { luaL_addsize(&b, l - 1); /* do not include `eol' */ luaL_pushresult(&b); /* close buffer */ return 1; /* read at least an `eol' */ } } } static int read_chars (lua_State *L, FILE *f, size_t n) { size_t rlen; /* how much to read */ size_t nr; /* number of chars actually read */ luaL_Buffer b; luaL_buffinit(L, &b); rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ do { char *p = luaL_prepbuffer(&b); if (rlen > n) rlen = n; /* cannot read more than asked */ nr = fread(p, sizeof(char), rlen, f); luaL_addsize(&b, nr); n -= nr; /* still have to read `n' chars */ } while (n > 0 && nr == rlen); /* until end of count or eof */ luaL_pushresult(&b); /* close buffer */ return (n == 0 || lua_strlen(L, -1) > 0); } static int g_read (lua_State *L, FILE *f, int first) { int nargs = lua_gettop(L) - 1; int success; int n; if (nargs == 0) { /* no arguments? */ success = read_line(L, f); n = first+1; /* to return 1 result */ } else { /* ensure stack space for all results and for auxlib's buffer */ luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); success = 1; for (n = first; nargs-- && success; n++) { if (lua_type(L, n) == LUA_TNUMBER) { size_t l = (size_t)lua_tonumber(L, n); success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); } else { const char *p = lua_tostring(L, n); luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); switch (p[1]) { case 'n': /* number */ success = read_number(L, f); break; case 'l': /* line */ success = read_line(L, f); break; case 'a': /* file */ read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ success = 1; /* always success */ break; case 'w': /* word */ return luaL_error(L, "obsolete option `*w' to `read'"); default: return luaL_argerror(L, n, "invalid format"); } } } } if (!success) { lua_pop(L, 1); /* remove last result */ lua_pushnil(L); /* push nil instead */ } return n - first; } static int io_read (lua_State *L) { return g_read(L, getiofile(L, IO_INPUT), 1); } static int f_read (lua_State *L) { return g_read(L, tofile(L, 1), 2); } static int io_readline (lua_State *L) { FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(2)); if (f == NULL) /* file is already closed? */ luaL_error(L, "file is already closed"); if (read_line(L, f)) return 1; else { /* EOF */ if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ lua_settop(L, 0); lua_pushvalue(L, lua_upvalueindex(2)); aux_close(L); /* close it */ } return 0; } } /* }====================================================== */ static int g_write (lua_State *L, FILE *f, int arg) { int nargs = lua_gettop(L) - 1; int status = 1; for (; nargs--; arg++) { if (lua_type(L, arg) == LUA_TNUMBER) { /* optimization: could be done exactly as for strings */ status = status && fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; } else { size_t l; const char *s = luaL_checklstring(L, arg, &l); status = status && (fwrite(s, sizeof(char), l, f) == l); } } return pushresult(L, status, NULL); } static int io_write (lua_State *L) { return g_write(L, getiofile(L, IO_OUTPUT), 1); } static int f_write (lua_State *L) { return g_write(L, tofile(L, 1), 2); } static int f_seek (lua_State *L) { static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; static const char *const modenames[] = {"set", "cur", "end", NULL}; FILE *f = tofile(L, 1); int op = luaL_findstring(luaL_optstring(L, 2, "cur"), modenames); long offset = luaL_optlong(L, 3, 0); luaL_argcheck(L, op != -1, 2, "invalid mode"); op = fseek(f, offset, mode[op]); if (op) return pushresult(L, 0, NULL); /* error */ else { lua_pushnumber(L, ftell(f)); return 1; } } static int io_flush (lua_State *L) { return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); } static int f_flush (lua_State *L) { return pushresult(L, fflush(tofile(L, 1)) == 0, NULL); } static const luaL_reg iolib[] = { {"input", io_input}, {"output", io_output}, {"lines", io_lines}, {"close", io_close}, {"flush", io_flush}, {"open", io_open}, {"popen", io_popen}, {"read", io_read}, {"tmpfile", io_tmpfile}, {"type", io_type}, {"write", io_write}, {NULL, NULL} }; static const luaL_reg flib[] = { {"flush", f_flush}, {"read", f_read}, {"lines", f_lines}, {"seek", f_seek}, {"write", f_write}, {"close", io_close}, {"__gc", io_gc}, {"__tostring", io_tostring}, {NULL, NULL} }; static void createmeta (lua_State *L) { luaL_newmetatable(L, FILEHANDLE); /* create new metatable for file handles */ /* file methods */ lua_pushliteral(L, "__index"); lua_pushvalue(L, -2); /* push metatable */ lua_rawset(L, -3); /* metatable.__index = metatable */ luaL_openlib(L, NULL, flib, 0); } /* }====================================================== */ /* ** {====================================================== ** Other O.S. Operations ** ======================================================= */ static int io_execute (lua_State *L) { lua_pushnumber(L, system(luaL_checkstring(L, 1))); return 1; } static int io_remove (lua_State *L) { const char *filename = luaL_checkstring(L, 1); return pushresult(L, remove(filename) == 0, filename); } static int io_rename (lua_State *L) { const char *fromname = luaL_checkstring(L, 1); const char *toname = luaL_checkstring(L, 2); return pushresult(L, rename(fromname, toname) == 0, fromname); } static int io_tmpname (lua_State *L) { #if !USE_TMPNAME luaL_error(L, "`tmpname' not supported"); return 0; #else char buff[L_tmpnam]; if (tmpnam(buff) != buff) return luaL_error(L, "unable to generate a unique filename in `tmpname'"); lua_pushstring(L, buff); return 1; #endif } static int io_getenv (lua_State *L) { lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ return 1; } static int io_clock (lua_State *L) { lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); return 1; } /* ** {====================================================== ** Time/Date operations ** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, ** wday=%w+1, yday=%j, isdst=? } ** ======================================================= */ static void setfield (lua_State *L, const char *key, int value) { lua_pushstring(L, key); lua_pushnumber(L, value); lua_rawset(L, -3); } static void setboolfield (lua_State *L, const char *key, int value) { lua_pushstring(L, key); lua_pushboolean(L, value); lua_rawset(L, -3); } static int getboolfield (lua_State *L, const char *key) { int res; lua_pushstring(L, key); lua_gettable(L, -2); res = lua_toboolean(L, -1); lua_pop(L, 1); return res; } static int getfield (lua_State *L, const char *key, int d) { int res; lua_pushstring(L, key); lua_gettable(L, -2); if (lua_isnumber(L, -1)) res = (int)(lua_tonumber(L, -1)); else { if (d == -2) return luaL_error(L, "field `%s' missing in date table", key); res = d; } lua_pop(L, 1); return res; } static int io_date (lua_State *L) { const char *s = luaL_optstring(L, 1, "%c"); time_t t = (time_t)(luaL_optnumber(L, 2, -1)); struct tm *stm; if (t == (time_t)(-1)) /* no time given? */ t = time(NULL); /* use current time */ if (*s == '!') { /* UTC? */ stm = gmtime(&t); s++; /* skip `!' */ } else stm = localtime(&t); if (stm == NULL) /* invalid date? */ lua_pushnil(L); else if (strcmp(s, "*t") == 0) { lua_newtable(L); setfield(L, "sec", stm->tm_sec); setfield(L, "min", stm->tm_min); setfield(L, "hour", stm->tm_hour); setfield(L, "day", stm->tm_mday); setfield(L, "month", stm->tm_mon+1); setfield(L, "year", stm->tm_year+1900); setfield(L, "wday", stm->tm_wday+1); setfield(L, "yday", stm->tm_yday+1); setboolfield(L, "isdst", stm->tm_isdst); } else { char b[256]; if (strftime(b, sizeof(b), s, stm)) lua_pushstring(L, b); else return luaL_error(L, "`date' format too long"); } return 1; } static int io_time (lua_State *L) { if (lua_isnoneornil(L, 1)) /* called without args? */ lua_pushnumber(L, time(NULL)); /* return current time */ else { time_t t; struct tm ts; luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 1); /* make sure table is at the top */ ts.tm_sec = getfield(L, "sec", 0); ts.tm_min = getfield(L, "min", 0); ts.tm_hour = getfield(L, "hour", 12); ts.tm_mday = getfield(L, "day", -2); ts.tm_mon = getfield(L, "month", -2) - 1; ts.tm_year = getfield(L, "year", -2) - 1900; ts.tm_isdst = getboolfield(L, "isdst"); t = mktime(&ts); if (t == (time_t)(-1)) lua_pushnil(L); else lua_pushnumber(L, t); } return 1; } static int io_difftime (lua_State *L) { lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), (time_t)(luaL_optnumber(L, 2, 0)))); return 1; } /* }====================================================== */ static int io_setloc (lua_State *L) { static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME}; static const char *const catnames[] = {"all", "collate", "ctype", "monetary", "numeric", "time", NULL}; const char *l = lua_tostring(L, 1); int op = luaL_findstring(luaL_optstring(L, 2, "all"), catnames); luaL_argcheck(L, l || lua_isnoneornil(L, 1), 1, "string expected"); luaL_argcheck(L, op != -1, 2, "invalid option"); lua_pushstring(L, setlocale(cat[op], l)); return 1; } static int io_exit (lua_State *L) { exit(luaL_optint(L, 1, EXIT_SUCCESS)); return 0; /* to avoid warnings */ } static const luaL_reg syslib[] = { {"clock", io_clock}, {"date", io_date}, {"difftime", io_difftime}, {"execute", io_execute}, {"exit", io_exit}, {"getenv", io_getenv}, {"remove", io_remove}, {"rename", io_rename}, {"setlocale", io_setloc}, {"time", io_time}, {"tmpname", io_tmpname}, {NULL, NULL} }; /* }====================================================== */ LUALIB_API int luaopen_io (lua_State *L) { luaL_openlib(L, LUA_OSLIBNAME, syslib, 0); createmeta(L); lua_pushvalue(L, -1); luaL_openlib(L, LUA_IOLIBNAME, iolib, 1); /* put predefined file handles into `io' table */ registerfile(L, stdin, "stdin", IO_INPUT); registerfile(L, stdout, "stdout", IO_OUTPUT); registerfile(L, stderr, "stderr", NULL); return 1; } --- NEW FILE: lmathlib.c --- /* ** $Id: lmathlib.c,v 1.1 2003/11/19 08:18:34 yurand Exp $ ** Standard mathematical library ** See Copyright Notice in lua.h */ #include <stdlib.h> #include <math.h> #define lmathlib_c #include "lua.h" #include "lauxlib.h" #include "lualib.h" #undef PI #define PI (3.14159265358979323846) #define RADIANS_PER_DEGREE (PI/180.0) /* ** If you want Lua to operate in degrees (instead of radians), ** define USE_DEGREES */ #ifdef USE_DEGREES #define FROMRAD(a) ((a)/RADIANS_PER_DEGREE) #define TORAD(a) ((a)*RADIANS_PER_DEGREE) #else #define FROMRAD(a) (a) #define TORAD(a) (a) #endif static int math_abs (lua_State *L) { lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); return 1; } static int math_sin (lua_State *L) { lua_pushnumber(L, sin(TORAD(luaL_checknumber(L, 1)))); return 1; } static int math_cos (lua_State *L) { lua_pushnumber(L, cos(TORAD(luaL_checknumber(L, 1)))); return 1; } static int math_tan (lua_State *L) { lua_pushnumber(L, tan(TORAD(luaL_checknumber(L, 1)))); return 1; } static int math_asin (lua_State *L) { lua_pushnumber(L, FROMRAD(asin(luaL_checknumber(L, 1)))); return 1; } static int math_acos (lua_State *L) { lua_pushnumber(L, FROMRAD(acos(luaL_checknumber(L, 1)))); return 1; } static int math_atan (lua_State *L) { lua_pushnumber(L, FROMRAD(atan(luaL_checknumber(L, 1)))); return 1; } static int math_atan2 (lua_State *L) { lua_pushnumber(L, FROMRA... [truncated message content] |
Update of /cvsroot/timewarp/source/util/lua In directory sc8-pr-cvs1:/tmp/cvs-serv14966/source/util/lua Added Files: lapi.c lapi.h lcode.c lcode.h ldebug.c ldebug.h ldo.c ldo.h ldump.c lfunc.c lfunc.h lgc.c lgc.h llex.c llex.h llimits.h lmem.c lmem.h lobject.c lobject.h lopcodes.c lopcodes.h lparser.c lparser.h lstate.c lstate.h lstring.c lstring.h ltable.c ltable.h ltests.c ltm.c ltm.h lundump.c lundump.h lvm.c lvm.h lzio.c lzio.h Log Message: lua support --- NEW FILE: lapi.c --- /* ** $Id: lapi.c,v 1.1 2003/11/19 08:17:06 yurand Exp $ ** Lua API ** See Copyright Notice in lua.h */ #include <assert.h> #include <string.h> #define lapi_c #include "lua.h" #include "lapi.h" #include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "lgc.h" #include "lmem.h" #include "lobject.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" #include "lundump.h" #include "lvm.h" const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n" "$Authors: " LUA_AUTHORS " $\n" "$URL: www.lua.org $\n"; #ifndef api_check #define api_check(L, o) /*{ assert(o); }*/ #endif #define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) #define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} static TObject *negindex (lua_State *L, int idx) { if (idx > LUA_REGISTRYINDEX) { api_check(L, idx != 0 && -idx <= L->top - L->base); return L->top+idx; } else switch (idx) { /* pseudo-indices */ case LUA_REGISTRYINDEX: return registry(L); case LUA_GLOBALSINDEX: return gt(L); default: { TObject *func = (L->base - 1); idx = LUA_GLOBALSINDEX - idx; lua_assert(iscfunction(func)); return (idx <= clvalue(func)->c.nupvalues) ? &clvalue(func)->c.upvalue[idx-1] : NULL; } } } static TObject *luaA_index (lua_State *L, int idx) { if (idx > 0) { api_check(L, idx <= L->top - L->base); return L->base + idx - 1; } else { TObject *o = negindex(L, idx); api_check(L, o != NULL); return o; } } static TObject *luaA_indexAcceptable (lua_State *L, int idx) { if (idx > 0) { TObject *o = L->base+(idx-1); api_check(L, idx <= L->stack_last - L->base); if (o >= L->top) return NULL; else return o; } else return negindex(L, idx); } void luaA_pushobject (lua_State *L, const TObject *o) { setobj2s(L->top, o); incr_top(L); } LUA_API int lua_checkstack (lua_State *L, int size) { int res; lua_lock(L); if ((L->top - L->base + size) > LUA_MAXCSTACK) res = 0; /* stack overflow */ else { luaD_checkstack(L, size); if (L->ci->top < L->top + size) L->ci->top = L->top + size; res = 1; } lua_unlock(L); return res; } LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { int i; lua_lock(to); api_checknelems(from, n); from->top -= n; for (i = 0; i < n; i++) { setobj2s(to->top, from->top + i); api_incr_top(to); } lua_unlock(to); } LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { lua_CFunction old; lua_lock(L); old = G(L)->panic; G(L)->panic = panicf; lua_unlock(L); return old; } LUA_API lua_State *lua_newthread (lua_State *L) { lua_State *L1; lua_lock(L); luaC_checkGC(L); L1 = luaE_newthread(L); setthvalue(L->top, L1); api_incr_top(L); lua_unlock(L); lua_userstateopen(L1); return L1; } /* ** basic stack manipulation */ LUA_API int lua_gettop (lua_State *L) { return (L->top - L->base); } LUA_API void lua_settop (lua_State *L, int idx) { lua_lock(L); if (idx >= 0) { api_check(L, idx <= L->stack_last - L->base); while (L->top < L->base + idx) setnilvalue(L->top++); L->top = L->base + idx; } else { api_check(L, -(idx+1) <= (L->top - L->base)); L->top += idx+1; /* `subtract' index (index is negative) */ } lua_unlock(L); } LUA_API void lua_remove (lua_State *L, int idx) { StkId p; lua_lock(L); p = luaA_index(L, idx); while (++p < L->top) setobjs2s(p-1, p); L->top--; lua_unlock(L); } LUA_API void lua_insert (lua_State *L, int idx) { StkId p; StkId q; lua_lock(L); p = luaA_index(L, idx); for (q = L->top; q>p; q--) setobjs2s(q, q-1); setobjs2s(p, L->top); lua_unlock(L); } LUA_API void lua_replace (lua_State *L, int idx) { lua_lock(L); api_checknelems(L, 1); setobj(luaA_index(L, idx), L->top - 1); /* write barrier */ L->top--; lua_unlock(L); } LUA_API void lua_pushvalue (lua_State *L, int idx) { lua_lock(L); setobj2s(L->top, luaA_index(L, idx)); api_incr_top(L); lua_unlock(L); } /* ** access functions (stack -> C) */ LUA_API int lua_type (lua_State *L, int idx) { StkId o = luaA_indexAcceptable(L, idx); return (o == NULL) ? LUA_TNONE : ttype(o); } LUA_API const char *lua_typename (lua_State *L, int t) { UNUSED(L); return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; } LUA_API int lua_iscfunction (lua_State *L, int idx) { StkId o = luaA_indexAcceptable(L, idx); return (o == NULL) ? 0 : iscfunction(o); } LUA_API int lua_isnumber (lua_State *L, int idx) { TObject n; const TObject *o = luaA_indexAcceptable(L, idx); return (o != NULL && tonumber(o, &n)); } LUA_API int lua_isstring (lua_State *L, int idx) { int t = lua_type(L, idx); return (t == LUA_TSTRING || t == LUA_TNUMBER); } LUA_API int lua_isuserdata (lua_State *L, int idx) { const TObject *o = luaA_indexAcceptable(L, idx); return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o))); } LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { StkId o1 = luaA_indexAcceptable(L, index1); StkId o2 = luaA_indexAcceptable(L, index2); return (o1 == NULL || o2 == NULL) ? 0 /* index out of range */ : luaO_rawequalObj(o1, o2); } LUA_API int lua_equal (lua_State *L, int index1, int index2) { StkId o1, o2; int i; lua_lock(L); /* may call tag method */ o1 = luaA_indexAcceptable(L, index1); o2 = luaA_indexAcceptable(L, index2); i = (o1 == NULL || o2 == NULL) ? 0 /* index out of range */ : equalobj(L, o1, o2); lua_unlock(L); return i; } LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { StkId o1, o2; int i; lua_lock(L); /* may call tag method */ o1 = luaA_indexAcceptable(L, index1); o2 = luaA_indexAcceptable(L, index2); i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */ : luaV_lessthan(L, o1, o2); lua_unlock(L); return i; } LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { TObject n; const TObject *o = luaA_indexAcceptable(L, idx); if (o != NULL && tonumber(o, &n)) return nvalue(o); else return 0; } LUA_API int lua_toboolean (lua_State *L, int idx) { const TObject *o = luaA_indexAcceptable(L, idx); return (o != NULL) && !l_isfalse(o); } LUA_API const char *lua_tostring (lua_State *L, int idx) { StkId o = luaA_indexAcceptable(L, idx); if (o == NULL) return NULL; else if (ttisstring(o)) return svalue(o); else { const char *s; lua_lock(L); /* `luaV_tostring' may create a new string */ s = (luaV_tostring(L, o) ? svalue(o) : NULL); luaC_checkGC(L); lua_unlock(L); return s; } } LUA_API size_t lua_strlen (lua_State *L, int idx) { StkId o = luaA_indexAcceptable(L, idx); if (o == NULL) return 0; else if (ttisstring(o)) return tsvalue(o)->tsv.len; else { size_t l; lua_lock(L); /* `luaV_tostring' may create a new string */ l = (luaV_tostring(L, o) ? tsvalue(o)->tsv.len : 0); lua_unlock(L); return l; } } LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { StkId o = luaA_indexAcceptable(L, idx); return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f; } LUA_API void *lua_touserdata (lua_State *L, int idx) { StkId o = luaA_indexAcceptable(L, idx); if (o == NULL) return NULL; switch (ttype(o)) { case LUA_TUSERDATA: return (uvalue(o) + 1); case LUA_TLIGHTUSERDATA: return pvalue(o); default: return NULL; } } LUA_API lua_State *lua_tothread (lua_State *L, int idx) { StkId o = luaA_indexAcceptable(L, idx); return (o == NULL || !ttisthread(o)) ? NULL : thvalue(o); } LUA_API const void *lua_topointer (lua_State *L, int idx) { StkId o = luaA_indexAcceptable(L, idx); if (o == NULL) return NULL; else { switch (ttype(o)) { case LUA_TTABLE: return hvalue(o); case LUA_TFUNCTION: return clvalue(o); case LUA_TTHREAD: return thvalue(o); case LUA_TUSERDATA: case LUA_TLIGHTUSERDATA: return lua_touserdata(L, idx); default: return NULL; } } } /* ** push functions (C -> stack) */ LUA_API void lua_pushnil (lua_State *L) { lua_lock(L); setnilvalue(L->top); api_incr_top(L); lua_unlock(L); } LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { lua_lock(L); setnvalue(L->top, n); api_incr_top(L); lua_unlock(L); } LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { lua_lock(L); luaC_checkGC(L); setsvalue2s(L->top, luaS_newlstr(L, s, len)); api_incr_top(L); lua_unlock(L); } LUA_API void lua_pushstring (lua_State *L, const char *s) { if (s == NULL) lua_pushnil(L); else lua_pushlstring(L, s, strlen(s)); } LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp) { const char *ret; lua_lock(L); luaC_checkGC(L); ret = luaO_pushvfstring(L, fmt, argp); lua_unlock(L); return ret; } LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { const char *ret; va_list argp; lua_lock(L); luaC_checkGC(L); va_start(argp, fmt); ret = luaO_pushvfstring(L, fmt, argp); va_end(argp); lua_unlock(L); return ret; } LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { Closure *cl; lua_lock(L); luaC_checkGC(L); api_checknelems(L, n); cl = luaF_newCclosure(L, n); cl->c.f = fn; L->top -= n; while (n--) setobj2n(&cl->c.upvalue[n], L->top+n); setclvalue(L->top, cl); api_incr_top(L); lua_unlock(L); } LUA_API void lua_pushboolean (lua_State *L, int b) { lua_lock(L); setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ api_incr_top(L); lua_unlock(L); } LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { lua_lock(L); setpvalue(L->top, p); api_incr_top(L); lua_unlock(L); } /* ** get functions (Lua -> stack) */ LUA_API void lua_gettable (lua_State *L, int idx) { StkId t; lua_lock(L); t = luaA_index(L, idx); setobj2s(L->top - 1, luaV_gettable(L, t, L->top - 1, 0)); lua_unlock(L); } LUA_API void lua_rawget (lua_State *L, int idx) { StkId t; lua_lock(L); t = luaA_index(L, idx); api_check(L, ttistable(t)); setobj2s(L->top - 1, luaH_get(hvalue(t), L->top - 1)); lua_unlock(L); } LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { StkId o; lua_lock(L); o = luaA_index(L, idx); api_check(L, ttistable(o)); setobj2s(L->top, luaH_getnum(hvalue(o), n)); api_incr_top(L); lua_unlock(L); } LUA_API void lua_newtable (lua_State *L) { lua_lock(L); luaC_checkGC(L); sethvalue(L->top, luaH_new(L, 0, 0)); api_incr_top(L); lua_unlock(L); } LUA_API int lua_getmetatable (lua_State *L, int objindex) { const TObject *obj; Table *mt = NULL; int res; lua_lock(L); obj = luaA_indexAcceptable(L, objindex); if (obj != NULL) { switch (ttype(obj)) { case LUA_TTABLE: mt = hvalue(obj)->metatable; break; case LUA_TUSERDATA: mt = uvalue(obj)->uv.metatable; break; } } if (mt == NULL || mt == hvalue(defaultmeta(L))) res = 0; else { sethvalue(L->top, mt); api_incr_top(L); res = 1; } lua_unlock(L); return res; } LUA_API void lua_getfenv (lua_State *L, int idx) { StkId o; lua_lock(L); o = luaA_index(L, idx); setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L)); api_incr_top(L); lua_unlock(L); } /* ** set functions (stack -> Lua) */ LUA_API void lua_settable (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); t = luaA_index(L, idx); luaV_settable(L, t, L->top - 2, L->top - 1); L->top -= 2; /* pop index and value */ lua_unlock(L); } LUA_API void lua_rawset (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); t = luaA_index(L, idx); api_check(L, ttistable(t)); setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */ L->top -= 2; lua_unlock(L); } LUA_API void lua_rawseti (lua_State *L, int idx, int n) { StkId o; lua_lock(L); api_checknelems(L, 1); o = luaA_index(L, idx); api_check(L, ttistable(o)); setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */ L->top--; lua_unlock(L); } LUA_API int lua_setmetatable (lua_State *L, int objindex) { TObject *obj, *mt; int res = 1; lua_lock(L); api_checknelems(L, 1); obj = luaA_index(L, objindex); mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L); api_check(L, ttistable(mt)); switch (ttype(obj)) { case LUA_TTABLE: { hvalue(obj)->metatable = hvalue(mt); /* write barrier */ break; } case LUA_TUSERDATA: { uvalue(obj)->uv.metatable = hvalue(mt); /* write barrier */ break; } default: { res = 0; /* cannot set */ break; } } L->top--; lua_unlock(L); return res; } LUA_API int lua_setfenv (lua_State *L, int idx) { StkId o; int res = 0; lua_lock(L); api_checknelems(L, 1); o = luaA_index(L, idx); L->top--; api_check(L, ttistable(L->top)); if (isLfunction(o)) { res = 1; clvalue(o)->l.g = *(L->top); } lua_unlock(L); return res; } /* ** `load' and `call' functions (run Lua code) */ LUA_API void lua_call (lua_State *L, int nargs, int nresults) { StkId func; lua_lock(L); api_checknelems(L, nargs+1); func = L->top - (nargs+1); luaD_call(L, func, nresults); lua_unlock(L); } /* ** Execute a protected call. */ struct CallS { /* data to `f_call' */ StkId func; int nresults; }; static void f_call (lua_State *L, void *ud) { struct CallS *c = cast(struct CallS *, ud); luaD_call(L, c->func, c->nresults); } LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { struct CallS c; int status; ptrdiff_t func; lua_lock(L); func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc)); c.func = L->top - (nargs+1); /* function to be called */ c.nresults = nresults; status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); lua_unlock(L); return status; } /* ** Execute a protected C call. */ struct CCallS { /* data to `f_Ccall' */ lua_CFunction func; void *ud; }; static void f_Ccall (lua_State *L, void *ud) { struct CCallS *c = cast(struct CCallS *, ud); Closure *cl; cl = luaF_newCclosure(L, 0); cl->c.f = c->func; setclvalue(L->top, cl); /* push function */ incr_top(L); setpvalue(L->top, c->ud); /* push only argument */ incr_top(L); luaD_call(L, L->top - 2, 0); } LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { struct CCallS c; int status; lua_lock(L); c.func = func; c.ud = ud; status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); lua_unlock(L); return status; } LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data, const char *chunkname) { ZIO z; int status; int c; lua_lock(L); if (!chunkname) chunkname = "?"; luaZ_init(&z, reader, data, chunkname); c = luaZ_lookahead(&z); status = luaD_protectedparser(L, &z, (c == LUA_SIGNATURE[0])); lua_unlock(L); return status; } LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) { int status; TObject *o; lua_lock(L); api_checknelems(L, 1); o = L->top - 1; if (isLfunction(o) && clvalue(o)->l.nupvalues == 0) { luaU_dump(L, clvalue(o)->l.p, writer, data); status = 1; } else status = 0; lua_unlock(L); return status; } /* ** Garbage-collection functions */ /* GC values are expressed in Kbytes: #bytes/2^10 */ #define GCscalel(x) ((x)>>10) #define GCscale(x) (cast(int, GCscalel(x))) #define GCunscale(x) (cast(lu_mem, x)<<10) LUA_API int lua_getgcthreshold (lua_State *L) { int threshold; lua_lock(L); threshold = GCscale(G(L)->GCthreshold); lua_unlock(L); return threshold; } LUA_API int lua_getgccount (lua_State *L) { int count; lua_lock(L); count = GCscale(G(L)->nblocks); lua_unlock(L); return count; } LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) { lua_lock(L); if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM)) G(L)->GCthreshold = MAX_LUMEM; else G(L)->GCthreshold = GCunscale(newthreshold); luaC_checkGC(L); lua_unlock(L); } /* ** miscellaneous functions */ LUA_API const char *lua_version (void) { return LUA_VERSION; } LUA_API int lua_error (lua_State *L) { lua_lock(L); api_checknelems(L, 1); luaG_errormsg(L); lua_unlock(L); return 0; /* to avoid warnings */ } LUA_API int lua_next (lua_State *L, int idx) { StkId t; int more; lua_lock(L); t = luaA_index(L, idx); api_check(L, ttistable(t)); more = luaH_next(L, hvalue(t), L->top - 1); if (more) { api_incr_top(L); } else /* no more elements */ L->top -= 1; /* remove key */ lua_unlock(L); return more; } LUA_API void lua_concat (lua_State *L, int n) { lua_lock(L); luaC_checkGC(L); api_checknelems(L, n); if (n >= 2) { luaV_concat(L, n, L->top - L->base - 1); L->top -= (n-1); } else if (n == 0) { /* push empty string */ setsvalue2s(L->top, luaS_newlstr(L, NULL, 0)); api_incr_top(L); } /* else n == 1; nothing to do */ lua_unlock(L); } LUA_API void *lua_newuserdata (lua_State *L, size_t size) { Udata *u; lua_lock(L); luaC_checkGC(L); u = luaS_newudata(L, size); setuvalue(L->top, u); api_incr_top(L); lua_unlock(L); return u + 1; } LUA_API int lua_pushupvalues (lua_State *L) { Closure *func; int n, i; lua_lock(L); api_check(L, iscfunction(L->base - 1)); func = clvalue(L->base - 1); n = func->c.nupvalues; luaD_checkstack(L, n + LUA_MINSTACK); for (i=0; i<n; i++) { setobj2s(L->top, &func->c.upvalue[i]); L->top++; } lua_unlock(L); return n; } static const char *aux_upvalue (lua_State *L, int funcindex, int n, TObject **val) { Closure *f; StkId fi = luaA_index(L, funcindex); if (!ttisfunction(fi)) return NULL; f = clvalue(fi); if (f->c.isC) { if (n > f->c.nupvalues) return NULL; *val = &f->c.upvalue[n-1]; return ""; } else { Proto *p = f->l.p; if (n > p->sizeupvalues) return NULL; *val = f->l.upvals[n-1]->v; return getstr(p->upvalues[n-1]); } } LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { const char *name; TObject *val; lua_lock(L); name = aux_upvalue(L, funcindex, n, &val); if (name) { setobj2s(L->top, val); api_incr_top(L); } lua_unlock(L); return name; } LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { const char *name; TObject *val; lua_lock(L); api_checknelems(L, 1); name = aux_upvalue(L, funcindex, n, &val); if (name) { L->top--; setobj(val, L->top); /* write barrier */ } lua_unlock(L); return name; } --- NEW FILE: lapi.h --- /* ** $Id: lapi.h,v 1.1 2003/11/19 08:17:06 yurand Exp $ ** Auxiliary functions from Lua API ** See Copyright Notice in lua.h */ #ifndef lapi_h #define lapi_h #include "lobject.h" void luaA_pushobject (lua_State *L, const TObject *o); #endif --- NEW FILE: lcode.c --- /* ** $Id: lcode.c,v 1.1 2003/11/19 08:17:06 yurand Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ #include <stdlib.h> #define lcode_c #include "lua.h" #include "lcode.h" #include "ldebug.h" #include "ldo.h" #include "llex.h" #include "lmem.h" #include "lobject.h" #include "lopcodes.h" #include "lparser.h" #include "ltable.h" #define hasjumps(e) ((e)->t != (e)->f) void luaK_nil (FuncState *fs, int from, int n) { Instruction *previous; if (fs->pc > fs->lasttarget && /* no jumps to current position? */ GET_OPCODE(*(previous = &fs->f->code[fs->pc-1])) == OP_LOADNIL) { int pfrom = GETARG_A(*previous); int pto = GETARG_B(*previous); if (pfrom <= from && from <= pto+1) { /* can connect both? */ if (from+n-1 > pto) SETARG_B(*previous, from+n-1); return; } } luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ } int luaK_jump (FuncState *fs) { int jpc = fs->jpc; /* save list of jumps to here */ int j; fs->jpc = NO_JUMP; j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); luaK_concat(fs, &j, jpc); /* keep them on hold */ return j; } static int luaK_condjump (FuncState *fs, OpCode op, int A, int B, int C) { luaK_codeABC(fs, op, A, B, C); return luaK_jump(fs); } static void luaK_fixjump (FuncState *fs, int pc, int dest) { Instruction *jmp = &fs->f->code[pc]; int offset = dest-(pc+1); lua_assert(dest != NO_JUMP); if (abs(offset) > MAXARG_sBx) luaX_syntaxerror(fs->ls, "control structure too long"); SETARG_sBx(*jmp, offset); } /* ** returns current `pc' and marks it as a jump target (to avoid wrong ** optimizations with consecutive instructions not in the same basic block). */ int luaK_getlabel (FuncState *fs) { fs->lasttarget = fs->pc; return fs->pc; } static int luaK_getjump (FuncState *fs, int pc) { int offset = GETARG_sBx(fs->f->code[pc]); if (offset == NO_JUMP) /* point to itself represents end of list */ return NO_JUMP; /* end of list */ else return (pc+1)+offset; /* turn offset into absolute position */ } static Instruction *getjumpcontrol (FuncState *fs, int pc) { Instruction *pi = &fs->f->code[pc]; if (pc >= 1 && testOpMode(GET_OPCODE(*(pi-1)), OpModeT)) return pi-1; else return pi; } /* ** check whether list has any jump that do not produce a value ** (or produce an inverted value) */ static int need_value (FuncState *fs, int list, int cond) { for (; list != NO_JUMP; list = luaK_getjump(fs, list)) { Instruction i = *getjumpcontrol(fs, list); if (GET_OPCODE(i) != OP_TEST || GETARG_C(i) != cond) return 1; } return 0; /* not found */ } static void patchtestreg (Instruction *i, int reg) { if (reg == NO_REG) reg = GETARG_B(*i); SETARG_A(*i, reg); } static void luaK_patchlistaux (FuncState *fs, int list, int ttarget, int treg, int ftarget, int freg, int dtarget) { while (list != NO_JUMP) { int next = luaK_getjump(fs, list); Instruction *i = getjumpcontrol(fs, list); if (GET_OPCODE(*i) != OP_TEST) { lua_assert(dtarget != NO_JUMP); luaK_fixjump(fs, list, dtarget); /* jump to default target */ } else { if (GETARG_C(*i)) { lua_assert(ttarget != NO_JUMP); patchtestreg(i, treg); luaK_fixjump(fs, list, ttarget); } else { lua_assert(ftarget != NO_JUMP); patchtestreg(i, freg); luaK_fixjump(fs, list, ftarget); } } list = next; } } static void luaK_dischargejpc (FuncState *fs) { luaK_patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc, NO_REG, fs->pc); fs->jpc = NO_JUMP; } void luaK_patchlist (FuncState *fs, int list, int target) { if (target == fs->pc) luaK_patchtohere(fs, list); else { lua_assert(target < fs->pc); luaK_patchlistaux(fs, list, target, NO_REG, target, NO_REG, target); } } void luaK_patchtohere (FuncState *fs, int list) { luaK_getlabel(fs); luaK_concat(fs, &fs->jpc, list); } void luaK_concat (FuncState *fs, int *l1, int l2) { if (l2 == NO_JUMP) return; else if (*l1 == NO_JUMP) *l1 = l2; else { int list = *l1; int next; while ((next = luaK_getjump(fs, list)) != NO_JUMP) /* find last element */ list = next; luaK_fixjump(fs, list, l2); } } void luaK_checkstack (FuncState *fs, int n) { int newstack = fs->freereg + n; if (newstack > fs->f->maxstacksize) { if (newstack >= MAXSTACK) luaX_syntaxerror(fs->ls, "function or expression too complex"); fs->f->maxstacksize = cast(lu_byte, newstack); } } void luaK_reserveregs (FuncState *fs, int n) { luaK_checkstack(fs, n); fs->freereg += n; } static void freereg (FuncState *fs, int reg) { if (reg >= fs->nactvar && reg < MAXSTACK) { fs->freereg--; lua_assert(reg == fs->freereg); } } static void freeexp (FuncState *fs, expdesc *e) { if (e->k == VNONRELOC) freereg(fs, e->info); } static int addk (FuncState *fs, TObject *k, TObject *v) { const TObject *idx = luaH_get(fs->h, k); if (ttisnumber(idx)) { lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v)); return cast(int, nvalue(idx)); } else { /* constant not found; create a new entry */ Proto *f = fs->f; luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject, MAXARG_Bx, "constant table overflow"); setobj2n(&f->k[fs->nk], v); setnvalue(luaH_set(fs->L, fs->h, k), cast(lua_Number, fs->nk)); return fs->nk++; } } int luaK_stringK (FuncState *fs, TString *s) { TObject o; setsvalue(&o, s); return addk(fs, &o, &o); } int luaK_numberK (FuncState *fs, lua_Number r) { TObject o; setnvalue(&o, r); return addk(fs, &o, &o); } static int nil_constant (FuncState *fs) { TObject k, v; setnilvalue(&v); sethvalue(&k, fs->h); /* cannot use nil as key; instead use table itself */ return addk(fs, &k, &v); } void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) { if (e->k == VCALL) { /* expression is an open function call? */ SETARG_C(getcode(fs, e), nresults+1); if (nresults == 1) { /* `regular' expression? */ e->k = VNONRELOC; e->info = GETARG_A(getcode(fs, e)); } } } void luaK_dischargevars (FuncState *fs, expdesc *e) { switch (e->k) { case VLOCAL: { e->k = VNONRELOC; break; } case VUPVAL: { e->info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->info, 0); e->k = VRELOCABLE; break; } case VGLOBAL: { e->info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->info); e->k = VRELOCABLE; break; } case VINDEXED: { freereg(fs, e->aux); freereg(fs, e->info); e->info = luaK_codeABC(fs, OP_GETTABLE, 0, e->info, e->aux); e->k = VRELOCABLE; break; } case VCALL: { luaK_setcallreturns(fs, e, 1); break; } default: break; /* there is one value available (somewhere) */ } } static int code_label (FuncState *fs, int A, int b, int jump) { luaK_getlabel(fs); /* those instructions may be jump targets */ return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); } static void discharge2reg (FuncState *fs, expdesc *e, int reg) { luaK_dischargevars(fs, e); switch (e->k) { case VNIL: { luaK_nil(fs, reg, 1); break; } case VFALSE: case VTRUE: { luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); break; } case VK: { luaK_codeABx(fs, OP_LOADK, reg, e->info); break; } case VRELOCABLE: { Instruction *pc = &getcode(fs, e); SETARG_A(*pc, reg); break; } case VNONRELOC: { if (reg != e->info) luaK_codeABC(fs, OP_MOVE, reg, e->info, 0); break; } default: { lua_assert(e->k == VVOID || e->k == VJMP); return; /* nothing to do... */ } } e->info = reg; e->k = VNONRELOC; } static void discharge2anyreg (FuncState *fs, expdesc *e) { if (e->k != VNONRELOC) { luaK_reserveregs(fs, 1); discharge2reg(fs, e, fs->freereg-1); } } static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) { discharge2reg(fs, e, reg); if (e->k == VJMP) luaK_concat(fs, &e->t, e->info); /* put this jump in `t' list */ if (hasjumps(e)) { int final; /* position after whole expression */ int p_f = NO_JUMP; /* position of an eventual LOAD false */ int p_t = NO_JUMP; /* position of an eventual LOAD true */ if (need_value(fs, e->t, 1) || need_value(fs, e->f, 0)) { int fj = NO_JUMP; /* first jump (over LOAD ops.) */ if (e->k != VJMP) fj = luaK_jump(fs); p_f = code_label(fs, reg, 0, 1); p_t = code_label(fs, reg, 1, 0); luaK_patchtohere(fs, fj); } final = luaK_getlabel(fs); luaK_patchlistaux(fs, e->f, p_f, NO_REG, final, reg, p_f); luaK_patchlistaux(fs, e->t, final, reg, p_t, NO_REG, p_t); } e->f = e->t = NO_JUMP; e->info = reg; e->k = VNONRELOC; } void luaK_exp2nextreg (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); freeexp(fs, e); luaK_reserveregs(fs, 1); luaK_exp2reg(fs, e, fs->freereg - 1); } int luaK_exp2anyreg (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); if (e->k == VNONRELOC) { if (!hasjumps(e)) return e->info; /* exp is already in a register */ if (e->info >= fs->nactvar) { /* reg. is not a local? */ luaK_exp2reg(fs, e, e->info); /* put value on it */ return e->info; } } luaK_exp2nextreg(fs, e); /* default */ return e->info; } void luaK_exp2val (FuncState *fs, expdesc *e) { if (hasjumps(e)) luaK_exp2anyreg(fs, e); else luaK_dischargevars(fs, e); } int luaK_exp2RK (FuncState *fs, expdesc *e) { luaK_exp2val(fs, e); switch (e->k) { case VNIL: { if (fs->nk + MAXSTACK <= MAXARG_C) { /* constant fit in argC? */ e->info = nil_constant(fs); e->k = VK; return e->info + MAXSTACK; } else break; } case VK: { if (e->info + MAXSTACK <= MAXARG_C) /* constant fit in argC? */ return e->info + MAXSTACK; else break; } default: break; } /* not a constant in the right range: put it in a register */ return luaK_exp2anyreg(fs, e); } void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) { switch (var->k) { case VLOCAL: { freeexp(fs, exp); luaK_exp2reg(fs, exp, var->info); return; } case VUPVAL: { int e = luaK_exp2anyreg(fs, exp); luaK_codeABC(fs, OP_SETUPVAL, e, var->info, 0); break; } case VGLOBAL: { int e = luaK_exp2anyreg(fs, exp); luaK_codeABx(fs, OP_SETGLOBAL, e, var->info); break; } case VINDEXED: { int e = luaK_exp2RK(fs, exp); luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e); break; } default: { lua_assert(0); /* invalid var kind to store */ break; } } freeexp(fs, exp); } void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { int func; luaK_exp2anyreg(fs, e); freeexp(fs, e); func = fs->freereg; luaK_reserveregs(fs, 2); luaK_codeABC(fs, OP_SELF, func, e->info, luaK_exp2RK(fs, key)); freeexp(fs, key); e->info = func; e->k = VNONRELOC; } static void invertjump (FuncState *fs, expdesc *e) { Instruction *pc = getjumpcontrol(fs, e->info); lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) && GET_OPCODE(*pc) != OP_TEST); SETARG_A(*pc, !(GETARG_A(*pc))); } static int jumponcond (FuncState *fs, expdesc *e, int cond) { if (e->k == VRELOCABLE) { Instruction ie = getcode(fs, e); if (GET_OPCODE(ie) == OP_NOT) { fs->pc--; /* remove previous OP_NOT */ return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond); } /* else go through */ } discharge2anyreg(fs, e); freeexp(fs, e); return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond); } void luaK_goiftrue (FuncState *fs, expdesc *e) { int pc; /* pc of last jump */ luaK_dischargevars(fs, e); switch (e->k) { case VK: case VTRUE: { pc = NO_JUMP; /* always true; do nothing */ break; } case VFALSE: { pc = luaK_jump(fs); /* always jump */ break; } case VJMP: { invertjump(fs, e); pc = e->info; break; } default: { pc = jumponcond(fs, e, 0); break; } } luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ } void luaK_goiffalse (FuncState *fs, expdesc *e) { int pc; /* pc of last jump */ luaK_dischargevars(fs, e); switch (e->k) { case VNIL: case VFALSE: { pc = NO_JUMP; /* always false; do nothing */ break; } case VTRUE: { pc = luaK_jump(fs); /* always jump */ break; } case VJMP: { pc = e->info; break; } default: { pc = jumponcond(fs, e, 1); break; } } luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ } static void codenot (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); switch (e->k) { case VNIL: case VFALSE: { e->k = VTRUE; break; } case VK: case VTRUE: { e->k = VFALSE; break; } case VJMP: { invertjump(fs, e); break; } case VRELOCABLE: case VNONRELOC: { discharge2anyreg(fs, e); freeexp(fs, e); e->info = luaK_codeABC(fs, OP_NOT, 0, e->info, 0); e->k = VRELOCABLE; break; } default: { lua_assert(0); /* cannot happen */ break; } } /* interchange true and false lists */ { int temp = e->f; e->f = e->t; e->t = temp; } } void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { t->aux = luaK_exp2RK(fs, k); t->k = VINDEXED; } void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { if (op == OPR_MINUS) { luaK_exp2val(fs, e); if (e->k == VK && ttisnumber(&fs->f->k[e->info])) e->info = luaK_numberK(fs, -nvalue(&fs->f->k[e->info])); else { luaK_exp2anyreg(fs, e); freeexp(fs, e); e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0); e->k = VRELOCABLE; } } else /* op == NOT */ codenot(fs, e); } void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { switch (op) { case OPR_AND: { luaK_goiftrue(fs, v); luaK_patchtohere(fs, v->t); v->t = NO_JUMP; break; } case OPR_OR: { luaK_goiffalse(fs, v); luaK_patchtohere(fs, v->f); v->f = NO_JUMP; break; } case OPR_CONCAT: { luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ break; } default: { luaK_exp2RK(fs, v); break; } } } static void codebinop (FuncState *fs, expdesc *res, BinOpr op, int o1, int o2) { if (op <= OPR_POW) { /* arithmetic operator? */ OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); /* ORDER OP */ res->info = luaK_codeABC(fs, opc, 0, o1, o2); res->k = VRELOCABLE; } else { /* test operator */ static const OpCode ops[] = {OP_EQ, OP_EQ, OP_LT, OP_LE, OP_LT, OP_LE}; int cond = 1; if (op >= OPR_GT) { /* `>' or `>='? */ int temp; /* exchange args and replace by `<' or `<=' */ temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ } else if (op == OPR_NE) cond = 0; res->info = luaK_condjump(fs, ops[op - OPR_NE], cond, o1, o2); res->k = VJMP; } } void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { switch (op) { case OPR_AND: { lua_assert(e1->t == NO_JUMP); /* list must be closed */ luaK_dischargevars(fs, e2); luaK_concat(fs, &e1->f, e2->f); e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->t = e2->t; break; } case OPR_OR: { lua_assert(e1->f == NO_JUMP); /* list must be closed */ luaK_dischargevars(fs, e2); luaK_concat(fs, &e1->t, e2->t); e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->f = e2->f; break; } case OPR_CONCAT: { luaK_exp2val(fs, e2); if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { lua_assert(e1->info == GETARG_B(getcode(fs, e2))-1); freeexp(fs, e1); SETARG_B(getcode(fs, e2), e1->info); e1->k = e2->k; e1->info = e2->info; } else { luaK_exp2nextreg(fs, e2); freeexp(fs, e2); freeexp(fs, e1); e1->info = luaK_codeABC(fs, OP_CONCAT, 0, e1->info, e2->info); e1->k = VRELOCABLE; } break; } default: { int o1 = luaK_exp2RK(fs, e1); int o2 = luaK_exp2RK(fs, e2); freeexp(fs, e2); freeexp(fs, e1); codebinop(fs, e1, op, o1, o2); } } } void luaK_fixline (FuncState *fs, int line) { fs->f->lineinfo[fs->pc - 1] = line; } int luaK_code (FuncState *fs, Instruction i, int line) { Proto *f = fs->f; luaK_dischargejpc(fs); /* `pc' will change */ /* put new instruction in code array */ luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, MAX_INT, "code size overflow"); f->code[fs->pc] = i; /* save corresponding line information */ luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, MAX_INT, "code size overflow"); f->lineinfo[fs->pc] = line; return fs->pc++; } int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { lua_assert(getOpMode(o) == iABC); return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); } int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); } --- NEW FILE: lcode.h --- /* ** $Id: lcode.h,v 1.1 2003/11/19 08:17:06 yurand Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ #ifndef lcode_h #define lcode_h #include "llex.h" #include "lobject.h" #include "lopcodes.h" #include "lparser.h" /* ** Marks the end of a patch list. It is an invalid value both as an absolute ** address, and as a list link (would link an element to itself). */ #define NO_JUMP (-1) /* ** grep "ORDER OPR" if you change these enums */ typedef enum BinOpr { OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_POW, OPR_CONCAT, OPR_NE, OPR_EQ, OPR_LT, OPR_LE, OPR_GT, OPR_GE, OPR_AND, OPR_OR, OPR_NOBINOPR } BinOpr; #define binopistest(op) ((op) >= OPR_NE) typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr; #define getcode(fs,e) ((fs)->f->code[(e)->info]) #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) int luaK_code (FuncState *fs, Instruction i, int line); int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); void luaK_fixline (FuncState *fs, int line); void luaK_nil (FuncState *fs, int from, int n); void luaK_reserveregs (FuncState *fs, int n); void luaK_checkstack (FuncState *fs, int n); int luaK_stringK (FuncState *fs, TString *s); int luaK_numberK (FuncState *fs, lua_Number r); void luaK_dischargevars (FuncState *fs, expdesc *e); int luaK_exp2anyreg (FuncState *fs, expdesc *e); void luaK_exp2nextreg (FuncState *fs, expdesc *e); void luaK_exp2val (FuncState *fs, expdesc *e); int luaK_exp2RK (FuncState *fs, expdesc *e); void luaK_self (FuncState *fs, expdesc *e, expdesc *key); void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); void luaK_goiftrue (FuncState *fs, expdesc *e); void luaK_goiffalse (FuncState *fs, expdesc *e); void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); void luaK_setcallreturns (FuncState *fs, expdesc *var, int nresults); int luaK_jump (FuncState *fs); void luaK_patchlist (FuncState *fs, int list, int target); void luaK_patchtohere (FuncState *fs, int list); void luaK_concat (FuncState *fs, int *l1, int l2); int luaK_getlabel (FuncState *fs); void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); #endif --- NEW FILE: ldebug.c --- /* ** $Id: ldebug.c,v 1.1 2003/11/19 08:17:06 yurand Exp $ ** Debug Interface ** See Copyright Notice in lua.h */ #include <stdlib.h> #include <string.h> #define ldebug_c #include "lua.h" #include "lapi.h" #include "lcode.h" #include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "lobject.h" #include "lopcodes.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" #include "lvm.h" static const char *getfuncname (CallInfo *ci, const char **name); #define isLua(ci) (!((ci)->state & CI_C)) static int currentpc (CallInfo *ci) { if (!isLua(ci)) return -1; /* function is not a Lua function? */ if (ci->state & CI_HASFRAME) /* function has a frame? */ ci->u.l.savedpc = *ci->u.l.pc; /* use `pc' from there */ /* function's pc is saved */ return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p); } static int currentline (CallInfo *ci) { int pc = currentpc(ci); if (pc < 0) return -1; /* only active lua functions have current-line information */ else return getline(ci_func(ci)->l.p, pc); } void luaG_inithooks (lua_State *L) { CallInfo *ci; for (ci = L->ci; ci != L->base_ci; ci--) /* update all `savedpc's */ currentpc(ci); L->hookinit = 1; } /* ** this function can be called asynchronous (e.g. during a signal) */ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { if (func == NULL || mask == 0) { /* turn off hooks? */ mask = 0; func = NULL; } L->hook = func; L->basehookcount = count; resethookcount(L); L->hookmask = cast(lu_byte, mask); L->hookinit = 0; return 1; } LUA_API lua_Hook lua_gethook (lua_State *L) { return L->hook; } LUA_API int lua_gethookmask (lua_State *L) { return L->hookmask; } LUA_API int lua_gethookcount (lua_State *L) { return L->basehookcount; } LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { int status; CallInfo *ci; lua_lock(L); for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { level--; if (!(ci->state & CI_C)) /* Lua function? */ level -= ci->u.l.tailcalls; /* skip lost tail calls */ } if (level > 0 || ci == L->base_ci) status = 0; /* there is no such level */ else if (level < 0) { /* level is of a lost tail call */ status = 1; ar->i_ci = 0; } else { status = 1; ar->i_ci = ci - L->base_ci; } lua_unlock(L); return status; } static Proto *getluaproto (CallInfo *ci) { return (isLua(ci) ? ci_func(ci)->l.p : NULL); } LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { const char *name; CallInfo *ci; Proto *fp; lua_lock(L); name = NULL; ci = L->base_ci + ar->i_ci; fp = getluaproto(ci); if (fp) { /* is a Lua function? */ name = luaF_getlocalname(fp, n, currentpc(ci)); if (name) luaA_pushobject(L, ci->base+(n-1)); /* push value */ } lua_unlock(L); return name; } LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { const char *name; CallInfo *ci; Proto *fp; lua_lock(L); name = NULL; ci = L->base_ci + ar->i_ci; fp = getluaproto(ci); L->top--; /* pop new value */ if (fp) { /* is a Lua function? */ name = luaF_getlocalname(fp, n, currentpc(ci)); if (!name || name[0] == '(') /* `(' starts private locals */ name = NULL; else setobjs2s(ci->base+(n-1), L->top); } lua_unlock(L); return name; } static void funcinfo (lua_Debug *ar, StkId func) { Closure *cl = clvalue(func); if (cl->c.isC) { ar->source = "=[C]"; ar->linedefined = -1; ar->what = "C"; } else { ar->source = getstr(cl->l.p->source); ar->linedefined = cl->l.p->lineDefined; ar->what = (ar->linedefined == 0) ? "main" : "Lua"; } luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); } static const char *travglobals (lua_State *L, const TObject *o) { Table *g = hvalue(gt(L)); int i = sizenode(g); while (i--) { Node *n = gnode(g, i); if (luaO_rawequalObj(o, gval(n)) && ttisstring(gkey(n))) return getstr(tsvalue(gkey(n))); } return NULL; } static void info_tailcall (lua_State *L, lua_Debug *ar) { ar->name = ar->namewhat = ""; ar->what = "tail"; ar->linedefined = ar->currentline = -1; ar->source = "=(tail call)"; luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); ar->nups = 0; setnilvalue(L->top); } static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, StkId f, CallInfo *ci) { int status = 1; for (; *what; what++) { switch (*what) { case 'S': { funcinfo(ar, f); break; } case 'l': { ar->currentline = (ci) ? currentline(ci) : -1; break; } case 'u': { ar->nups = clvalue(f)->c.nupvalues; break; } case 'n': { ar->namewhat = (ci) ? getfuncname(ci, &ar->name) : NULL; if (ar->namewhat == NULL) { /* try to find a global name */ if ((ar->name = travglobals(L, f)) != NULL) ar->namewhat = "global"; else ar->namewhat = ""; /* not found */ } break; } case 'f': { setobj2s(L->top, f); break; } default: status = 0; /* invalid option */ } } return status; } LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { int status = 1; lua_lock(L); if (*what == '>') { StkId f = L->top - 1; if (!ttisfunction(f)) luaG_runerror(L, "value for `lua_getinfo' is not a function"); status = auxgetinfo(L, what + 1, ar, f, NULL); L->top--; /* pop function */ } else if (ar->i_ci != 0) { /* no tail call? */ CallInfo *ci = L->base_ci + ar->i_ci; lua_assert(ttisfunction(ci->base - 1)); status = auxgetinfo(L, what, ar, ci->base - 1, ci); } else info_tailcall(L, ar); if (strchr(what, 'f')) incr_top(L); lua_unlock(L); return status; } /* ** {====================================================== ** Symbolic Execution and code checker ** ======================================================= */ #define check(x) if (!(x)) return 0; #define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) #define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) static int precheck (const Proto *pt) { check(pt->maxstacksize <= MAXSTACK); check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); lua_assert(pt->numparams+pt->is_vararg <= pt->maxstacksize); check(GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); return 1; } static int checkopenop (const Proto *pt, int pc) { Instruction i = pt->code[pc+1]; switch (GET_OPCODE(i)) { case OP_CALL: case OP_TAILCALL: case OP_RETURN: { check(GETARG_B(i) == 0); return 1; } case OP_SETLISTO: return 1; default: return 0; /* invalid instruction after an open call */ } } static int checkRK (const Proto *pt, int r) { return (r < pt->maxstacksize || (r >= MAXSTACK && r-MAXSTACK < pt->sizek)); } static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) { int pc; int last; /* stores position of last instruction that changed `reg' */ last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ check(precheck(pt)); for (pc = 0; pc < lastpc; pc++) { const Instruction i = pt->code[pc]; OpCode op = GET_OPCODE(i); int a = GETARG_A(i); int b = 0; int c = 0; checkreg(pt, a); switch (getOpMode(op)) { case iABC: { b = GETARG_B(i); c = GETARG_C(i); if (testOpMode(op, OpModeBreg)) { checkreg(pt, b); } else if (testOpMode(op, OpModeBrk)) check(checkRK(pt, b)); if (testOpMode(op, OpModeCrk)) check(checkRK(pt, c)); break; } case iABx: { b = GETARG_Bx(i); if (testOpMode(op, OpModeK)) check(b < pt->sizek); break; } case iAsBx: { b = GETARG_sBx(i); break; } } if (testOpMode(op, OpModesetA)) { if (a == reg) last = pc; /* change register `a' */ } if (testOpMode(op, OpModeT)) { check(pc+2 < pt->sizecode); /* check skip */ check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); } switch (op) { case OP_LOADBOOL: { check(c == 0 || pc+2 < pt->sizecode); /* check its jump */ break; } case OP_LOADNIL: { if (a <= reg && reg <= b) last = pc; /* set registers from `a' to `b' */ break; } case OP_GETUPVAL: case OP_SETUPVAL: { check(b < pt->nups); break; } case OP_GETGLOBAL: case OP_SETGLOBAL: { check(ttisstring(&pt->k[b])); break; } case OP_SELF: { checkreg(pt, a+1); if (reg == a+1) last = pc; break; } case OP_CONCAT: { /* `c' is a register, and at least two operands */ check(c < MAXSTACK && b < c); break; } case OP_TFORLOOP: checkreg(pt, a+c+5); if (reg >= a) last = pc; /* affect all registers above base */ /* go through */ case OP_FORLOOP: checkreg(pt, a+2); /* go through */ case OP_JMP: { int dest = pc+1+b; check(0 <= dest && dest < pt->sizecode); /* not full check and jump is forward and do not skip `lastpc'? */ if (reg != NO_REG && pc < dest && dest <= lastpc) pc += b; /* do the jump */ break; } case OP_CALL: case OP_TAILCALL: { if (b != 0) { checkreg(pt, a+b-1); } c--; /* c = num. returns */ if (c == LUA_MULTRET) { check(checkopenop(pt, pc)); } else if (c != 0) checkreg(pt, a+c-1); if (reg >= a) last = pc; /* affect all registers above base */ break; } case OP_RETURN: { b--; /* b = num. returns */ if (b > 0) checkreg(pt, a+b-1); break; } case OP_SETLIST: { checkreg(pt, a + (b&(LFIELDS_PER_FLUSH-1)) + 1); break; } case OP_CLOSURE: { int nup; check(b < pt->sizep); nup = pt->p[b]->nups; check(pc + nup < pt->sizecode); for (; nup>0; nup--) { OpCode op1 = GET_OPCODE(pt->code[pc+nup]); check(op1 == OP_GETUPVAL || op1 == OP_MOVE); } break; } default: break; } } return pt->code[last]; } #undef check #undef checkjump #undef checkreg /* }====================================================== */ int luaG_checkcode (const Proto *pt) { return luaG_symbexec(pt, pt->sizecode, NO_REG); } static const char *kname (Proto *p, int c) { c = c - MAXSTACK; if (c >= 0 && ttisstring(&p->k[c])) return svalue(&p->k[c]); else return "?"; } static const char *getobjname (CallInfo *ci, int stackpos, const char **name) { if (isLua(ci)) { /* a Lua function? */ Proto *p = ci_func(ci)->l.p; int pc = currentpc(ci); Instruction i; *name = luaF_getlocalname(p, stackpos+1, pc); if (*name) /* is a local? */ return "local"; i = luaG_symbexec(p, pc, stackpos); /* try symbolic execution */ lua_assert(pc != -1); switch (GET_OPCODE(i)) { case OP_GETGLOBAL: { int g = GETARG_Bx(i); /* global index */ lua_assert(ttisstring(&p->k[g])); *name = svalue(&p->k[g]); return "global"; } case OP_MOVE: { int a = GETARG_A(i); int b = GETARG_B(i); /* move from `b' to `a' */ if (b < a) return getobjname(ci, b, name); /* get name for `b' */ break; } case OP_GETTABLE: { int k = GETARG_C(i); /* key index */ *name = kname(p, k); return "field"; } case OP_SELF: { int k = GETARG_C(i); /* key index */ *name = kname(p, k); return "method"; } default: break; } } return NULL; /* no useful name found */ } static const char *getfuncname (CallInfo *ci, const char **name) { Instruction i; if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1)) return NULL; /* calling function is not Lua (or is unknown) */ ci--; /* calling function */ i = ci_func(ci)->l.p->code[currentpc(ci)]; if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL) return getobjname(ci, GETARG_A(i), name); else return NULL; /* no useful name can be found */ } /* only ANSI way to check whether a pointer points to an array */ static int isinstack (CallInfo *ci, const TObject *o) { StkId p; for (p = ci->base; p < ci->top; p++) if (o == p) return 1; return 0; } void luaG_typeerror (lua_State *L, const TObject *o, const char *op) { const char *name = NULL; const char *t = luaT_typenames[ttype(o)]; const char *kind = (isinstack(L->ci, o)) ? getobjname(L->ci, o - L->base, &name) : NULL; if (kind) luaG_runerror(L, "attempt to %s %s `%s' (a %s value)", op, kind, name, t); else luaG_runerror(L, "attempt to %s a %s value", op, t); } void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { if (ttisstring(p1)) p1 = p2; lua_assert(!ttisstring(p1)); luaG_typeerror(L, p1, "concatenate"); } void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2) { TObject temp; if (luaV_tonumber(p1, &temp) == NULL) p2 = p1; /* first operand is wrong */ luaG_typeerror(L, p2, "perform arithmetic on"); } int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) { const char *t1 = luaT_typenames[ttype(p1)]; const char *t2 = luaT_typenames[ttype(p2)]; if (t1[2] == t2[2]) luaG_runerror(L, "attempt to compare two %s values", t1); else luaG_runerror(L, "attempt to compare %s with %s", t1, t2); return 0; } static void addinfo (lua_State *L, const char *msg) { CallInfo *ci = L->ci; if (isLua(ci)) { /* is Lua code? */ char buff[LUA_IDSIZE]; /* add file:line information */ int line = currentline(ci); luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); } } void luaG_errormsg (lua_State *L) { if (L->errfunc != 0) { /* is there an error handling function? */ StkId errfunc = restorestack(L, L->errfunc); if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); setobjs2s(L->top, L->top - 1); /* move argument */ setobjs2s(L->top - 1, errfunc); /* push function */ incr_top(L); luaD_call(L, L->top - 2, 1); /* call it */ } luaD_throw(L, LUA_ERRRUN); } void luaG_runerror (lua_State *L, const char *fmt, ...) { va_list argp; va_start(argp, fmt); addinfo(L, luaO_pushvfstring(L, fmt, argp)); va_end(argp); luaG_errormsg(L); } --- NEW FILE: ldebug.h --- /* ** $Id: ldebug.h,v 1.1 2003/11/19 08:17:06 yurand Exp $ ** Auxiliary functions from Debug Interface module ** See Copyright Notice in lua.h */ #ifndef ldebug_h #define ldebug_h #include "lstate.h" #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) #define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) #define resethookcount(L) (L->hookcount = L->basehookcount) void luaG_inithooks (lua_State *L); void luaG_typeerror (lua_State *L, const TObject *o, const char *opname); void luaG_concaterror (lua_State *L, StkId p1, StkId p2); void luaG_aritherror (lua_State *L, const TObject *p1, const TObject *p2); int luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2); void luaG_runerror (lua_State *L, const char *fmt, ...); void luaG_errormsg (lua_State *L); int luaG_checkcode (const Proto *pt); #endif --- NEW FILE: ldo.c --- /* ** $Id: ldo.c,v 1.1 2003/11/19 08:17:06 yurand Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ #include <setjmp.h> #include <stdlib.h> #include <string.h> #define ldo_c #include "lua.h" #include "ldebug.h" #include "ldo.h" #include "lfunc.h" #include "lgc.h" #include "lmem.h" #include "lobject.h" #include "lopcodes.h" #include "lparser.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" #include "ltm.h" #include "lundump.h" #include "lvm.h" #include "lzio.h" /* ** {====================================================== ** Error-recovery functions (based on long jumps) ** ======================================================= */ /* chain list of long jump buffers */ struct lua_longjmp { struct lua_longjmp *previous; jmp_buf b; volatile int status; /* error code */ }; static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { switch (errcode) { case LUA_ERRMEM: { setsvalue2s(oldtop, luaS_new(L, MEMERRMSG)); break; } case LUA_ERRERR: { setsvalue2s(oldtop, luaS_new(L, "error in error handling")); break; } case LUA_ERRSYNTAX: case LUA_ERRRUN: { setobjs2s(oldtop, L->top - 1); /* error message on current top */ break; } } L->top = oldtop + 1; } void luaD_throw (lua_State *L, int errcode) { if (L->errorJmp) { L->errorJmp->status = errcode; longjmp(L->errorJmp->b, 1); } else { G(L)->panic(L); exit(EXIT_FAILURE); } } int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { struct lua_longjmp lj; lj.status = 0; lj.previous = L->errorJmp; /* chain new error handler */ L->errorJmp = &lj; if (setjmp(lj.b) == 0) (*f)(L, ud); L->errorJmp = lj.previous; /* restore old error handler */ return lj.status; } static void restore_stack_limit (lua_State *L) { L->stack_last = L->stack+L->stacksize-1; if (L->size_ci > LUA_MAXCALLS) { /* there was an overflow? */ int inuse = (L->ci - L->base_ci); if (inuse + 1 < LUA_MAXCALLS) /* can `undo' overflow? */ luaD_reallocCI(L, LUA_MAXCALLS); } } /* }====================================================== */ static void correctstack (lua_State *L, TObject *oldstack) { CallInfo *ci; GCObject *up; L->top = (L->top - oldstack) + L->stack; for (up = L->openupval; up != NULL; up = up->gch.next) gcotouv(up)->v = (gcotouv(up)->v - oldstack) + L->stack; for (ci = L->base_ci; ci <= L->ci; ci++) { ci->top = (ci->top - oldstack) + L->stack; ci->base = (ci->base - oldstack) + L->stack; } L->base = L->ci->base; } void luaD_reallocstack (lua_State *L, int newsize) { TObject *oldstack = L->stack; luaM_reallocvector(L, L->stack, L->stacksize, newsize, TObject); L->stacksize = newsize; L->stack_last = L->stack+newsize-1-EXTRA_STACK; correctstack(L, oldstack); } void luaD_reallocCI (lua_State *L, int newsize) { CallInfo *oldci = L->base_ci; luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); L->size_ci = cast(unsigned short, newsize); L->ci = (L->ci - oldci) + L->base_ci; L->end_ci = L->base_ci + L->size_ci; } void luaD_growstack (lua_State *L, int n) { if (n <= L->stacksize) /* double size is enough? */ luaD_reallocstack(L, 2*L->stacksize); else luaD_reallocstack(L, L->stacksize + n + EXTRA_STACK); } static void luaD_growCI (lua_State *L) { if (L->size_ci > LUA_MAXCALLS) /* overflow while handling overflow? */ luaD_throw(L, LUA_ERRERR); else { luaD_reallocCI(L, 2*L->size_ci); if (L->size_ci > LUA_MAXCALLS) luaG_runerror(L, "stack overflow"); } } void luaD_callhook (lua_State *L, int event, int line) { lua_Hook hook = L->hook; if (hook && L->allowhook) { ptrdiff_t top = savestack(L, L->top); ptrdiff_t ci_top = savestack(L, L->ci->top); lua_Debug ar; ar.event = event; ar.currentline = line; if (event == LUA_HOOKTAILRET) ar.i_ci = 0; /* tail call; no debug information about it */ else ar.i_ci = L->ci - L->base_ci; luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ L->ci->top = L->top + LUA_MINSTACK; L->allowhook = 0; /* cannot call hooks inside a hook */ lua_unlock(L); (*hook)(L, &ar); lua_lock(L); lua_assert(!L->allowhook); L->allowhook = 1; L->ci->top = restorestack(L, ci_top); L->top = restorestack(L, top); } } static void adjust_varargs (lua_State *L, int nfixargs, StkId base) { int i; Table *htab; TObject nname; int actual = L->top - base; /* actual number of arguments */ if (actual < nfixargs) { luaD_checkstack(L, nfixargs - actual); for (; actual < nfixargs; ++actual) setnilvalue(L->top++); } actual -= nfixargs; /* number of extra arguments */ htab = luaH_new(L, actual, 1); /* create `arg' table */ for (i=0; i<actual; i++) /* put extra arguments into `arg' table */ setobj2n(luaH_setnum(L, htab, i+1), L->top - actual + i); /* store counter in field `n' */ setsvalue(&nname, luaS_newliteral(L, "n")); setnvalue(luaH_set(L, htab, &nname), cast(lua... [truncated message content] |
From: <yu...@us...> - 2003-11-19 08:17:10
|
Update of /cvsroot/timewarp In directory sc8-pr-cvs1:/tmp/cvs-serv14966 Modified Files: twwin.dsp Log Message: lua support |
From: <yu...@us...> - 2003-11-19 08:14:33
|
Update of /cvsroot/timewarp/source/util/lua/lib In directory sc8-pr-cvs1:/tmp/cvs-serv14653/lib Log Message: Directory /cvsroot/timewarp/source/util/lua/lib added to the repository |
From: <yu...@us...> - 2003-11-19 08:13:52
|
Update of /cvsroot/timewarp/source/util/lua In directory sc8-pr-cvs1:/tmp/cvs-serv14549/lua Log Message: Directory /cvsroot/timewarp/source/util/lua added to the repository |
From: <geo...@us...> - 2003-11-19 00:25:37
|
Update of /cvsroot/timewarp/source/newships In directory sc8-pr-cvs1:/tmp/cvs-serv13444 Modified Files: shpconca.cpp Log Message: added check, so that enemy cargo isn't picked up anymore Index: shpconca.cpp =================================================================== RCS file: /cvsroot/timewarp/source/newships/shpconca.cpp,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** shpconca.cpp 25 Oct 2003 14:30:20 -0000 1.10 --- shpconca.cpp 19 Nov 2003 00:25:34 -0000 1.11 *************** *** 580,588 **** void ConfedCargotran::inflict_damage(SpaceObject *other) { ! STACKTRACE Ship::inflict_damage(other); // check if the other thing is a crate (doesn't matter which ship it belongs to) ! if ( other->id == CARGOCRATE_ID ) { // add that crate as a new link at the end of the cargotrain: --- 580,592 ---- void ConfedCargotran::inflict_damage(SpaceObject *other) { ! STACKTRACE; ! if (!(other && other->exists())) ! return; ! Ship::inflict_damage(other); // check if the other thing is a crate (doesn't matter which ship it belongs to) ! // ... but, only add it, if it's owned by that particular ship. ! if ( (other->id == CARGOCRATE_ID) && (other->ship == this) ) { // add that crate as a new link at the end of the cargotrain: |
From: <geo...@us...> - 2003-11-19 00:15:30
|
Update of /cvsroot/timewarp/source/newships In directory sc8-pr-cvs1:/tmp/cvs-serv11348 Modified Files: shpbubex.cpp Log Message: removed alternating fire Index: shpbubex.cpp =================================================================== RCS file: /cvsroot/timewarp/source/newships/shpbubex.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** shpbubex.cpp 18 Nov 2003 18:20:16 -0000 1.6 --- shpbubex.cpp 19 Nov 2003 00:15:24 -0000 1.7 *************** *** 12,17 **** int weaponArmour; int weaponOffset; ! double weaponDriftVelocity; ! int shield; double specialRange; --- 12,17 ---- int weaponArmour; int weaponOffset; ! // double weaponDriftVelocity; ! // int shield; double specialRange; *************** *** 35,39 **** public: BubalosMissile(double ox, double oy, double oangle, double ov, int odamage, ! double weaponDriftVelocity, double orange, int oarmour, Ship *oship, SpaceSprite *osprite); virtual void inflict_damage (SpaceObject *other); --- 35,39 ---- public: BubalosMissile(double ox, double oy, double oangle, double ov, int odamage, ! /*double weaponDriftVelocity, */double orange, int oarmour, Ship *oship, SpaceSprite *osprite); virtual void inflict_damage (SpaceObject *other); *************** *** 48,53 **** weaponDamage = get_config_int("Weapon", "Damage", 0); weaponArmour = get_config_int("Weapon", "Armour", 0); ! weaponDriftVelocity = scale_velocity(get_config_int("Weapon", "DriftVelocity", 0)); ! shield = get_config_int("Extra", "AbsorberShield", 0); reverse_frame = 0; --- 48,53 ---- weaponDamage = get_config_int("Weapon", "Damage", 0); weaponArmour = get_config_int("Weapon", "Armour", 0); ! // weaponDriftVelocity = scale_velocity(get_config_int("Weapon", "DriftVelocity", 0)); ! // shield = get_config_int("Extra", "AbsorberShield", 0); reverse_frame = 0; *************** *** 61,65 **** void BubalosExecutioner::calculate() { ! STACKTRACE Ship::calculate(); --- 61,65 ---- void BubalosExecutioner::calculate() { ! STACKTRACE; Ship::calculate(); *************** *** 81,88 **** int BubalosExecutioner::activate_weapon() { ! STACKTRACE add(new BubalosMissile(10.5*(weaponOffset-1), 44, angle, weaponVelocity, weaponDamage, ! weaponDriftVelocity,weaponRange, weaponArmour, this, data->spriteWeapon)); weaponOffset = (weaponOffset + 1) % 3; --- 81,88 ---- int BubalosExecutioner::activate_weapon() { ! STACKTRACE; add(new BubalosMissile(10.5*(weaponOffset-1), 44, angle, weaponVelocity, weaponDamage, ! /*weaponDriftVelocity,*/weaponRange, weaponArmour, this, data->spriteWeapon)); weaponOffset = (weaponOffset + 1) % 3; *************** *** 92,96 **** int BubalosExecutioner::activate_special() { ! STACKTRACE //double shpAngle; --- 92,96 ---- int BubalosExecutioner::activate_special() { ! STACKTRACE; //double shpAngle; *************** *** 108,117 **** if (normal > 0) { ! // removed the armor // normal -= shield; // if (normal <= 0) // normal = 1; ! batt += normal; if (batt > batt_max) batt = batt_max; } --- 108,118 ---- if (normal > 0) { ! // remove the armor damage reduction // normal -= shield; // if (normal <= 0) // normal = 1; ! // remove the batt for damage quirk ! // batt += normal; if (batt > batt_max) batt = batt_max; } *************** *** 120,133 **** BubalosMissile::BubalosMissile(double ox, double oy, double oangle, double ov, ! int odamage, double weaponDriftVelocity, double orange, int oarmour, Ship *oship, SpaceSprite *osprite) : ! Missile(oship, Vector2(ox,oy), oangle, ov, odamage, orange, oarmour, oship, osprite), ! kick(weaponDriftVelocity) {} void BubalosMissile::inflict_damage (SpaceObject *other) { ! STACKTRACE ! if (other->mass) ! other->accelerate (this, angle, kick / other->mass, MAX_SPEED); Missile::inflict_damage(other); } --- 121,136 ---- BubalosMissile::BubalosMissile(double ox, double oy, double oangle, double ov, ! int odamage, /*double weaponDriftVelocity,*/ double orange, int oarmour, Ship *oship, SpaceSprite *osprite) : ! Missile(oship, Vector2(ox,oy), oangle, ov, odamage, orange, oarmour, oship, osprite)/*, ! kick(weaponDriftVelocity)*/ {} void BubalosMissile::inflict_damage (SpaceObject *other) { ! STACKTRACE; ! ! // remove the weapon-bounce quirk. ! //if (other->mass) ! // other->accelerate (this, angle, kick / other->mass, MAX_SPEED); Missile::inflict_damage(other); } |
From: <geo...@us...> - 2003-11-19 00:15:07
|
Update of /cvsroot/timewarp/source/newships In directory sc8-pr-cvs1:/tmp/cvs-serv11235 Modified Files: shpbubbo.cpp Log Message: removed batt quirk, armor quirk, and bounce effect. Index: shpbubbo.cpp =================================================================== RCS file: /cvsroot/timewarp/source/newships/shpbubbo.cpp,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** shpbubbo.cpp 15 Nov 2003 20:48:07 -0000 1.13 --- shpbubbo.cpp 19 Nov 2003 00:15:03 -0000 1.14 *************** *** 233,237 **** int wo = (weapon_offset>3)?(6-weapon_offset):weapon_offset; ! weapon_offset = (weapon_offset + 1) % 6; double dx; --- 233,239 ---- int wo = (weapon_offset>3)?(6-weapon_offset):weapon_offset; ! ! // remove the alternating fire ! /* weapon_offset = (weapon_offset + 1) % 6; double dx; *************** *** 243,246 **** --- 245,251 ---- default: tw_error("Unexpected value of weapon_offset"); dx=0;break; } + */ + double dx; + dx = 0; BMIRV = new BubalosMIRV(dx, 54 * Direction, FireAngle,weaponVelocity, |
From: <geo...@us...> - 2003-11-18 18:20:57
|
Update of /cvsroot/timewarp/source/newships In directory sc8-pr-cvs1:/tmp/cvs-serv29549 Modified Files: shpgerhe.cpp Log Message: dunno what happened, just returning the result of merge Index: shpgerhe.cpp =================================================================== RCS file: /cvsroot/timewarp/source/newships/shpgerhe.cpp,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** shpgerhe.cpp 15 Nov 2003 20:48:07 -0000 1.13 --- shpgerhe.cpp 18 Nov 2003 18:20:53 -0000 1.14 *************** *** 969,973 **** if ( mother->crew > mother->crew_max ) mother->crew = mother->crew_max; ! mother->update_panel; } --- 969,973 ---- if ( mother->crew > mother->crew_max ) mother->crew = mother->crew_max; ! mother->update_panel = true; } |
From: <geo...@us...> - 2003-11-18 18:20:20
|
Update of /cvsroot/timewarp/source/newships In directory sc8-pr-cvs1:/tmp/cvs-serv29421 Modified Files: shpbubex.cpp Log Message: ship tweak for MRT Index: shpbubex.cpp =================================================================== RCS file: /cvsroot/timewarp/source/newships/shpbubex.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** shpbubex.cpp 20 Oct 2003 11:00:28 -0000 1.5 --- shpbubex.cpp 18 Nov 2003 18:20:16 -0000 1.6 *************** *** 71,75 **** if (reverse_frame > 0) ! add(new PositionedAnimation(this, this, Vector2(0,(reverse_frame-3)*6.0), data->spriteExtra, 0, 1, 160, LAYER_EXPLOSIONS)); else --- 71,75 ---- if (reverse_frame > 0) ! add(new PositionedAnimation(this, this, Vector2((reverse_frame-3)*6.0, 0), data->spriteExtra, 0, 1, 160, LAYER_EXPLOSIONS)); else *************** *** 104,112 **** int BubalosExecutioner::handle_damage(SpaceLocation *source, double normal, double direct) { ! STACKTRACE if (normal > 0) { ! normal -= shield; ! if (normal <= 0) ! normal = 1; batt += normal; --- 104,115 ---- int BubalosExecutioner::handle_damage(SpaceLocation *source, double normal, double direct) { ! STACKTRACE; ! if (normal > 0) { ! ! // removed the armor ! // normal -= shield; ! // if (normal <= 0) ! // normal = 1; batt += normal; |
From: <geo...@us...> - 2003-11-18 18:14:47
|
Update of /cvsroot/timewarp In directory sc8-pr-cvs1:/tmp/cvs-serv28287 Modified Files: twwin.dsp Log Message: updating project |
From: <geo...@us...> - 2003-11-18 17:21:16
|
Update of /cvsroot/timewarp/source In directory sc8-pr-cvs1:/tmp/cvs-serv20229 Modified Files: scp.cpp Log Message: to enter the full-game Index: scp.cpp =================================================================== RCS file: /cvsroot/timewarp/source/scp.cpp,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** scp.cpp 15 Nov 2003 11:04:17 -0000 1.24 --- scp.cpp 18 Nov 2003 17:21:11 -0000 1.25 *************** *** 68,72 **** #define SCPGUI_TITLE 1 ! //#include "gamex/projectx.h" // for future use (Rob) --- 68,72 ---- #define SCPGUI_TITLE 1 ! #include "gamex/projectx.h" // for future use (Rob) *************** *** 165,169 **** MAIN_DIALOG_HELP, MAIN_DIALOG_EXIT, ! // MAIN_DIALOG_FG, }; --- 165,169 ---- MAIN_DIALOG_HELP, MAIN_DIALOG_EXIT, ! MAIN_DIALOG_FG, }; *************** *** 177,181 **** { d_button_proc, 45, 185, 170, 30, 255, 0, 0, D_EXIT, 0, 0, (void *)"Help", NULL, NULL }, { d_button_proc, 45, 220, 170, 30, 255, 0, 0, D_EXIT, 0, 0, (void *)"Exit", NULL, NULL }, ! // { d_button_proc, 550, 440, 50, 30, 255, 0, 0, D_EXIT, 0, 0, (void *)"FG" , NULL, NULL }, { d_tw_yield_proc, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, NULL, NULL, NULL }, { NULL, 0, 0, 0, 0, 255, 0, 0, 0, 1, 0, NULL, NULL, NULL } --- 177,181 ---- { d_button_proc, 45, 185, 170, 30, 255, 0, 0, D_EXIT, 0, 0, (void *)"Help", NULL, NULL }, { d_button_proc, 45, 220, 170, 30, 255, 0, 0, D_EXIT, 0, 0, (void *)"Exit", NULL, NULL }, ! { d_button_proc, 550, 440, 50, 30, 255, 0, 0, D_EXIT, 0, 0, (void *)"FG" , NULL, NULL }, { d_tw_yield_proc, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, NULL, NULL, NULL }, { NULL, 0, 0, 0, 0, 255, 0, 0, 0, 1, 0, NULL, NULL, NULL } *************** *** 638,649 **** showTitle(); break; ! /* case MAIN_DIALOG_FG: // for future use (Rob) disable(); ! play_fg(scp, SCPGUI_MUSIC); enable(); break; ! */ } } while((mainRet != MAIN_DIALOG_EXIT) && (mainRet != -1)); --- 638,649 ---- showTitle(); break; ! // /* case MAIN_DIALOG_FG: // for future use (Rob) disable(); ! play_fg(&scp, SCPGUI_MUSIC); enable(); break; ! // */ } } while((mainRet != MAIN_DIALOG_EXIT) && (mainRet != -1)); |