├── llcommon ├── lluuid.h ├── llstring.h ├── llerror.h ├── string_table.h ├── llformat.h ├── linden_common.h ├── stdtypes.h ├── stringize.h ├── llstringtable.h ├── llmap.h ├── lldefs.h ├── llpreprocessor.h ├── llstringtable.cpp ├── llfile.h ├── llstl.h └── linked_lists.h ├── .gitignore ├── indra.l.hpp ├── lscript_scope.cpp ├── lscript_resource.cpp ├── lscript_resource.h ├── lslcomp.cpp ├── lscript ├── lscript_byteconvert.h ├── lscript_library.h └── lscript_byteformat.h ├── README.md ├── Makefile ├── lscript_typecheck.h ├── lscript_error.cpp ├── indralex.py ├── lscript_error.h ├── lscript_library └── lscript_library.cpp.in ├── lscript_scope.h ├── indra.l.in └── lscript_typecheck.cpp /llcommon/lluuid.h: -------------------------------------------------------------------------------- 1 | #ifndef _LLUUID__H_ 2 | #define _LLUUID__H_ 3 | 4 | typedef char *LLUUID; 5 | 6 | #endif /* _LLERROR__H_ */ 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.x 3 | *.o 4 | indra.l 5 | indra.l.cpp 6 | indra.y.cpp 7 | indra.y.hpp 8 | lscript_library/lscript_library.cpp 9 | lslcomp 10 | -------------------------------------------------------------------------------- /llcommon/llstring.h: -------------------------------------------------------------------------------- 1 | #ifndef _LLSTRING__H_ 2 | #define _LLSTRING__H_ 3 | 4 | inline std::string ll_safe_string(const char* in) 5 | { 6 | if(in) return std::string(in); 7 | return std::string(); 8 | } 9 | 10 | #endif /* _LLSTRING__H_ */ 11 | -------------------------------------------------------------------------------- /indra.l.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _INDRA__L__HPP_ 2 | #define _INDRA__L__HPP_ 3 | 4 | #include "stdtypes.h" 5 | 6 | BOOL lscript_compile(const char* src_filename, const char* dst_filename, 7 | const char* err_filename, BOOL compile_to_mono, const char* class_name, BOOL is_god_like); 8 | 9 | BOOL lscript_compile(char *filename, BOOL compile_to_mono, BOOL is_god_like = FALSE); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /llcommon/llerror.h: -------------------------------------------------------------------------------- 1 | #ifndef _LLERROR__H_ 2 | #define _LLERROR__H_ 3 | 4 | #include 5 | #include 6 | #define llerr std::cerr << "Error: " 7 | #define llwarn std::cerr << "Warning: " 8 | #define lldebug std::cerr << "Debug: " 9 | #define llendl std::endl 10 | #define llerror(msg, lvl) llerr << (msg) << " (lvl=" << (lvl) << ")" << llendl 11 | #define LL_ERRS(x) std::cerr << x "Error: " << ": " 12 | #define LL_WARNS(x) std::cerr << x "Warning: " << ": " 13 | #define LL_DEBUGS(x) std::cerr << x "Warning: " << ": " 14 | #define LL_ENDL std::endl 15 | #define llassert assert 16 | //#define LL_BAD_TEMPLATE_INSTANTIATION(type, msg) static_assert(false, msg) 17 | 18 | #endif /* _LLERROR__H_ */ 19 | -------------------------------------------------------------------------------- /llcommon/string_table.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file string_table.h 3 | * @brief Legacy wrapper header. 4 | * 5 | * $LicenseInfo:firstyear=2000&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | #include "llstringtable.h" 27 | -------------------------------------------------------------------------------- /lscript_scope.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lscript_scope.cpp 3 | * @brief builds nametable and checks scope 4 | * 5 | * $LicenseInfo:firstyear=2002&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #include "linden_common.h" 28 | 29 | #include "lscript_tree.h" 30 | 31 | LLStringTable *gScopeStringTable; 32 | -------------------------------------------------------------------------------- /lscript_resource.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lscript_resource.cpp 3 | * @brief resource determination prior to assembly 4 | * 5 | * $LicenseInfo:firstyear=2002&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #include "linden_common.h" 28 | 29 | #include "lscript_resource.h" 30 | 31 | void init_temp_jumps() 32 | { 33 | gTempJumpCount = 0; 34 | } 35 | 36 | S32 gTempJumpCount = 0; 37 | -------------------------------------------------------------------------------- /lscript_resource.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lscript_resource.h 3 | * @brief resource determination prior to assembly 4 | * 5 | * $LicenseInfo:firstyear=2002&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #ifndef LL_LSCRIPT_RESOURCE_H 28 | #define LL_LSCRIPT_RESOURCE_H 29 | 30 | #include "lscript_scope.h" 31 | 32 | void init_temp_jumps(); 33 | 34 | extern S32 gTempJumpCount; 35 | 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /llcommon/llformat.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file llformat.h 3 | * @date January 2007 4 | * @brief string formatting utility 5 | * 6 | * $LicenseInfo:firstyear=2007&license=viewerlgpl$ 7 | * Second Life Viewer Source Code 8 | * Copyright (C) 2010, Linden Research, Inc. 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; 13 | * version 2.1 of the License only. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public 21 | * License along with this library; if not, write to the Free Software 22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 | * 24 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 25 | * $/LicenseInfo$ 26 | */ 27 | 28 | #ifndef LL_LLFORMAT_H 29 | #define LL_LLFORMAT_H 30 | 31 | // Use as follows: 32 | // llinfos << llformat("Test:%d (%.2f %.2f)", idx, x, y) << llendl; 33 | // 34 | // *NOTE: buffer limited to 1024, (but vsnprintf prevents overrun) 35 | // should perhaps be replaced with boost::format. 36 | 37 | std::string LL_COMMON_API llformat(const char *fmt, ...); 38 | 39 | // the same version as above but ensures that returned string is in utf8 on windows 40 | // to enable correct converting utf8_to_wstring. 41 | std::string LL_COMMON_API llformat_to_utf8(const char *fmt, ...); 42 | 43 | #endif // LL_LLFORMAT_H 44 | -------------------------------------------------------------------------------- /lslcomp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "indra.l.hpp" 4 | 5 | // http_request string constants 6 | const char* URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED"; 7 | const char* URL_REQUEST_DENIED = "URL_REQUEST_DENIED"; 8 | #define MAX_STRING 255 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | char base_filename[MAX_STRING]; 13 | int i, len; 14 | char *dot; 15 | if (argc < 2) 16 | { 17 | fputs("Requires a filename without extension.\n", stderr); 18 | return 1; 19 | } 20 | // lscript_compile(argv[1], true); 21 | len = strlen(argv[1]); 22 | // leave room for ".lsl.pp\0" (length 8) 23 | if (len > MAX_STRING - 8) 24 | { 25 | fputs("Input filename too long.\n", stderr); 26 | return 1; 27 | } 28 | dot = strrchr(argv[1], '.'); 29 | if (dot == NULL) 30 | dot = argv[1] + len; 31 | 32 | strncpy(base_filename, argv[1], dot - argv[1]); 33 | base_filename[dot - argv[1]] = '\0'; 34 | 35 | char src_filename[MAX_STRING]; 36 | if (*dot == '.') 37 | sprintf(src_filename, "%s", argv[1]); // use the arg verbatim 38 | else 39 | sprintf(src_filename, "%s.lsl", base_filename); // append .lsl 40 | char err_filename[MAX_STRING]; 41 | sprintf(err_filename, "%s.out", base_filename); 42 | //char class_name[MAX_STRING]; 43 | //sprintf(class_name, "%s", argv[1]); 44 | char bin_name[MAX_STRING]; 45 | sprintf(bin_name, "%s.cil", base_filename); 46 | 47 | lscript_compile(src_filename, bin_name, err_filename, true, "1f1f1f1f-1f1f-1f1f-1f1f-1f1f1f1f1f1f", false); 48 | 49 | // Don't generate LSO bytecode as we've removed LSO output code. 50 | // sprintf(bin_name, "%s.lso", base_filename); 51 | // lscript_compile(src_filename, bin_name, err_filename, false, class_name, false); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /lscript/lscript_byteconvert.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lscript_byteconvert.h 3 | * @brief Shared code for compiler and assembler for LSL 4 | * 5 | * $LicenseInfo:firstyear=2002&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | // data shared between compiler/assembler 28 | // used to convert data between byte stream and outside data types 29 | 30 | #ifndef LL_LSCRIPT_BYTECONVERT_H 31 | #define LL_LSCRIPT_BYTECONVERT_H 32 | 33 | #include "lscript_byteformat.h" 34 | 35 | static inline LSCRIPTType char2type(char type) 36 | { 37 | switch(type) 38 | { 39 | case 'i': 40 | return LST_INTEGER; 41 | case 'f': 42 | return LST_FLOATINGPOINT; 43 | case 's': 44 | return LST_STRING; 45 | case 'k': 46 | return LST_KEY; 47 | case 'v': 48 | return LST_VECTOR; 49 | case 'q': 50 | return LST_QUATERNION; 51 | case 'l': 52 | return LST_LIST; 53 | default: 54 | return LST_NULL; 55 | } 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /llcommon/linden_common.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file linden_common.h 3 | * @brief Includes common headers that are always safe to include 4 | * 5 | * $LicenseInfo:firstyear=2001&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #ifndef LL_LINDEN_COMMON_H 28 | #define LL_LINDEN_COMMON_H 29 | 30 | // *NOTE: Please keep includes here to a minimum! 31 | // 32 | // Files included here are included in every library .cpp file and 33 | // are not precompiled. 34 | 35 | #if defined(LL_WINDOWS) && defined(_DEBUG) 36 | # if _MSC_VER >= 1400 // Visual C++ 2005 or later 37 | # define _CRTDBG_MAP_ALLOC 38 | # include 39 | # include 40 | # endif 41 | #endif 42 | 43 | #include "llpreprocessor.h" 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | // Linden only libs in alpha-order other than stdtypes.h 56 | // *NOTE: Please keep includes here to a minimum, see above. 57 | #include "stdtypes.h" 58 | #include "lldefs.h" 59 | #include "llerror.h" 60 | #include "llfile.h" 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LSL-compiler 2 | 3 | This is a standalone LSL compiler, extracted from the viewer sources. Its main purpose is to allow the analysis of the generated code, providing an insight into the internals of Mono and LSO, but it can also be used as an external syntax checking tool. 4 | 5 | This version includes some fixes and code changes that are believed to exist in the server (like the output of ldloc/stloc), or that do not affect compilation or generated code (like fixes to the pretty printer). 6 | 7 | ## Building 8 | 9 | Building requires installation of [**kwdb**](https://bitbucket.org/Sei_Lisa/kwdb). The file `indralex.py` present in the source should be copied to **kwdb**'s `lsl2dfg/lsloutputs/` directory. Edit `Makefile` to point to the installation directory of **kwdb** and to modify the compiler options if required. 10 | 11 | **kwdb** in turn requires **python 2**. **flex** and **bison** are also required. And of course, a C++ compiler (tested with **g++** only). 12 | 13 | ## Running 14 | 15 | Run by entering: 16 | 17 | ``` 18 | ./lslcomp 19 | ``` 20 | 21 | The input script's extension defaults to `.lsl` if not specified. In case of successful compilation, it generates the following files: 22 | 23 | - An `.out` file with the LSO assembler output. 24 | - A `.cil` file with the Mono assembler output. 25 | - An `.lsl.pp` (or whatever the original extension was, with `.pp` appended) file with the pretty-printed script output. 26 | 27 | In case of error, the error message is displayed in standard error, and the `.out` file and possibly the `.lsl.pp` file are still generated. 28 | 29 | The generated `.cil` file is suitable as input to the Mono assembler, which can generate a `.dll` with this command: 30 | 31 | ``` 32 | ilasm /dll .cil 33 | ``` 34 | 35 | (assuming you have the **mono-devel** package). 36 | 37 | ## License 38 | 39 | This program, like the viewer sources it is based on, is licensed under the GNU LGPL v2.1. 40 | 41 | Copyright © 2010 Linden Research, Inc. 42 | Copyright © 2017 Sei Lisa. 43 | 44 | Sei Lisa is the author's user name in the Second Life® virtual world. 45 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CXX=g++ 2 | CPPFLAGS=-DLINUX=1 -Illcommon -Ilscript -DEMERGENCY_DEBUG_PRINTOUTS 3 | CFLAGS=-g -O0 4 | LDFLAGS= 5 | 6 | LSLK=~/apps/secondlife/scripts/lslkeywords/ 7 | 8 | all : lslcomp 9 | 10 | indra.l : indra.l.in 11 | $(LSLK)lsl2dfg/LSL2dfg.py -y -d $(LSLK)database/kwdb.xml -g sl -f indralex -i $< -o $@ 12 | 13 | lscript_library/lscript_library.cpp : lscript_library/lscript_library.cpp.in 14 | \ 15 | $(LSLK)lsl2dfg/LSL2dfg.py -d $(LSLK)database/kwdb.xml -g sl -f viewersrc -i $<\ 16 | | $(LSLK)lsl2dfg/LSL2dfg.py -d $(LSLK)database/kwdb.xml -f viewersrc -g os,-sl -t OSSL\ 17 | | $(LSLK)lsl2dfg/LSL2dfg.py -d $(LSLK)database/kwdb.xml -f viewersrc -g aa,-os,-sl -t AA -o $@ 18 | 19 | 20 | indra.l.cpp : indra.l 21 | flex -P indra_ -o indra.l.cpp indra.l 22 | 23 | indra.y.cpp indra.y.hpp : indra.y 24 | bison -p indra_ -d -o indra.y.cpp indra.y 25 | 26 | 27 | %.o : %.cpp 28 | $(CXX) -c $(CFLAGS) $(CPPFLAGS) "$<" -o "$@" 29 | 30 | # Known problem: there are more unlisted dependencies than these, 31 | # mainly lots of .h files, but we're not analyzing them. Make clean if 32 | # in doubt. 33 | lscript_library/lscript_library.o : lscript_library/lscript_library.cpp 34 | lslcomp.o : lslcomp.cpp 35 | lscript_error.o : lscript_error.cpp 36 | lscript_resource.o : lscript_resource.cpp 37 | lscript_scope.o : lscript_scope.cpp 38 | lscript_tree.o : lscript_tree.cpp llcommon/llstring.h 39 | lscript_typecheck.o : lscript_typecheck.cpp 40 | indra.l.o : indra.l.cpp indra.y.hpp 41 | indra.y.o : indra.y.cpp indra.y.hpp 42 | llcommon/llfile.o : llcommon/llfile.cpp 43 | llcommon/llstringtable.o : llcommon/llstringtable.cpp 44 | 45 | lslcomp : lslcomp.o indra.l.o indra.y.o\ 46 | lscript_library/lscript_library.o\ 47 | lscript_error.o lscript_resource.o\ 48 | lscript_scope.o lscript_tree.o\ 49 | lscript_typecheck.o\ 50 | llcommon/llfile.o llcommon/llstringtable.o 51 | g++ $(CFLAGS) $(LDFLAGS) lslcomp.o indra.l.o indra.y.o\ 52 | lscript_library/lscript_library.o\ 53 | lscript_error.o lscript_resource.o\ 54 | lscript_scope.o lscript_tree.o\ 55 | lscript_typecheck.o\ 56 | llcommon/llfile.o llcommon/llstringtable.o\ 57 | -o lslcomp 58 | 59 | 60 | clean : 61 | rm -f lslcomp *.o lscript_library/*.o llcommon/*.o\ 62 | indra.l.cpp indra.l indra.y.cpp indra.y.hpp\ 63 | lscript_library/lscript_library.cpp 64 | 65 | .PHONY : all clean 66 | -------------------------------------------------------------------------------- /llcommon/stdtypes.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file stdtypes.h 3 | * @brief Basic type declarations for cross platform compatibility. 4 | * 5 | * $LicenseInfo:firstyear=2000&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | #ifndef LL_STDTYPES_H 27 | #define LL_STDTYPES_H 28 | 29 | #include 30 | #include 31 | 32 | typedef signed char S8; 33 | typedef unsigned char U8; 34 | typedef signed short S16; 35 | typedef unsigned short U16; 36 | typedef signed int S32; 37 | typedef unsigned int U32; 38 | 39 | #if LL_WINDOWS 40 | // Windows wchar_t is 16-bit 41 | typedef U32 llwchar; 42 | #else 43 | typedef wchar_t llwchar; 44 | #endif 45 | 46 | #if LL_WINDOWS 47 | typedef signed __int64 S64; 48 | // probably should be 'hyper' or similiar 49 | #define S64L(a) (a) 50 | typedef unsigned __int64 U64; 51 | #define U64L(a) (a) 52 | #else 53 | typedef long long int S64; 54 | typedef long long unsigned int U64; 55 | #if LL_DARWIN || LL_LINUX || LL_SOLARIS 56 | #define S64L(a) (a##LL) 57 | #define U64L(a) (a##ULL) 58 | #endif 59 | #endif 60 | 61 | typedef float F32; 62 | typedef double F64; 63 | 64 | typedef S32 BOOL; 65 | typedef U8 KEY; 66 | typedef U32 MASK; 67 | typedef U32 TPACKETID; 68 | 69 | // Use #define instead of consts to avoid conversion headaches 70 | #define S8_MAX (SCHAR_MAX) 71 | #define U8_MAX (UCHAR_MAX) 72 | #define S16_MAX (SHRT_MAX) 73 | #define U16_MAX (USHRT_MAX) 74 | #define S32_MAX (INT_MAX) 75 | #define U32_MAX (UINT_MAX) 76 | #define F32_MAX (FLT_MAX) 77 | #define F64_MAX (DBL_MAX) 78 | 79 | #define S8_MIN (SCHAR_MIN) 80 | #define U8_MIN (0) 81 | #define S16_MIN (SHRT_MIN) 82 | #define U16_MIN (0) 83 | #define S32_MIN (INT_MIN) 84 | #define U32_MIN (0) 85 | #define F32_MIN (FLT_MIN) 86 | #define F64_MIN (DBL_MIN) 87 | 88 | 89 | #ifndef TRUE 90 | #define TRUE (1) 91 | #endif 92 | 93 | #ifndef FALSE 94 | #define FALSE (0) 95 | #endif 96 | 97 | #ifndef NULL 98 | #define NULL (0) 99 | #endif 100 | 101 | typedef U8 LLPCode; 102 | 103 | #define LL_ARRAY_SIZE( _kArray ) ( sizeof( (_kArray) ) / sizeof( _kArray[0] ) ) 104 | 105 | #if LL_LINUX && __GNUC__ <= 2 106 | typedef int intptr_t; 107 | #endif 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /llcommon/stringize.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file stringize.h 3 | * @author Nat Goodspeed 4 | * @date 2008-12-17 5 | * @brief stringize(item) template function and STRINGIZE(expression) macro 6 | * 7 | * $LicenseInfo:firstyear=2008&license=viewerlgpl$ 8 | * Second Life Viewer Source Code 9 | * Copyright (C) 2010, Linden Research, Inc. 10 | * 11 | * This library is free software; you can redistribute it and/or 12 | * modify it under the terms of the GNU Lesser General Public 13 | * License as published by the Free Software Foundation; 14 | * version 2.1 of the License only. 15 | * 16 | * This library is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 | * Lesser General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU Lesser General Public 22 | * License along with this library; if not, write to the Free Software 23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 24 | * 25 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 26 | * $/LicenseInfo$ 27 | */ 28 | 29 | #if ! defined(LL_STRINGIZE_H) 30 | #define LL_STRINGIZE_H 31 | 32 | #include 33 | #include 34 | 35 | /** 36 | * stringize(item) encapsulates an idiom we use constantly, using 37 | * operator<<(std::ostringstream&, TYPE) followed by std::ostringstream::str() 38 | * to render a string expressing some item. 39 | */ 40 | template 41 | std::string stringize(const T& item) 42 | { 43 | std::ostringstream out; 44 | out << item; 45 | return out.str(); 46 | } 47 | 48 | /** 49 | * stringize_f(functor) 50 | */ 51 | template 52 | std::string stringize_f(Functor const & f) 53 | { 54 | std::ostringstream out; 55 | f(out); 56 | return out.str(); 57 | } 58 | 59 | /** 60 | * STRINGIZE(item1 << item2 << item3 ...) effectively expands to the 61 | * following: 62 | * @code 63 | * std::ostringstream out; 64 | * out << item1 << item2 << item3 ... ; 65 | * return out.str(); 66 | * @endcode 67 | */ 68 | #define STRINGIZE(EXPRESSION) (stringize_f(boost::lambda::_1 << EXPRESSION)) 69 | 70 | 71 | /** 72 | * destringize(str) 73 | * defined for symmetry with stringize 74 | * *NOTE - this has distinct behavior from boost::lexical_cast regarding 75 | * leading/trailing whitespace and handling of bad_lexical_cast exceptions 76 | */ 77 | template 78 | T destringize(std::string const & str) 79 | { 80 | T val; 81 | std::istringstream in(str); 82 | in >> val; 83 | return val; 84 | } 85 | 86 | /** 87 | * destringize_f(str, functor) 88 | */ 89 | template 90 | void destringize_f(std::string const & str, Functor const & f) 91 | { 92 | std::istringstream in(str); 93 | f(in); 94 | } 95 | 96 | /** 97 | * DESTRINGIZE(str, item1 >> item2 >> item3 ...) effectively expands to the 98 | * following: 99 | * @code 100 | * std::istringstream in(str); 101 | * in >> item1 >> item2 >> item3 ... ; 102 | * @endcode 103 | */ 104 | #define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), (boost::lambda::_1 >> EXPRESSION))) 105 | 106 | 107 | #endif /* ! defined(LL_STRINGIZE_H) */ 108 | -------------------------------------------------------------------------------- /lscript_typecheck.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lscript_typecheck.h 3 | * @brief typechecks script 4 | * 5 | * $LicenseInfo:firstyear=2002&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #ifndef LL_LSCRIPT_TYPECHECK_H 28 | #define LL_LSCRIPT_TYPECHECK_H 29 | 30 | #include "lscript_error.h" 31 | 32 | LSCRIPTType implicit_casts(LSCRIPTType left_side, LSCRIPTType right_side); 33 | BOOL legal_casts(LSCRIPTType cast, LSCRIPTType base); 34 | LSCRIPTType promote(LSCRIPTType left_side, LSCRIPTType right_side); 35 | BOOL legal_assignment(LSCRIPTType left_side, LSCRIPTType right_side); 36 | 37 | typedef enum e_lscript_expression_types 38 | { 39 | LET_NULL, 40 | LET_ASSIGNMENT, 41 | LET_ADD_ASSIGN, 42 | LET_SUB_ASSIGN, 43 | LET_MUL_ASSIGN, 44 | LET_DIV_ASSIGN, 45 | LET_MOD_ASSIGN, 46 | LET_EQUALITY, 47 | LET_NOT_EQUALS, 48 | LET_LESS_EQUALS, 49 | LET_GREATER_EQUALS, 50 | LET_LESS_THAN, 51 | LET_GREATER_THAN, 52 | LET_PLUS, 53 | LET_MINUS, 54 | LET_TIMES, 55 | LET_DIVIDE, 56 | LET_MOD, 57 | LET_BIT_AND, 58 | LET_BIT_OR, 59 | LET_BIT_XOR, 60 | LET_BOOLEAN_AND, 61 | LET_BOOLEAN_OR, 62 | LET_PARENTHESIS, 63 | LET_UNARY_MINUS, 64 | LET_BOOLEAN_NOT, 65 | LET_BIT_NOT, 66 | LET_PRE_INCREMENT, 67 | LET_PRE_DECREMENT, 68 | LET_CAST, 69 | LET_VECTOR_INITIALIZER, 70 | LET_QUATERNION_INITIALIZER, 71 | LET_LIST_INITIALIZER, 72 | LET_LVALUE, 73 | LET_POST_INCREMENT, 74 | LET_POST_DECREMENT, 75 | LET_FUNCTION_CALL, 76 | LET_CONSTANT, 77 | LET_FOR_EXPRESSION_LIST, 78 | LET_FUNC_EXPRESSION_LIST, 79 | LET_LIST_EXPRESSION_LIST, 80 | LET_PRINT, 81 | LET_SHIFT_LEFT, 82 | LET_SHIFT_RIGHT, 83 | LET_EOF 84 | } LSCRIPTExpressionType; 85 | 86 | BOOL legal_binary_expression(LSCRIPTType &result, LSCRIPTType left_side, LSCRIPTType right_side, LSCRIPTExpressionType expression); 87 | BOOL legal_unary_expression(LSCRIPTType &result, LSCRIPTType left_side, LSCRIPTExpressionType expression); 88 | 89 | void init_supported_expressions(void); 90 | 91 | /* 92 | LScript automatic type casting 93 | 94 | LST_INTEGER -> LST_INTEGER 95 | 96 | LST_FLOATINGPOINT -> LST_FLOATINGPOINT 97 | LST_INTEGER -> LST_FLOATINGPOINT 98 | 99 | LST_FLOATINGPOINT -> LST_STRING 100 | LST_INTEGER -> LST_STRING 101 | LST_STRING -> LST_STRING 102 | LST_VECTOR -> LST_STRING 103 | LST_QUATERNION -> LST_STRING 104 | LST_LIST -> LST_STRING 105 | 106 | LST_VECTOR -> LST_VECTOR 107 | 108 | LST_QUATERNION -> LST_QUATERNION 109 | 110 | LST_FLOATINGPOINT -> LST_LIST 111 | LST_INTEGER -> LST_LIST 112 | LST_STRING -> LST_LIST 113 | LST_VECTOR -> LST_LIST 114 | LST_QUATERNION -> LST_LIST 115 | LST_LIST -> LST_LIST 116 | */ 117 | 118 | #endif 119 | -------------------------------------------------------------------------------- /lscript_error.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lscript_error.cpp 3 | * @brief error reporting class and strings 4 | * 5 | * $LicenseInfo:firstyear=2002&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #include "linden_common.h" 28 | 29 | #include "lscript_error.h" 30 | 31 | S32 gColumn = 0; 32 | S32 gLine = 0; 33 | S32 gInternalColumn = 0; 34 | S32 gInternalLine = 0; 35 | 36 | LLScriptGenerateErrorText gErrorToText; 37 | 38 | void LLScriptFilePosition::fdotabs(LLFILE *fp, S32 tabs, S32 tabsize) 39 | { 40 | S32 i; 41 | for (i = 0; i < tabs * tabsize; i++) 42 | { 43 | fprintf(fp, " "); 44 | } 45 | } 46 | 47 | const char* gWarningText[LSWARN_EOF] = /*Flawfinder: ignore*/ 48 | { 49 | "INVALID", 50 | "Dead code found beyond return statement" 51 | }; 52 | 53 | const char* gErrorText[LSERROR_EOF] = /*Flawfinder: ignore*/ 54 | { 55 | "INVALID", 56 | "Syntax error", 57 | "Not all code paths return a value", 58 | "Function returns a value but return statement doesn't", 59 | "Return statement type doesn't match function return type", 60 | "Global functions can't change state", 61 | "Name previously declared within scope", 62 | "Name not defined within scope", 63 | "Type mismatch", 64 | "Expression must act on LValue", 65 | "Byte code assembly failed -- out of memory", 66 | "Function call mismatches type or number of arguments", 67 | "Use of vector or quaternion method on incorrect type", 68 | "Lists can't be included in lists", 69 | "Unitialized variables can't be included in lists", 70 | "Declaration requires a new scope -- use { and }", 71 | "CIL assembler failed", 72 | "Bytecode transformer failed", 73 | "Bytecode verification failed" 74 | }; 75 | 76 | void LLScriptGenerateErrorText::writeWarning(LLFILE *fp, LLScriptFilePosition *pos, LSCRIPTWarnings warning) 77 | { 78 | fprintf(stderr, "(%d, %d) : WARNING : %s\n", pos->mLineNumber, pos->mColumnNumber, gWarningText[warning]); 79 | mTotalWarnings++; 80 | } 81 | 82 | void LLScriptGenerateErrorText::writeWarning(LLFILE *fp, S32 line, S32 col, LSCRIPTWarnings warning) 83 | { 84 | fprintf(stderr, "(%d, %d) : WARNING : %s\n", line, col, gWarningText[warning]); 85 | mTotalWarnings++; 86 | } 87 | 88 | void LLScriptGenerateErrorText::writeError(LLFILE *fp, LLScriptFilePosition *pos, LSCRIPTErrors error) 89 | { 90 | fprintf(stderr, "(%d, %d) : ERROR : %s\n", pos->mLineNumber, pos->mColumnNumber, gErrorText[error]); 91 | mTotalErrors++; 92 | } 93 | 94 | void LLScriptGenerateErrorText::writeError(LLFILE *fp, S32 line, S32 col, LSCRIPTErrors error) 95 | { 96 | fprintf(stderr, "(%d, %d) : ERROR : %s\n", line, col, gErrorText[error]); 97 | mTotalErrors++; 98 | } 99 | 100 | std::string getLScriptErrorString(LSCRIPTErrors error) 101 | { 102 | return gErrorText[error]; 103 | } 104 | -------------------------------------------------------------------------------- /indralex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # indralex.py - This is a LSL2dfg.py output module generating constants for the indra.l viewer file. 4 | # 5 | # (C) Copyright 2017 Sei Lisa. 6 | # Sei Lisa is the author's username in the Second Life online virtual world. 7 | # 8 | # This file is part of LSL2 Derived Files Generator. 9 | # 10 | # LSL2 Derived Files Generator is free software: you can redistribute it 11 | # and/or modify it under the terms of the GNU Lesser General Public License 12 | # as published by the Free Software Foundation, either version 3 of the 13 | # License, or (at your option) any later version. 14 | # 15 | # LSL2 Derived Files Generator is distributed in the hope that it will be 16 | # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU Lesser General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU Lesser General Public License 21 | # along with LSL2 Derived Files Generator. If not, see 22 | # . 23 | # 24 | # Second Life is a trademark of Linden Research, Inc. 25 | 26 | 27 | # Input file should contain lines like: 28 | # <<< XXX KEYWORDS version >>> to insert the version comment 29 | # <<< XXX KEYWORDS integer_constants >>> to insert the integer constants 30 | # <<< XXX KEYWORDS string_constants >>> to insert the string constants 31 | # <<< XXX KEYWORDS fp_constants >>> to insert the float constants 32 | # 33 | # (XXX is the tag parameter, default is empty) 34 | 35 | 36 | import sys 37 | 38 | def output(document, defaultdescs, databaseversion, infilename, outfilename, lang, tag): 39 | 40 | version = "0.0.20140602000" 41 | 42 | iconstants = [] 43 | sconstants = [] 44 | fconstants = [] 45 | 46 | for element in document: 47 | if element["cat"] == "constant": 48 | if element["type"] == "integer" and element["name"] not in ('TRUE','FALSE'): 49 | iconstants.append(element) 50 | elif element["type"] == "string": 51 | sconstants.append(element) 52 | elif element["type"] == "float": 53 | fconstants.append(element) 54 | 55 | if infilename is not None: 56 | inf = open(infilename, "rb") 57 | else: 58 | inf = sys.stdin 59 | 60 | try: 61 | inputlines = inf.readlines() 62 | 63 | finally: 64 | if infilename is not None: 65 | inf.close() 66 | 67 | if outfilename is not None: 68 | outf = open(outfilename, "wb") 69 | else: 70 | outf = sys.stdout 71 | 72 | try: 73 | 74 | for line in inputlines: 75 | if line.startswith(("<<< %s KEYWORDS version >>>" % tag).encode('utf8')): 76 | outf.write((" /* Generated by LSL2 Derived Files Generator. Database version: %s; output module version: %s */\n" 77 | % (databaseversion, version)).encode('utf8')) 78 | 79 | elif line.startswith(("<<< %s KEYWORDS integer_constants >>>" % tag).encode('utf8')): 80 | for element in iconstants: 81 | outf.write(('"%s" { count(); yylval.ival = %s; return(INTEGER_CONSTANT); }\n' % (element['name'], element['value'])).encode('utf8')) 82 | 83 | elif line.startswith(("<<< %s KEYWORDS fp_constants >>>" % tag).encode('utf8')): 84 | for element in fconstants: 85 | outf.write(('"%s" { count(); yylval.fval = %s; return(FP_CONSTANT); }\n' % (element['name'], element['value'])).encode('utf8')) 86 | 87 | elif line.startswith(("<<< %s KEYWORDS string_constants >>>" % tag).encode('utf8')): 88 | for element in sconstants: 89 | try: 90 | val = element['value'].encode('utf8').encode('string-escape') 91 | except: 92 | # Python 3 93 | val = element['value'].encode('utf8') 94 | val = val.replace(b'\\', b'\\\\').replace(b'\n', b'\\n').replace(b'"', b'\\"') 95 | for c in range(32): 96 | val = val.replace(chr(c).encode('latin1'), b'\\x'+hex(c)[2:].zfill(2).encode('utf8')) 97 | for c in range(129): 98 | val = val.replace(chr(c+127).encode('latin1'), b'\\x'+hex(c+127)[2:].zfill(2).encode('utf8')) 99 | #val = val.decode('utf8') 100 | 101 | outf.write(('"%s" { yylval.sval = new char[%d]; strcpy(yylval.sval, "%s"); return(STRING_CONSTANT); }\n' % (element['name'], len(element['value'].encode('utf8'))+1, val.decode('utf8'))).encode('utf8')) 102 | 103 | else: 104 | outf.write(line) 105 | 106 | finally: 107 | if outfilename is not None: 108 | outf.close() 109 | 110 | 111 | pass 112 | -------------------------------------------------------------------------------- /lscript_error.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lscript_error.h 3 | * @brief error reporting class and strings 4 | * 5 | * $LicenseInfo:firstyear=2002&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #ifndef LL_LSCRIPT_ERROR_H 28 | #define LL_LSCRIPT_ERROR_H 29 | 30 | #include "lscript_scope.h" 31 | 32 | typedef enum e_lscript_compile_pass 33 | { 34 | LSCP_INVALID, 35 | LSCP_PRETTY_PRINT, 36 | LSCP_PRUNE, 37 | LSCP_SCOPE_PASS1, 38 | LSCP_SCOPE_PASS2, 39 | LSCP_TYPE, 40 | LSCP_RESOURCE, 41 | LSCP_EMIT_ASSEMBLY, 42 | LSCP_EMIT_BYTE_CODE, 43 | LSCP_DETERMINE_HANDLERS, 44 | LSCP_LIST_BUILD_SIMPLE, 45 | LSCP_TO_STACK, 46 | LSCP_BUILD_FUNCTION_ARGS, 47 | LSCP_EMIT_CIL_ASSEMBLY, 48 | LSCP_EOF 49 | } LSCRIPTCompilePass; 50 | 51 | typedef enum e_lscript_prune_type 52 | { 53 | LSPRUNE_INVALID, 54 | LSPRUNE_GLOBAL_VOIDS, 55 | LSPRUNE_GLOBAL_NON_VOIDS, 56 | LSPRUNE_EVENTS, 57 | LSPRUNE_DEAD_CODE, 58 | LSPRUNE_EOF 59 | } LSCRIPTPruneType; 60 | 61 | extern S32 gColumn; 62 | extern S32 gLine; 63 | extern S32 gInternalColumn; 64 | extern S32 gInternalLine; 65 | 66 | 67 | // used to describe where in the file this piece is 68 | class LLScriptByteCodeChunk; 69 | 70 | class LLScriptLibData; 71 | 72 | class LLScriptFilePosition 73 | { 74 | public: 75 | LLScriptFilePosition(S32 line, S32 col) 76 | : mLineNumber(line), mColumnNumber(col), mByteOffset(0), mByteSize(0) 77 | { 78 | } 79 | 80 | virtual ~LLScriptFilePosition() {} 81 | 82 | virtual void recurse(LLFILE *fp, S32 tabs, S32 tabsize, 83 | LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, 84 | LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, 85 | LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata) = 0; 86 | virtual S32 getSize() = 0; 87 | 88 | void fdotabs(LLFILE *fp, S32 tabs, S32 tabsize); 89 | 90 | S32 mLineNumber; 91 | S32 mColumnNumber; 92 | 93 | S32 mByteOffset; 94 | S32 mByteSize; 95 | }; 96 | 97 | typedef enum e_lscript_warnings 98 | { 99 | LSWARN_INVALID, 100 | LSWARN_DEAD_CODE, 101 | LSWARN_EOF 102 | } LSCRIPTWarnings; 103 | 104 | typedef enum e_lscript_errors 105 | { 106 | LSERROR_INVALID, 107 | LSERROR_SYNTAX_ERROR, 108 | LSERROR_NO_RETURN, 109 | LSERROR_INVALID_VOID_RETURN, 110 | LSERROR_INVALID_RETURN, 111 | LSERROR_STATE_CHANGE_IN_GLOBAL, 112 | LSERROR_DUPLICATE_NAME, 113 | LSERROR_UNDEFINED_NAME, 114 | LSERROR_TYPE_MISMATCH, 115 | LSERROR_EXPRESSION_ON_LVALUE, 116 | LSERROR_ASSEMBLE_OUT_OF_MEMORY, 117 | LSERROR_FUNCTION_TYPE_ERROR, 118 | LSERROR_VECTOR_METHOD_ERROR, 119 | LSERROR_NO_LISTS_IN_LISTS, 120 | LSERROR_NO_UNITIALIZED_VARIABLES_IN_LISTS, 121 | LSERROR_NEED_NEW_SCOPE, 122 | LSERROR_CIL_ASSEMBLER_FAILED = 16, // Mono build error. 123 | LSERROR_BYTECODE_TRANSFORM_FAILED = 17, // Mono build error. 124 | LSERROR_BYTECODE_VERIFICATION_FAILED, // Mono build error. 125 | LSERROR_EOF 126 | } LSCRIPTErrors; 127 | 128 | class LLScriptGenerateErrorText 129 | { 130 | public: 131 | LLScriptGenerateErrorText() { init(); } 132 | ~LLScriptGenerateErrorText() {} 133 | 134 | void init() { mTotalErrors = 0; mTotalWarnings = 0; } 135 | 136 | void writeWarning(LLFILE *fp, LLScriptFilePosition *pos, LSCRIPTWarnings warning); 137 | void writeWarning(LLFILE *fp, S32 line, S32 col, LSCRIPTWarnings warning); 138 | void writeError(LLFILE *fp, LLScriptFilePosition *pos, LSCRIPTErrors error); 139 | void writeError(LLFILE *fp, S32 line, S32 col, LSCRIPTErrors error); 140 | 141 | BOOL getErrors() { return mTotalErrors; } 142 | BOOL getWarnings() { return mTotalWarnings; } 143 | 144 | S32 mTotalErrors; 145 | S32 mTotalWarnings; 146 | }; 147 | 148 | std::string getLScriptErrorString(LSCRIPTErrors error); 149 | 150 | extern LLScriptGenerateErrorText gErrorToText; 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /llcommon/llstringtable.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file llstringtable.h 3 | * @brief The LLStringTable class provides a _fast_ method for finding 4 | * unique copies of strings. 5 | * 6 | * $LicenseInfo:firstyear=2001&license=viewerlgpl$ 7 | * Second Life Viewer Source Code 8 | * Copyright (C) 2010, Linden Research, Inc. 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; 13 | * version 2.1 of the License only. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public 21 | * License along with this library; if not, write to the Free Software 22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 | * 24 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 25 | * $/LicenseInfo$ 26 | */ 27 | 28 | #ifndef LL_STRING_TABLE_H 29 | #define LL_STRING_TABLE_H 30 | 31 | #include "lldefs.h" 32 | #include "llformat.h" 33 | #include "llstl.h" 34 | #include 35 | #include 36 | 37 | #if LL_WINDOWS 38 | # if (_MSC_VER >= 1300 && _MSC_VER < 1400) 39 | # define STRING_TABLE_HASH_MAP 1 40 | # endif 41 | #else 42 | //# define STRING_TABLE_HASH_MAP 1 43 | #endif 44 | 45 | #if STRING_TABLE_HASH_MAP 46 | # if LL_WINDOWS 47 | # include 48 | # else 49 | # include 50 | # endif 51 | #endif 52 | 53 | const U32 MAX_STRINGS_LENGTH = 256; 54 | 55 | class LL_COMMON_API LLStringTableEntry 56 | { 57 | public: 58 | LLStringTableEntry(const char *str); 59 | ~LLStringTableEntry(); 60 | 61 | void incCount() { mCount++; } 62 | BOOL decCount() { return --mCount; } 63 | 64 | char *mString; 65 | S32 mCount; 66 | }; 67 | 68 | class LL_COMMON_API LLStringTable 69 | { 70 | public: 71 | LLStringTable(int tablesize); 72 | ~LLStringTable(); 73 | 74 | char *checkString(const char *str); 75 | char *checkString(const std::string& str); 76 | LLStringTableEntry *checkStringEntry(const char *str); 77 | LLStringTableEntry *checkStringEntry(const std::string& str); 78 | 79 | char *addString(const char *str); 80 | char *addString(const std::string& str); 81 | LLStringTableEntry *addStringEntry(const char *str); 82 | LLStringTableEntry *addStringEntry(const std::string& str); 83 | void removeString(const char *str); 84 | 85 | S32 mMaxEntries; 86 | S32 mUniqueEntries; 87 | 88 | #if STRING_TABLE_HASH_MAP 89 | #if LL_WINDOWS 90 | typedef std::hash_multimap string_hash_t; 91 | #else 92 | typedef __gnu_cxx::hash_multimap string_hash_t; 93 | #endif 94 | string_hash_t mStringHash; 95 | #else 96 | typedef std::list string_list_t; 97 | typedef string_list_t * string_list_ptr_t; 98 | string_list_ptr_t *mStringList; 99 | #endif 100 | }; 101 | 102 | extern LL_COMMON_API LLStringTable gStringTable; 103 | 104 | //============================================================================ 105 | 106 | // This class is designed to be used locally, 107 | // e.g. as a member of an LLXmlTree 108 | // Strings can be inserted only, then quickly looked up 109 | 110 | typedef const std::string* LLStdStringHandle; 111 | 112 | class LL_COMMON_API LLStdStringTable 113 | { 114 | public: 115 | LLStdStringTable(S32 tablesize = 0) 116 | { 117 | if (tablesize == 0) 118 | { 119 | tablesize = 256; // default 120 | } 121 | // Make sure tablesize is power of 2 122 | for (S32 i = 31; i>0; i--) 123 | { 124 | if (tablesize & (1<= (3<<(i-1))) 127 | tablesize = (1<<(i+1)); 128 | else 129 | tablesize = (1< > string_set_t; 213 | string_set_t* mStringList; // [mTableSize] 214 | }; 215 | 216 | 217 | #endif 218 | -------------------------------------------------------------------------------- /llcommon/llmap.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file llmap.h 3 | * @brief LLMap class header file 4 | * 5 | * $LicenseInfo:firstyear=2001&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #ifndef LL_LLMAP_H 28 | #define LL_LLMAP_H 29 | 30 | // llmap uses the fast stl library code in a manner consistant with LLSkipMap, et. al. 31 | 32 | template class LLMap 33 | { 34 | private: 35 | typedef typename std::map stl_map_t; 36 | typedef typename stl_map_t::iterator stl_iter_t; 37 | typedef typename stl_map_t::value_type stl_value_t; 38 | 39 | stl_map_t mStlMap; 40 | stl_iter_t mCurIter; // *iterator = pair 41 | MAPPED_TYPE dummy_data; 42 | INDEX_TYPE dummy_index; 43 | 44 | public: 45 | LLMap() : mStlMap() 46 | { 47 | memset((void*)(&dummy_data), 0x0, sizeof(MAPPED_TYPE)); 48 | memset((void*)(&dummy_index), 0x0, sizeof(INDEX_TYPE)); 49 | mCurIter = mStlMap.begin(); 50 | } 51 | ~LLMap() 52 | { 53 | mStlMap.clear(); 54 | } 55 | 56 | // use these functions to itterate through a list 57 | void resetMap() 58 | { 59 | mCurIter = mStlMap.begin(); 60 | } 61 | 62 | // get the current data and bump mCurrentp 63 | // This is kind of screwy since it returns a reference; 64 | // We have to have a dummy value for when we reach the end 65 | // or in case we have an empty list. Presumably, this value 66 | // will initialize to some NULL value that will end the iterator. 67 | // We really shouldn't be using getNextData() or getNextKey() anyway... 68 | MAPPED_TYPE &getNextData() 69 | { 70 | if (mCurIter == mStlMap.end()) 71 | { 72 | return dummy_data; 73 | } 74 | else 75 | { 76 | return (*mCurIter++).second; 77 | } 78 | } 79 | 80 | const INDEX_TYPE &getNextKey() 81 | { 82 | if (mCurIter == mStlMap.end()) 83 | { 84 | return dummy_index; 85 | } 86 | else 87 | { 88 | return (*mCurIter++).first; 89 | } 90 | } 91 | 92 | MAPPED_TYPE &getFirstData() 93 | { 94 | resetMap(); 95 | return getNextData(); 96 | } 97 | 98 | const INDEX_TYPE &getFirstKey() 99 | { 100 | resetMap(); 101 | return getNextKey(); 102 | } 103 | 104 | S32 getLength() 105 | { 106 | return mStlMap.size(); 107 | } 108 | 109 | void addData(const INDEX_TYPE &index, MAPPED_TYPE pointed_to) 110 | { 111 | mStlMap.insert(stl_value_t(index, pointed_to)); 112 | } 113 | 114 | void addData(const INDEX_TYPE &index) 115 | { 116 | mStlMap.insert(stl_value_t(index, dummy_data)); 117 | } 118 | 119 | // if index doesn't exist, then insert a new node and return it 120 | MAPPED_TYPE &getData(const INDEX_TYPE &index) 121 | { 122 | std::pair res; 123 | res = mStlMap.insert(stl_value_t(index, dummy_data)); 124 | return res.first->second; 125 | } 126 | 127 | // if index doesn't exist, then insert a new node, return it, and set b_new_entry to true 128 | MAPPED_TYPE &getData(const INDEX_TYPE &index, BOOL &b_new_entry) 129 | { 130 | std::pair res; 131 | res = mStlMap.insert(stl_value_t(index, dummy_data)); 132 | b_new_entry = res.second; 133 | return res.first->second; 134 | } 135 | 136 | // If there, returns the data. 137 | // If not, returns NULL. 138 | // Never adds entries to the map. 139 | MAPPED_TYPE getIfThere(const INDEX_TYPE &index) 140 | { 141 | stl_iter_t iter; 142 | iter = mStlMap.find(index); 143 | if (iter == mStlMap.end()) 144 | { 145 | return (MAPPED_TYPE)0; 146 | } 147 | else 148 | { 149 | return (*iter).second; 150 | } 151 | } 152 | 153 | 154 | // if index doesn't exist, then make a new node and return it 155 | MAPPED_TYPE &operator[](const INDEX_TYPE &index) 156 | { 157 | return getData(index); 158 | } 159 | 160 | // do a reverse look-up, return NULL if failed 161 | INDEX_TYPE reverseLookup(const MAPPED_TYPE data) 162 | { 163 | stl_iter_t iter; 164 | stl_iter_t end_iter; 165 | iter = mStlMap.begin(); 166 | end_iter = mStlMap.end(); 167 | while (iter != end_iter) 168 | { 169 | if ((*iter).second == data) 170 | return (*iter).first; 171 | iter++; 172 | } 173 | return (INDEX_TYPE)0; 174 | } 175 | 176 | BOOL removeData(const INDEX_TYPE &index) 177 | { 178 | mCurIter = mStlMap.find(index); 179 | if (mCurIter == mStlMap.end()) 180 | { 181 | return FALSE; 182 | } 183 | else 184 | { 185 | stl_iter_t iter = mCurIter++; // incrament mCurIter to the next element 186 | mStlMap.erase(iter); 187 | return TRUE; 188 | } 189 | } 190 | 191 | // does this index exist? 192 | BOOL checkData(const INDEX_TYPE &index) 193 | { 194 | stl_iter_t iter; 195 | iter = mStlMap.find(index); 196 | if (iter == mStlMap.end()) 197 | { 198 | return FALSE; 199 | } 200 | else 201 | { 202 | mCurIter = iter; 203 | return TRUE; 204 | } 205 | } 206 | 207 | BOOL deleteData(const INDEX_TYPE &index) 208 | { 209 | mCurIter = mStlMap.find(index); 210 | if (mCurIter == mStlMap.end()) 211 | { 212 | return FALSE; 213 | } 214 | else 215 | { 216 | stl_iter_t iter = mCurIter++; // incrament mCurIter to the next element 217 | delete (*iter).second; 218 | mStlMap.erase(iter); 219 | return TRUE; 220 | } 221 | } 222 | 223 | void deleteAllData() 224 | { 225 | stl_iter_t iter; 226 | stl_iter_t end_iter; 227 | iter = mStlMap.begin(); 228 | end_iter = mStlMap.end(); 229 | while (iter != end_iter) 230 | { 231 | delete (*iter).second; 232 | iter++; 233 | } 234 | mStlMap.clear(); 235 | mCurIter = mStlMap.end(); 236 | } 237 | 238 | void removeAllData() 239 | { 240 | mStlMap.clear(); 241 | } 242 | }; 243 | 244 | 245 | #endif 246 | -------------------------------------------------------------------------------- /lscript_library/lscript_library.cpp.in: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lscript_library.cpp 3 | * @brief external library interface 4 | * 5 | * $LicenseInfo:firstyear=2002&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | 28 | // ## ## ### ######## ## ## #### ## ## ###### #### #### 29 | // ## ## ## ## ## ## ## ### ## ## ### ## ## ## #### #### 30 | // ## ## ## ## ## ## ## #### ## ## #### ## ## #### #### 31 | // ## ## ## ## ## ######## ## ## ## ## ## ## ## ## #### ## ## 32 | // ## ## ## ######### ## ## ## #### ## ## #### ## ## 33 | // ## ## ## ## ## ## ## ## ### ## ## ### ## ## #### #### 34 | // ### ### ## ## ## ## ## ## #### ## ## ###### #### #### 35 | // 36 | // When adding functions, they MUST be appended to the end of 37 | // the init() method. The init() associates the name with a number, 38 | // which is then serialized into the bytecode. Inserting a new 39 | // function in the middle will lead to many sim crashes. Phoenix 2006-04-10. 40 | 41 | #include "linden_common.h" 42 | 43 | #include "lscript_library.h" 44 | 45 | LLScriptLibrary::LLScriptLibrary() 46 | { 47 | init(); 48 | } 49 | 50 | LLScriptLibrary::~LLScriptLibrary() 51 | { 52 | } 53 | 54 | void dummy_func(LLScriptLibData *retval, LLScriptLibData *args, const LLUUID &id) 55 | { 56 | } 57 | 58 | void LLScriptLibrary::init() 59 | { 60 | // IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST. 61 | // Otherwise the bytecode numbers for each call will be wrong, and all 62 | // existing scripts will crash. 63 | 64 | // energy, sleep, dummy_func, name, return type, parameters, gods-only 65 | <<< LSL KEYWORDS >>> 66 | 67 | // energy, sleep, dummy_func, name, return type, parameters, help text, gods-only 68 | 69 | // IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST. 70 | // Otherwise the bytecode numbers for each call will be wrong, and all 71 | // existing scripts will crash. 72 | 73 | // According to Kelly Linden we don't need to obey the function ID order in the viewer! 74 | // According to Kelly Linden we don't need to obey the function ID order in the viewer! 75 | 76 | // Opensim/Aurora scripting functions - Please add Second Life LSL functions above this line! 77 | #ifdef OPENSIM 78 | <<< OSSL KEYWORDS >>> 79 | <<< AA KEYWORDS >>> 80 | #endif // OPENSIM 81 | // Opensim/Aurora scripting functions 82 | } 83 | 84 | LLScriptLibraryFunction::LLScriptLibraryFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), const char *name, const char *ret_type, const char *args, BOOL god_only) 85 | : mEnergyUse(eu), mSleepTime(st), mExecFunc(exec_func), mName(name), mReturnType(ret_type), mArgs(args), mGodOnly(god_only) 86 | { 87 | } 88 | 89 | LLScriptLibraryFunction::~LLScriptLibraryFunction() 90 | { 91 | } 92 | 93 | void LLScriptLibrary::addFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), const char *name, const char *ret_type, const char *args, BOOL god_only) 94 | { 95 | LLScriptLibraryFunction func(eu, st, exec_func, name, ret_type, args, god_only); 96 | mFunctions.push_back(func); 97 | } 98 | 99 | void LLScriptLibrary::assignExec(const char *name, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &)) 100 | { 101 | #if 0 102 | for (std::vector::iterator i = mFunctions.begin(); 103 | i != mFunctions.end(); ++i) 104 | { 105 | if (!strcmp(name, i->mName)) 106 | { 107 | i->mExecFunc = exec_func; 108 | return; 109 | } 110 | } 111 | 112 | llerrs << "Unknown LSL function in assignExec: " << name << llendl; 113 | #endif 114 | } 115 | 116 | #if 0 117 | void LLScriptLibData::print(std::ostream &s, BOOL b_prepend_comma) 118 | { 119 | char tmp[1024]; /*Flawfinder: ignore*/ 120 | if (b_prepend_comma) 121 | { 122 | s << ", "; 123 | } 124 | switch (mType) 125 | { 126 | case LST_INTEGER: 127 | s << mInteger; 128 | break; 129 | case LST_FLOATINGPOINT: 130 | snprintf(tmp, 1024, "%f", mFP); /* Flawfinder: ignore */ 131 | s << tmp; 132 | break; 133 | case LST_KEY: 134 | s << mKey; 135 | break; 136 | case LST_STRING: 137 | s << mString; 138 | break; 139 | case LST_VECTOR: 140 | snprintf(tmp, 1024, "<%f, %f, %f>", mVec.mV[VX], /* Flawfinder: ignore */ 141 | mVec.mV[VY], mVec.mV[VZ]); 142 | s << tmp; 143 | break; 144 | case LST_QUATERNION: 145 | snprintf(tmp, 1024, "<%f, %f, %f, %f>", mQuat.mQ[VX], mQuat.mQ[VY], /* Flawfinder: ignore */ 146 | mQuat.mQ[VZ], mQuat.mQ[VS]); 147 | s << tmp; 148 | break; 149 | default: 150 | break; 151 | } 152 | } 153 | 154 | void LLScriptLibData::print_separator(std::ostream& ostr, BOOL b_prepend_sep, char* sep) 155 | { 156 | if (b_prepend_sep) 157 | { 158 | ostr << sep; 159 | } 160 | //print(ostr, FALSE); 161 | { 162 | char tmp[1024]; /* Flawfinder: ignore */ 163 | switch (mType) 164 | { 165 | case LST_INTEGER: 166 | ostr << mInteger; 167 | break; 168 | case LST_FLOATINGPOINT: 169 | snprintf(tmp, 1024, "%f", mFP); /* Flawfinder: ignore */ 170 | ostr << tmp; 171 | break; 172 | case LST_KEY: 173 | ostr << mKey; 174 | break; 175 | case LST_STRING: 176 | ostr << mString; 177 | break; 178 | case LST_VECTOR: 179 | snprintf(tmp, 1024, "<%f, %f, %f>", mVec.mV[VX], /* Flawfinder: ignore */ 180 | mVec.mV[VY], mVec.mV[VZ]); 181 | ostr << tmp; 182 | break; 183 | case LST_QUATERNION: 184 | snprintf(tmp, 1024, "<%f, %f, %f, %f>", mQuat.mQ[VX], mQuat.mQ[VY], /* Flawfinder: ignore */ 185 | mQuat.mQ[VZ], mQuat.mQ[VS]); 186 | ostr << tmp; 187 | break; 188 | default: 189 | break; 190 | } 191 | } 192 | } 193 | #endif 194 | 195 | 196 | LLScriptLibrary gScriptLibrary; 197 | -------------------------------------------------------------------------------- /llcommon/lldefs.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lldefs.h 3 | * @brief Various generic constant definitions. 4 | * 5 | * $LicenseInfo:firstyear=2001&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #ifndef LL_LLDEFS_H 28 | #define LL_LLDEFS_H 29 | 30 | #include "stdtypes.h" 31 | 32 | // Often used array indices 33 | const U32 VX = 0; 34 | const U32 VY = 1; 35 | const U32 VZ = 2; 36 | const U32 VW = 3; 37 | const U32 VS = 3; 38 | 39 | const U32 VRED = 0; 40 | const U32 VGREEN = 1; 41 | const U32 VBLUE = 2; 42 | const U32 VALPHA = 3; 43 | 44 | const U32 INVALID_DIRECTION = 0xFFFFFFFF; 45 | const U32 EAST = 0; 46 | const U32 NORTH = 1; 47 | const U32 WEST = 2; 48 | const U32 SOUTH = 3; 49 | 50 | const U32 NORTHEAST = 4; 51 | const U32 NORTHWEST = 5; 52 | const U32 SOUTHWEST = 6; 53 | const U32 SOUTHEAST = 7; 54 | const U32 MIDDLE = 8; 55 | 56 | const U8 EAST_MASK = 0x1< X 113 | // |/| | -4- |/| | 114 | // | +----|---------|---+ 115 | // | / / | / 116 | // | / -6- | / 117 | // |/ / |/ 118 | // +------------------+ 119 | const U32 NO_SIDE = 0; 120 | const U32 FRONT_SIDE = 1; 121 | const U32 BACK_SIDE = 2; 122 | const U32 LEFT_SIDE = 3; 123 | const U32 RIGHT_SIDE = 4; 124 | const U32 TOP_SIDE = 5; 125 | const U32 BOTTOM_SIDE = 6; 126 | 127 | const U8 LL_SOUND_FLAG_NONE = 0x0; 128 | const U8 LL_SOUND_FLAG_LOOP = 1<<0; 129 | const U8 LL_SOUND_FLAG_SYNC_MASTER = 1<<1; 130 | const U8 LL_SOUND_FLAG_SYNC_SLAVE = 1<<2; 131 | const U8 LL_SOUND_FLAG_SYNC_PENDING = 1<<3; 132 | const U8 LL_SOUND_FLAG_QUEUE = 1<<4; 133 | const U8 LL_SOUND_FLAG_STOP = 1<<5; 134 | const U8 LL_SOUND_FLAG_SYNC_MASK = LL_SOUND_FLAG_SYNC_MASTER | LL_SOUND_FLAG_SYNC_SLAVE | LL_SOUND_FLAG_SYNC_PENDING; 135 | 136 | // 137 | // *NOTE: These values may be used as hard-coded numbers in scanf() variants. 138 | // 139 | // -------------- 140 | // DO NOT CHANGE. 141 | // -------------- 142 | // 143 | const U32 LL_MAX_PATH = 1024; // buffer size of maximum path + filename string length 144 | 145 | // For strings we send in messages 146 | const U32 STD_STRING_BUF_SIZE = 255; // Buffer size 147 | const U32 STD_STRING_STR_LEN = 254; // Length of the string (not including \0) 148 | 149 | // *NOTE: This value is used as hard-coded numbers in scanf() variants. 150 | // DO NOT CHANGE. 151 | const U32 MAX_STRING = STD_STRING_BUF_SIZE; // Buffer size 152 | 153 | const U32 MAXADDRSTR = 17; // 123.567.901.345 = 15 chars + \0 + 1 for good luck 154 | 155 | // C++ is our friend. . . use template functions to make life easier! 156 | 157 | // specific inlines for basic types 158 | // 159 | // defined for all: 160 | // llmin(a,b) 161 | // llmax(a,b) 162 | // llclamp(a,minimum,maximum) 163 | // 164 | // defined for F32, F64: 165 | // llclampf(a) // clamps a to [0.0 .. 1.0] 166 | // 167 | // defined for U16, U32, U64, S16, S32, S64, : 168 | // llclampb(a) // clamps a to [0 .. 255] 169 | // 170 | 171 | template 172 | inline LLDATATYPE llmax(const LLDATATYPE& d1, const LLDATATYPE& d2) 173 | { 174 | return (d1 > d2) ? d1 : d2; 175 | } 176 | 177 | template 178 | inline LLDATATYPE llmax(const LLDATATYPE& d1, const LLDATATYPE& d2, const LLDATATYPE& d3) 179 | { 180 | LLDATATYPE r = llmax(d1,d2); 181 | return llmax(r, d3); 182 | } 183 | 184 | template 185 | inline LLDATATYPE llmax(const LLDATATYPE& d1, const LLDATATYPE& d2, const LLDATATYPE& d3, const LLDATATYPE& d4) 186 | { 187 | LLDATATYPE r1 = llmax(d1,d2); 188 | LLDATATYPE r2 = llmax(d3,d4); 189 | return llmax(r1, r2); 190 | } 191 | 192 | template 193 | inline LLDATATYPE llmin(const LLDATATYPE& d1, const LLDATATYPE& d2) 194 | { 195 | return (d1 < d2) ? d1 : d2; 196 | } 197 | 198 | template 199 | inline LLDATATYPE llmin(const LLDATATYPE& d1, const LLDATATYPE& d2, const LLDATATYPE& d3) 200 | { 201 | LLDATATYPE r = llmin(d1,d2); 202 | return (r < d3 ? r : d3); 203 | } 204 | 205 | template 206 | inline LLDATATYPE llmin(const LLDATATYPE& d1, const LLDATATYPE& d2, const LLDATATYPE& d3, const LLDATATYPE& d4) 207 | { 208 | LLDATATYPE r1 = llmin(d1,d2); 209 | LLDATATYPE r2 = llmin(d3,d4); 210 | return llmin(r1, r2); 211 | } 212 | 213 | template 214 | inline LLDATATYPE llclamp(const LLDATATYPE& a, const LLDATATYPE& minval, const LLDATATYPE& maxval) 215 | { 216 | if ( a < minval ) 217 | { 218 | return minval; 219 | } 220 | else if ( a > maxval ) 221 | { 222 | return maxval; 223 | } 224 | return a; 225 | } 226 | 227 | template 228 | inline LLDATATYPE llclampf(const LLDATATYPE& a) 229 | { 230 | return llmin(llmax(a, (LLDATATYPE)0), (LLDATATYPE)1); 231 | } 232 | 233 | template 234 | inline LLDATATYPE llclampb(const LLDATATYPE& a) 235 | { 236 | return llmin(llmax(a, (LLDATATYPE)0), (LLDATATYPE)255); 237 | } 238 | 239 | template 240 | inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs) 241 | { 242 | LLDATATYPE tmp = lhs; 243 | lhs = rhs; 244 | rhs = tmp; 245 | } 246 | 247 | #endif // LL_LLDEFS_H 248 | 249 | -------------------------------------------------------------------------------- /llcommon/llpreprocessor.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file llpreprocessor.h 3 | * @brief This file should be included in all Linden Lab files and 4 | * should only contain special preprocessor directives 5 | * 6 | * $LicenseInfo:firstyear=2001&license=viewerlgpl$ 7 | * Second Life Viewer Source Code 8 | * Copyright (C) 2010, Linden Research, Inc. 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; 13 | * version 2.1 of the License only. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public 21 | * License along with this library; if not, write to the Free Software 22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 | * 24 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 25 | * $/LicenseInfo$ 26 | */ 27 | 28 | #ifndef LLPREPROCESSOR_H 29 | #define LLPREPROCESSOR_H 30 | 31 | // Figure out endianness of platform 32 | #ifdef LL_LINUX 33 | #define __ENABLE_WSTRING 34 | #include 35 | #endif // LL_LINUX 36 | 37 | #if LL_SOLARIS 38 | # ifdef __sparc // Since we're talking Solaris 10 and up, only 64 bit is supported. 39 | # define LL_BIG_ENDIAN 1 40 | # define LL_SOLARIS_ALIGNED_CPU 1 // used to designate issues where SPARC alignment is addressed 41 | # define LL_SOLARIS_NON_MESA_GL 1 // The SPARC GL does not provide a MESA-based GL API 42 | # endif 43 | # include // ensure we know which end is up 44 | #endif // LL_SOLARIS 45 | 46 | #if (defined(LL_WINDOWS) || (defined(LL_LINUX) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || (defined(LL_DARWIN) && defined(__LITTLE_ENDIAN__)) || (defined(LL_SOLARIS) && defined(__i386))) 47 | #define LL_LITTLE_ENDIAN 1 48 | #else 49 | #define LL_BIG_ENDIAN 1 50 | #endif 51 | 52 | 53 | // Per-compiler switches 54 | 55 | #ifdef __GNUC__ 56 | #define LL_FORCE_INLINE inline __attribute__((always_inline)) 57 | #else 58 | #define LL_FORCE_INLINE __forceinline 59 | #endif 60 | 61 | // Mark-up expressions with branch prediction hints. Do NOT use 62 | // this with reckless abandon - it's an obfuscating micro-optimization 63 | // outside of inner loops or other places where you are OVERWHELMINGLY 64 | // sure which way an expression almost-always evaluates. 65 | #if __GNUC__ >= 3 66 | # define LL_LIKELY(EXPR) __builtin_expect (!!(EXPR), true) 67 | # define LL_UNLIKELY(EXPR) __builtin_expect (!!(EXPR), false) 68 | #else 69 | # define LL_LIKELY(EXPR) (EXPR) 70 | # define LL_UNLIKELY(EXPR) (EXPR) 71 | #endif 72 | 73 | 74 | // Figure out differences between compilers 75 | #if defined(__GNUC__) 76 | #define GCC_VERSION (__GNUC__ * 10000 \ 77 | + __GNUC_MINOR__ * 100 \ 78 | + __GNUC_PATCHLEVEL__) 79 | #ifndef LL_GNUC 80 | #define LL_GNUC 1 81 | #endif 82 | #elif defined(__MSVC_VER__) || defined(_MSC_VER) 83 | #ifndef LL_MSVC 84 | #define LL_MSVC 1 85 | #endif 86 | #if _MSC_VER < 1400 87 | #define LL_MSVC7 //Visual C++ 2003 or earlier 88 | #endif 89 | #endif 90 | 91 | // Deal with minor differences on Unixy OSes. 92 | #if LL_DARWIN || LL_LINUX 93 | // Different name, same functionality. 94 | #define stricmp strcasecmp 95 | #define strnicmp strncasecmp 96 | 97 | // Not sure why this is different, but... 98 | #ifndef MAX_PATH 99 | #define MAX_PATH PATH_MAX 100 | #endif // not MAX_PATH 101 | 102 | #endif 103 | 104 | 105 | // Static linking with apr on windows needs to be declared. 106 | #if LL_WINDOWS && !LL_COMMON_LINK_SHARED 107 | #ifndef APR_DECLARE_STATIC 108 | #define APR_DECLARE_STATIC // For APR on Windows 109 | #endif 110 | #ifndef APU_DECLARE_STATIC 111 | #define APU_DECLARE_STATIC // For APR util on Windows 112 | #endif 113 | #endif 114 | 115 | #if defined(LL_WINDOWS) 116 | #define BOOST_REGEX_NO_LIB 1 117 | #define CURL_STATICLIB 1 118 | #ifndef XML_STATIC 119 | #define XML_STATIC 120 | #endif 121 | #endif // LL_WINDOWS 122 | 123 | 124 | // Deal with VC6 problems 125 | #if LL_MSVC 126 | #pragma warning( 3 : 4701 ) // "local variable used without being initialized" Treat this as level 3, not level 4. 127 | #pragma warning( 3 : 4702 ) // "unreachable code" Treat this as level 3, not level 4. 128 | #pragma warning( 3 : 4189 ) // "local variable initialized but not referenced" Treat this as level 3, not level 4. 129 | //#pragma warning( 3 : 4018 ) // "signed/unsigned mismatch" Treat this as level 3, not level 4. 130 | #pragma warning( 3 : 4263 ) // 'function' : member function does not override any base class virtual member function 131 | #pragma warning( 3 : 4264 ) // "'virtual_function' : no override available for virtual member function from base 'class'; function is hidden" 132 | #pragma warning( 3 : 4265 ) // "class has virtual functions, but destructor is not virtual" 133 | #pragma warning( 3 : 4266 ) // 'function' : no override available for virtual member function from base 'type'; function is hidden 134 | #pragma warning (disable : 4180) // qualifier applied to function type has no meaning; ignored 135 | //#pragma warning( disable : 4284 ) // silly MS warning deep inside their include file 136 | #pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation. 137 | #pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) 138 | #pragma warning( disable : 4996 ) // warning: deprecated 139 | 140 | // Linker optimization with "extern template" generates these warnings 141 | #pragma warning( disable : 4231 ) // nonstandard extension used : 'extern' before template explicit instantiation 142 | #pragma warning( disable : 4506 ) // no definition for inline function 143 | 144 | // level 4 warnings that we need to disable: 145 | #pragma warning (disable : 4100) // unreferenced formal parameter 146 | #pragma warning (disable : 4127) // conditional expression is constant (e.g. while(1) ) 147 | #pragma warning (disable : 4244) // possible loss of data on conversions 148 | #pragma warning (disable : 4396) // the inline specifier cannot be used when a friend declaration refers to a specialization of a function template 149 | #pragma warning (disable : 4512) // assignment operator could not be generated 150 | #pragma warning (disable : 4706) // assignment within conditional (even if((x = y)) ) 151 | 152 | #pragma warning (disable : 4251) // member needs to have dll-interface to be used by clients of class 153 | #pragma warning (disable : 4275) // non dll-interface class used as base for dll-interface class 154 | #pragma warning (disable : 4018) // '<' : signed/unsigned mismatch 155 | 156 | #endif // LL_MSVC 157 | 158 | #if LL_WINDOWS 159 | #define LL_DLLEXPORT __declspec(dllexport) 160 | #define LL_DLLIMPORT __declspec(dllimport) 161 | #elif LL_LINUX 162 | #define LL_DLLEXPORT __attribute__ ((visibility("default"))) 163 | #define LL_DLLIMPORT 164 | #else 165 | #define LL_DLLEXPORT 166 | #define LL_DLLIMPORT 167 | #endif // LL_WINDOWS 168 | 169 | #if LL_COMMON_LINK_SHARED 170 | // CMake automagically defines llcommon_EXPORTS only when building llcommon 171 | // sources, and only when llcommon is a shared library (i.e. when 172 | // LL_COMMON_LINK_SHARED). We must still test LL_COMMON_LINK_SHARED because 173 | // otherwise we can't distinguish between (non-llcommon source) and (llcommon 174 | // not shared). 175 | # if defined(llcommon_EXPORTS) 176 | # define LL_COMMON_API LL_DLLEXPORT 177 | # else //llcommon_EXPORTS 178 | # define LL_COMMON_API LL_DLLIMPORT 179 | # endif //llcommon_EXPORTS 180 | #else // LL_COMMON_LINK_SHARED 181 | # define LL_COMMON_API 182 | #endif // LL_COMMON_LINK_SHARED 183 | 184 | #endif // not LL_LINDEN_PREPROCESSOR_H 185 | -------------------------------------------------------------------------------- /lscript_scope.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lscript_scope.h 3 | * @brief builds nametable and checks scope 4 | * 5 | * $LicenseInfo:firstyear=2002&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #ifndef LL_LSCRIPT_SCOPE_H 28 | #define LL_LSCRIPT_SCOPE_H 29 | 30 | #include "string_table.h" 31 | #include "llmap.h" 32 | #include "lscript_byteformat.h" 33 | 34 | typedef enum e_lscript_identifier_type 35 | { 36 | LIT_INVALID, 37 | LIT_GLOBAL, 38 | LIT_VARIABLE, 39 | LIT_FUNCTION, 40 | LIT_LABEL, 41 | LIT_STATE, 42 | LIT_HANDLER, 43 | LIT_LIBRARY_FUNCTION, 44 | LIT_EOF 45 | } LSCRIPTIdentifierType; 46 | 47 | const char LSCRIPTFunctionTypeStrings[LST_EOF] = /*Flawfinder: ignore*/ 48 | { 49 | '0', 50 | 'i', 51 | 'f', 52 | 's', 53 | 'k', 54 | 'v', 55 | 'q', 56 | 'l', 57 | '0' 58 | }; 59 | 60 | const char * const LSCRIPTListDescription[LST_EOF] = /*Flawfinder: ignore*/ 61 | { 62 | "PUSHARGB 0", 63 | "PUSHARGB 1", 64 | "PUSHARGB 2", 65 | "PUSHARGB 3", 66 | "PUSHARGB 4", 67 | "PUSHARGB 5", 68 | "PUSHARGB 6", 69 | "PUSHARGB 7", 70 | "PUSHARGB 0" 71 | }; 72 | 73 | const char * const LSCRIPTTypePush[LST_EOF] = /*Flawfinder: ignore*/ 74 | { 75 | "INVALID", 76 | "PUSHE", 77 | "PUSHE", 78 | "PUSHE", 79 | "PUSHE", 80 | "PUSHEV", 81 | "PUSHEQ", 82 | "PUSHE", 83 | "undefined" 84 | }; 85 | 86 | const char * const LSCRIPTTypeReturn[LST_EOF] = /*Flawfinder: ignore*/ 87 | { 88 | "INVALID", 89 | "LOADP -12", 90 | "LOADP -12", 91 | "STORES -12\nPOP", 92 | "STORES -12\nPOP", 93 | "LOADVP -20", 94 | "LOADQP -24", 95 | "LOADLP -12", 96 | "undefined" 97 | }; 98 | 99 | const char * const LSCRIPTTypePop[LST_EOF] = /*Flawfinder: ignore*/ 100 | { 101 | "INVALID", 102 | "POP", 103 | "POP", 104 | "POPS", 105 | "POPS", 106 | "POPV", 107 | "POPQ", 108 | "POPL", 109 | "undefined" 110 | }; 111 | 112 | const char * const LSCRIPTTypeDuplicate[LST_EOF] = /*Flawfinder: ignore*/ 113 | { 114 | "INVALID", 115 | "DUP", 116 | "DUP", 117 | "DUPS", 118 | "DUPS", 119 | "DUPV", 120 | "DUPQ", 121 | "DUPL", 122 | "undefined" 123 | }; 124 | 125 | const char * const LSCRIPTTypeLocalStore[LST_EOF] = /*Flawfinder: ignore*/ 126 | { 127 | "INVALID", 128 | "STORE ", 129 | "STORE ", 130 | "STORES ", 131 | "STORES ", 132 | "STOREV ", 133 | "STOREQ ", 134 | "STOREL ", 135 | "undefined" 136 | }; 137 | 138 | const char * const LSCRIPTTypeLocalDeclaration[LST_EOF] = /*Flawfinder: ignore*/ 139 | { 140 | "INVALID", 141 | "STOREP ", 142 | "STOREP ", 143 | "STORESP ", 144 | "STORESP ", 145 | "STOREVP ", 146 | "STOREQP ", 147 | "STORELP ", 148 | "undefined" 149 | }; 150 | 151 | const char * const LSCRIPTTypeGlobalStore[LST_EOF] = /*Flawfinder: ignore*/ 152 | { 153 | "INVALID", 154 | "STOREG ", 155 | "STOREG ", 156 | "STORESG ", 157 | "STORESG ", 158 | "STOREGV ", 159 | "STOREGQ ", 160 | "STORELG ", 161 | "undefined" 162 | }; 163 | 164 | const char * const LSCRIPTTypeLocalPush[LST_EOF] = /*Flawfinder: ignore*/ 165 | { 166 | "INVALID", 167 | "PUSH ", 168 | "PUSH ", 169 | "PUSHS ", 170 | "PUSHS ", 171 | "PUSHV ", 172 | "PUSHQ ", 173 | "PUSHL ", 174 | "undefined" 175 | }; 176 | 177 | const char * const LSCRIPTTypeLocalPush1[LST_EOF] = /*Flawfinder: ignore*/ 178 | { 179 | "INVALID", 180 | "PUSHARGI 1", 181 | "PUSHARGF 1", 182 | "undefined", 183 | "undefined", 184 | "undefined", 185 | "undefined", 186 | "undefined", 187 | "undefined" 188 | }; 189 | 190 | const char * const LSCRIPTTypeGlobalPush[LST_EOF] = /*Flawfinder: ignore*/ 191 | { 192 | "INVALID", 193 | "PUSHG ", 194 | "PUSHG ", 195 | "PUSHGS ", 196 | "PUSHGS ", 197 | "PUSHGV ", 198 | "PUSHGQ ", 199 | "PUSHGL ", 200 | "undefined" 201 | }; 202 | 203 | class LLScriptSimpleAssignable; 204 | 205 | class LLScriptArgString 206 | { 207 | public: 208 | LLScriptArgString() : mString(NULL) {} 209 | ~LLScriptArgString() { delete [] mString; } 210 | 211 | LSCRIPTType getType(S32 count) 212 | { 213 | if (!mString) 214 | return LST_NULL; 215 | S32 length = (S32)strlen(mString); /*Flawfinder: ignore*/ 216 | if (count >= length) 217 | { 218 | return LST_NULL; 219 | } 220 | switch(mString[count]) 221 | { 222 | case 'i': 223 | return LST_INTEGER; 224 | case 'f': 225 | return LST_FLOATINGPOINT; 226 | case 's': 227 | return LST_STRING; 228 | case 'k': 229 | return LST_KEY; 230 | case 'v': 231 | return LST_VECTOR; 232 | case 'q': 233 | return LST_QUATERNION; 234 | case 'l': 235 | return LST_LIST; 236 | default: 237 | return LST_NULL; 238 | } 239 | } 240 | 241 | void addType(LSCRIPTType type) 242 | { 243 | S32 count = 0; 244 | if (mString) 245 | { 246 | count = (S32)strlen(mString); /*Flawfinder: ignore*/ 247 | char *temp = new char[count + 2]; 248 | memcpy(temp, mString, count); /*Flawfinder: ignore*/ 249 | delete [] mString; 250 | mString = temp; 251 | mString[count + 1] = 0; 252 | } 253 | else 254 | { 255 | mString = new char[count + 2]; 256 | mString[count + 1] = 0; 257 | } 258 | mString[count++] = LSCRIPTFunctionTypeStrings[type]; 259 | } 260 | 261 | S32 getNumber() 262 | { 263 | if (mString) 264 | return (S32)strlen(mString); /*Flawfinder: ignore*/ 265 | else 266 | return 0; 267 | } 268 | 269 | char *mString; 270 | }; 271 | 272 | class LLScriptScopeEntry 273 | { 274 | public: 275 | LLScriptScopeEntry(const char *identifier, LSCRIPTIdentifierType idtype, LSCRIPTType type, S32 count = 0) 276 | : mIdentifier(identifier), mIDType(idtype), mType(type), mOffset(0), mSize(0), mAssignable(NULL), mCount(count), mLibraryNumber(0) 277 | { 278 | } 279 | 280 | ~LLScriptScopeEntry() {} 281 | 282 | const char *mIdentifier; 283 | LSCRIPTIdentifierType mIDType; 284 | LSCRIPTType mType; 285 | S32 mOffset; 286 | S32 mSize; 287 | LLScriptSimpleAssignable *mAssignable; 288 | S32 mCount; // NOTE: Index for locals in CIL. 289 | U16 mLibraryNumber; 290 | LLScriptArgString mFunctionArgs; 291 | LLScriptArgString mLocals; 292 | }; 293 | 294 | class LLScriptScope 295 | { 296 | public: 297 | LLScriptScope(LLStringTable *stable) 298 | : mParentScope(NULL), mSTable(stable), mFunctionCount(0), mStateCount(0) 299 | { 300 | } 301 | 302 | ~LLScriptScope() 303 | { 304 | mEntryMap.deleteAllData(); 305 | } 306 | 307 | LLScriptScopeEntry *addEntry(const char *identifier, LSCRIPTIdentifierType idtype, LSCRIPTType type) 308 | { 309 | const char *name = mSTable->addString(identifier); 310 | if (!mEntryMap.checkData(name)) 311 | { 312 | if (idtype == LIT_FUNCTION) 313 | mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type, mFunctionCount++); 314 | else if (idtype == LIT_STATE) 315 | mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type, mStateCount++); 316 | else 317 | mEntryMap[name] = new LLScriptScopeEntry(name, idtype, type); 318 | return mEntryMap[name]; 319 | } 320 | else 321 | { 322 | // identifier already exists at this scope 323 | return NULL; 324 | } 325 | } 326 | 327 | BOOL checkEntry(const char *identifier) 328 | { 329 | const char *name = mSTable->addString(identifier); 330 | if (mEntryMap.checkData(name)) 331 | { 332 | return TRUE; 333 | } 334 | else 335 | { 336 | // identifier already exists at this scope 337 | return FALSE; 338 | } 339 | } 340 | 341 | LLScriptScopeEntry *findEntry(const char *identifier) 342 | { 343 | const char *name = mSTable->addString(identifier); 344 | LLScriptScope *scope = this; 345 | 346 | while (scope) 347 | { 348 | if (scope->mEntryMap.checkData(name)) 349 | { 350 | // cool, we found it at this scope 351 | return scope->mEntryMap[name]; 352 | } 353 | scope = scope->mParentScope; 354 | } 355 | return NULL; 356 | } 357 | 358 | LLScriptScopeEntry *findEntryTyped(const char *identifier, LSCRIPTIdentifierType idtype) 359 | { 360 | const char *name = mSTable->addString(identifier); 361 | LLScriptScope *scope = this; 362 | 363 | while (scope) 364 | { 365 | if (scope->mEntryMap.checkData(name)) 366 | { 367 | // need to check type, and if type is function we need to check both types 368 | if (idtype == LIT_FUNCTION) 369 | { 370 | if (scope->mEntryMap[name]->mIDType == LIT_FUNCTION) 371 | { 372 | return scope->mEntryMap[name]; 373 | } 374 | else if (scope->mEntryMap[name]->mIDType == LIT_LIBRARY_FUNCTION) 375 | { 376 | return scope->mEntryMap[name]; 377 | } 378 | } 379 | else if (scope->mEntryMap[name]->mIDType == idtype) 380 | { 381 | // cool, we found it at this scope 382 | return scope->mEntryMap[name]; 383 | } 384 | } 385 | scope = scope->mParentScope; 386 | } 387 | return NULL; 388 | } 389 | 390 | void addParentScope(LLScriptScope *scope) 391 | { 392 | mParentScope = scope; 393 | } 394 | 395 | LLMap mEntryMap; 396 | LLScriptScope *mParentScope; 397 | LLStringTable *mSTable; 398 | S32 mFunctionCount; 399 | S32 mStateCount; 400 | }; 401 | 402 | extern LLStringTable *gScopeStringTable; 403 | 404 | 405 | 406 | #endif 407 | -------------------------------------------------------------------------------- /llcommon/llstringtable.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file llstringtable.cpp 3 | * @brief The LLStringTable class provides a _fast_ method for finding 4 | * unique copies of strings. 5 | * 6 | * $LicenseInfo:firstyear=2001&license=viewerlgpl$ 7 | * Second Life Viewer Source Code 8 | * Copyright (C) 2010, Linden Research, Inc. 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Lesser General Public 12 | * License as published by the Free Software Foundation; 13 | * version 2.1 of the License only. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Lesser General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU Lesser General Public 21 | * License along with this library; if not, write to the Free Software 22 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 | * 24 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 25 | * $/LicenseInfo$ 26 | */ 27 | 28 | #include "linden_common.h" 29 | 30 | #include "llstringtable.h" 31 | #include "llstl.h" 32 | 33 | LLStringTable gStringTable(32768); 34 | 35 | LLStringTableEntry::LLStringTableEntry(const char *str) 36 | : mString(NULL), mCount(1) 37 | { 38 | // Copy string 39 | U32 length = (U32)strlen(str) + 1; /*Flawfinder: ignore*/ 40 | length = llmin(length, MAX_STRINGS_LENGTH); 41 | mString = new char[length]; 42 | strncpy(mString, str, length); /*Flawfinder: ignore*/ 43 | mString[length - 1] = 0; 44 | } 45 | 46 | LLStringTableEntry::~LLStringTableEntry() 47 | { 48 | delete [] mString; 49 | mCount = 0; 50 | } 51 | 52 | LLStringTable::LLStringTable(int tablesize) 53 | : mUniqueEntries(0) 54 | { 55 | S32 i; 56 | if (!tablesize) 57 | tablesize = 4096; // some arbitrary default 58 | // Make sure tablesize is power of 2 59 | for (i = 31; i>0; i--) 60 | { 61 | if (tablesize & (1<= (3<<(i-1))) 64 | tablesize = (1<<(i+1)); 65 | else 66 | tablesize = (1<begin(); iter != mStringList[i]->end(); iter++) 94 | delete *iter; // *iter = (LLStringTableEntry*) 95 | } 96 | delete mStringList[i]; 97 | } 98 | delete [] mStringList; 99 | mStringList = NULL; 100 | } 101 | #else 102 | // Need to clean up the string hash 103 | for_each(mStringHash.begin(), mStringHash.end(), DeletePairedPointer()); 104 | mStringHash.clear(); 105 | #endif 106 | } 107 | 108 | 109 | static U32 hash_my_string(const char *str, int max_entries) 110 | { 111 | U32 retval = 0; 112 | #if 0 113 | while (*str) 114 | { 115 | retval <<= 1; 116 | retval += *str++; 117 | } 118 | #else 119 | while (*str) 120 | { 121 | retval = (retval<<4) + *str; 122 | U32 x = (retval & 0xf0000000); 123 | if (x) retval = retval ^ (x>>24); 124 | retval = retval & (~x); 125 | str++; 126 | } 127 | #endif 128 | return (retval & (max_entries-1)); // max_entries is gauranteed to be power of 2 129 | } 130 | 131 | char* LLStringTable::checkString(const std::string& str) 132 | { 133 | return checkString(str.c_str()); 134 | } 135 | 136 | char* LLStringTable::checkString(const char *str) 137 | { 138 | LLStringTableEntry* entry = checkStringEntry(str); 139 | if (entry) 140 | { 141 | return entry->mString; 142 | } 143 | else 144 | { 145 | return NULL; 146 | } 147 | } 148 | 149 | LLStringTableEntry* LLStringTable::checkStringEntry(const std::string& str) 150 | { 151 | return checkStringEntry(str.c_str()); 152 | } 153 | 154 | LLStringTableEntry* LLStringTable::checkStringEntry(const char *str) 155 | { 156 | if (str) 157 | { 158 | char *ret_val; 159 | LLStringTableEntry *entry; 160 | U32 hash_value = hash_my_string(str, mMaxEntries); 161 | #if STRING_TABLE_HASH_MAP 162 | #if 1 // Microsoft 163 | string_hash_t::iterator lower = mStringHash.lower_bound(hash_value); 164 | string_hash_t::iterator upper = mStringHash.upper_bound(hash_value); 165 | #else // stlport 166 | std::pair P = mStringHash.equal_range(hash_value); 167 | string_hash_t::iterator lower = P.first; 168 | string_hash_t::iterator upper = P.second; 169 | #endif 170 | for (string_hash_t::iterator iter = lower; iter != upper; iter++) 171 | { 172 | entry = iter->second; 173 | ret_val = entry->mString; 174 | if (!strncmp(ret_val, str, MAX_STRINGS_LENGTH)) 175 | { 176 | return entry; 177 | } 178 | } 179 | #else 180 | string_list_t *strlist = mStringList[hash_value]; 181 | if (strlist) 182 | { 183 | string_list_t::iterator iter; 184 | for (iter = strlist->begin(); iter != strlist->end(); iter++) 185 | { 186 | entry = *iter; 187 | ret_val = entry->mString; 188 | if (!strncmp(ret_val, str, MAX_STRINGS_LENGTH)) 189 | { 190 | return entry; 191 | } 192 | } 193 | } 194 | #endif 195 | } 196 | return NULL; 197 | } 198 | 199 | char* LLStringTable::addString(const std::string& str) 200 | { 201 | //RN: safe to use temporary c_str since string is copied 202 | return addString(str.c_str()); 203 | } 204 | 205 | char* LLStringTable::addString(const char *str) 206 | { 207 | 208 | LLStringTableEntry* entry = addStringEntry(str); 209 | if (entry) 210 | { 211 | return entry->mString; 212 | } 213 | else 214 | { 215 | return NULL; 216 | } 217 | } 218 | 219 | LLStringTableEntry* LLStringTable::addStringEntry(const std::string& str) 220 | { 221 | return addStringEntry(str.c_str()); 222 | } 223 | 224 | LLStringTableEntry* LLStringTable::addStringEntry(const char *str) 225 | { 226 | if (str) 227 | { 228 | char *ret_val = NULL; 229 | LLStringTableEntry *entry; 230 | U32 hash_value = hash_my_string(str, mMaxEntries); 231 | #if STRING_TABLE_HASH_MAP 232 | #if 1 // Microsoft 233 | string_hash_t::iterator lower = mStringHash.lower_bound(hash_value); 234 | string_hash_t::iterator upper = mStringHash.upper_bound(hash_value); 235 | #else // stlport 236 | std::pair P = mStringHash.equal_range(hash_value); 237 | string_hash_t::iterator lower = P.first; 238 | string_hash_t::iterator upper = P.second; 239 | #endif 240 | for (string_hash_t::iterator iter = lower; iter != upper; iter++) 241 | { 242 | entry = iter->second; 243 | ret_val = entry->mString; 244 | if (!strncmp(ret_val, str, MAX_STRINGS_LENGTH)) 245 | { 246 | entry->incCount(); 247 | return entry; 248 | } 249 | } 250 | 251 | // not found, so add! 252 | LLStringTableEntry* newentry = new LLStringTableEntry(str); 253 | ret_val = newentry->mString; 254 | mStringHash.insert(string_hash_t::value_type(hash_value, newentry)); 255 | #else 256 | string_list_t *strlist = mStringList[hash_value]; 257 | 258 | if (strlist) 259 | { 260 | string_list_t::iterator iter; 261 | for (iter = strlist->begin(); iter != strlist->end(); iter++) 262 | { 263 | entry = *iter; 264 | ret_val = entry->mString; 265 | if (!strncmp(ret_val, str, MAX_STRINGS_LENGTH)) 266 | { 267 | entry->incCount(); 268 | return entry; 269 | } 270 | } 271 | } 272 | else 273 | { 274 | mStringList[hash_value] = new string_list_t; 275 | strlist = mStringList[hash_value]; 276 | } 277 | 278 | // not found, so add! 279 | LLStringTableEntry *newentry = new LLStringTableEntry(str); 280 | //ret_val = newentry->mString; 281 | strlist->push_front(newentry); 282 | #endif 283 | mUniqueEntries++; 284 | return newentry; 285 | } 286 | else 287 | { 288 | return NULL; 289 | } 290 | } 291 | 292 | void LLStringTable::removeString(const char *str) 293 | { 294 | if (str) 295 | { 296 | char *ret_val; 297 | LLStringTableEntry *entry; 298 | U32 hash_value = hash_my_string(str, mMaxEntries); 299 | #if STRING_TABLE_HASH_MAP 300 | { 301 | #if 1 // Microsoft 302 | string_hash_t::iterator lower = mStringHash.lower_bound(hash_value); 303 | string_hash_t::iterator upper = mStringHash.upper_bound(hash_value); 304 | #else // stlport 305 | std::pair P = mStringHash.equal_range(hash_value); 306 | string_hash_t::iterator lower = P.first; 307 | string_hash_t::iterator upper = P.second; 308 | #endif 309 | for (string_hash_t::iterator iter = lower; iter != upper; iter++) 310 | { 311 | entry = iter->second; 312 | ret_val = entry->mString; 313 | if (!strncmp(ret_val, str, MAX_STRINGS_LENGTH)) 314 | { 315 | if (!entry->decCount()) 316 | { 317 | mUniqueEntries--; 318 | if (mUniqueEntries < 0) 319 | { 320 | llerror("LLStringTable:removeString trying to remove too many strings!", 0); 321 | } 322 | delete iter->second; 323 | mStringHash.erase(iter); 324 | } 325 | return; 326 | } 327 | } 328 | } 329 | #else 330 | string_list_t *strlist = mStringList[hash_value]; 331 | 332 | if (strlist) 333 | { 334 | string_list_t::iterator iter; 335 | for (iter = strlist->begin(); iter != strlist->end(); iter++) 336 | { 337 | entry = *iter; 338 | ret_val = entry->mString; 339 | if (!strncmp(ret_val, str, MAX_STRINGS_LENGTH)) 340 | { 341 | if (!entry->decCount()) 342 | { 343 | mUniqueEntries--; 344 | if (mUniqueEntries < 0) 345 | { 346 | llerror("LLStringTable:removeString trying to remove too many strings!", 0); 347 | } 348 | strlist->remove(entry); 349 | delete entry; 350 | } 351 | return; 352 | } 353 | } 354 | } 355 | #endif 356 | } 357 | } 358 | 359 | -------------------------------------------------------------------------------- /lscript/lscript_library.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lscript_library.h 3 | * @brief External library interface 4 | * 5 | * $LicenseInfo:firstyear=2002&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #ifndef LL_LSCRIPT_LIBRARY_H 28 | #define LL_LSCRIPT_LIBRARY_H 29 | 30 | #include "lscript_byteformat.h" 31 | //#include "v3math.h" 32 | //#include "llquaternion.h" 33 | #include "lluuid.h" 34 | #include "lscript_byteconvert.h" 35 | #include 36 | 37 | class LLScriptLibData; 38 | 39 | class LLScriptLibraryFunction 40 | { 41 | public: 42 | LLScriptLibraryFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), const char *name, const char *ret_type, const char *args, BOOL god_only = FALSE); 43 | ~LLScriptLibraryFunction(); 44 | 45 | F32 mEnergyUse; 46 | F32 mSleepTime; 47 | void (*mExecFunc)(LLScriptLibData *, LLScriptLibData *, const LLUUID &); 48 | const char *mName; 49 | const char *mReturnType; 50 | const char *mArgs; 51 | BOOL mGodOnly; 52 | }; 53 | 54 | class LLScriptLibrary 55 | { 56 | public: 57 | LLScriptLibrary(); 58 | ~LLScriptLibrary(); 59 | 60 | void init(); 61 | 62 | void addFunction(F32 eu, F32 st, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &), const char *name, const char *ret_type, const char *args, BOOL god_only = FALSE); 63 | void assignExec(const char *name, void (*exec_func)(LLScriptLibData *, LLScriptLibData *, const LLUUID &)); 64 | 65 | std::vector mFunctions; 66 | }; 67 | 68 | 69 | 70 | class LLScriptLibData 71 | { 72 | #if 0 73 | public: 74 | // TODO: Change this to a union 75 | LSCRIPTType mType; 76 | S32 mInteger; 77 | F32 mFP; 78 | char *mKey; 79 | char *mString; 80 | LLVector3 mVec; 81 | LLQuaternion mQuat; 82 | LLScriptLibData *mListp; 83 | 84 | friend bool operator<=(const LLScriptLibData &a, const LLScriptLibData &b) 85 | { 86 | if (a.mType == b.mType) 87 | { 88 | if (a.mType == LST_INTEGER) 89 | { 90 | return a.mInteger <= b.mInteger; 91 | } 92 | if (a.mType == LST_FLOATINGPOINT) 93 | { 94 | return a.mFP <= b.mFP; 95 | } 96 | if (a.mType == LST_STRING) 97 | { 98 | return strcmp(a.mString, b.mString) <= 0; 99 | } 100 | if (a.mType == LST_KEY) 101 | { 102 | return strcmp(a.mKey, b.mKey) <= 0; 103 | } 104 | if (a.mType == LST_VECTOR) 105 | { 106 | return a.mVec.magVecSquared() <= b.mVec.magVecSquared(); 107 | } 108 | } 109 | return TRUE; 110 | } 111 | 112 | friend bool operator==(const LLScriptLibData &a, const LLScriptLibData &b) 113 | { 114 | if (a.mType == b.mType) 115 | { 116 | if (a.mType == LST_INTEGER) 117 | { 118 | return a.mInteger == b.mInteger; 119 | } 120 | if (a.mType == LST_FLOATINGPOINT) 121 | { 122 | return a.mFP == b.mFP; 123 | } 124 | if (a.mType == LST_STRING) 125 | { 126 | return !strcmp(a.mString, b.mString); 127 | } 128 | if (a.mType == LST_KEY) 129 | { 130 | return !strcmp(a.mKey, b.mKey); 131 | } 132 | if (a.mType == LST_VECTOR) 133 | { 134 | return a.mVec == b.mVec; 135 | } 136 | if (a.mType == LST_QUATERNION) 137 | { 138 | return a.mQuat == b.mQuat; 139 | } 140 | } 141 | return FALSE; 142 | } 143 | 144 | S32 getListLength() const 145 | { 146 | const LLScriptLibData *data = this; 147 | S32 retval = 0; 148 | while (data->mListp) 149 | { 150 | retval++; 151 | data = data->mListp; 152 | } 153 | return retval; 154 | } 155 | 156 | BOOL checkForMultipleLists() 157 | { 158 | LLScriptLibData *data = this; 159 | while (data->mListp) 160 | { 161 | data = data->mListp; 162 | if (data->mType == LST_LIST) 163 | return TRUE; 164 | } 165 | return FALSE; 166 | } 167 | 168 | S32 getSavedSize() 169 | { 170 | S32 size = 0; 171 | // mType 172 | size += 4; 173 | 174 | switch(mType) 175 | { 176 | case LST_INTEGER: 177 | size += 4; 178 | break; 179 | case LST_FLOATINGPOINT: 180 | size += 4; 181 | break; 182 | case LST_KEY: 183 | size += (S32)strlen(mKey) + 1; /*Flawfinder: ignore*/ 184 | break; 185 | case LST_STRING: 186 | size += (S32)strlen(mString) + 1; /*Flawfinder: ignore*/ 187 | break; 188 | case LST_LIST: 189 | break; 190 | case LST_VECTOR: 191 | size += 12; 192 | break; 193 | case LST_QUATERNION: 194 | size += 16; 195 | break; 196 | default: 197 | break; 198 | } 199 | return size; 200 | } 201 | 202 | S32 write2bytestream(U8 *dest) 203 | { 204 | S32 offset = 0; 205 | integer2bytestream(dest, offset, mType); 206 | switch(mType) 207 | { 208 | case LST_INTEGER: 209 | integer2bytestream(dest, offset, mInteger); 210 | break; 211 | case LST_FLOATINGPOINT: 212 | float2bytestream(dest, offset, mFP); 213 | break; 214 | case LST_KEY: 215 | char2bytestream(dest, offset, mKey); 216 | break; 217 | case LST_STRING: 218 | char2bytestream(dest, offset, mString); 219 | break; 220 | case LST_LIST: 221 | break; 222 | case LST_VECTOR: 223 | vector2bytestream(dest, offset, mVec); 224 | break; 225 | case LST_QUATERNION: 226 | quaternion2bytestream(dest, offset, mQuat); 227 | break; 228 | default: 229 | break; 230 | } 231 | return offset; 232 | } 233 | 234 | LLScriptLibData() : mType(LST_NULL), mInteger(0), mFP(0.f), mKey(NULL), mString(NULL), mVec(), mQuat(), mListp(NULL) 235 | { 236 | } 237 | 238 | LLScriptLibData(const LLScriptLibData &data) : mType(data.mType), mInteger(data.mInteger), mFP(data.mFP), mKey(NULL), mString(NULL), mVec(data.mVec), mQuat(data.mQuat), mListp(NULL) 239 | { 240 | if (data.mKey) 241 | { 242 | mKey = new char[strlen(data.mKey) + 1]; /* Flawfinder: ignore */ 243 | if (mKey == NULL) 244 | { 245 | llerrs << "Memory Allocation Failed" << llendl; 246 | return; 247 | } 248 | strcpy(mKey, data.mKey); /* Flawfinder: ignore */ 249 | } 250 | if (data.mString) 251 | { 252 | mString = new char[strlen(data.mString) + 1]; /* Flawfinder: ignore */ 253 | if (mString == NULL) 254 | { 255 | llerrs << "Memory Allocation Failed" << llendl; 256 | return; 257 | } 258 | strcpy(mString, data.mString); /* Flawfinder: ignore */ 259 | } 260 | } 261 | 262 | LLScriptLibData(U8 *src, S32 &offset) : mListp(NULL) 263 | { 264 | static char temp[TOP_OF_MEMORY]; /* Flawfinder: ignore */ 265 | mType = (LSCRIPTType)bytestream2integer(src, offset); 266 | switch(mType) 267 | { 268 | case LST_INTEGER: 269 | mInteger = bytestream2integer(src, offset); 270 | break; 271 | case LST_FLOATINGPOINT: 272 | mFP = bytestream2float(src, offset); 273 | break; 274 | case LST_KEY: 275 | { 276 | bytestream2char(temp, src, offset, sizeof(temp)); 277 | mKey = new char[strlen(temp) + 1]; /* Flawfinder: ignore */ 278 | if (mKey == NULL) 279 | { 280 | llerrs << "Memory Allocation Failed" << llendl; 281 | return; 282 | } 283 | strcpy(mKey, temp); /* Flawfinder: ignore */ 284 | } 285 | break; 286 | case LST_STRING: 287 | { 288 | bytestream2char(temp, src, offset, sizeof(temp)); 289 | mString = new char[strlen(temp) + 1]; /* Flawfinder: ignore */ 290 | if (mString == NULL) 291 | { 292 | llerrs << "Memory Allocation Failed" << llendl; 293 | return; 294 | } 295 | strcpy(mString, temp); /* Flawfinder: ignore */ 296 | } 297 | break; 298 | case LST_LIST: 299 | break; 300 | case LST_VECTOR: 301 | bytestream2vector(mVec, src, offset); 302 | break; 303 | case LST_QUATERNION: 304 | bytestream2quaternion(mQuat, src, offset); 305 | break; 306 | default: 307 | break; 308 | } 309 | } 310 | 311 | void set(U8 *src, S32 &offset) 312 | { 313 | static char temp[TOP_OF_MEMORY]; /* Flawfinder: ignore */ 314 | mType = (LSCRIPTType)bytestream2integer(src, offset); 315 | switch(mType) 316 | { 317 | case LST_INTEGER: 318 | mInteger = bytestream2integer(src, offset); 319 | break; 320 | case LST_FLOATINGPOINT: 321 | mFP = bytestream2float(src, offset); 322 | break; 323 | case LST_KEY: 324 | { 325 | bytestream2char(temp, src, offset, sizeof(temp)); 326 | mKey = new char[strlen(temp) + 1]; /* Flawfinder: ignore */ 327 | if (mKey == NULL) 328 | { 329 | llerrs << "Memory Allocation Failed" << llendl; 330 | return; 331 | } 332 | strcpy(mKey, temp); /* Flawfinder: ignore */ 333 | } 334 | break; 335 | case LST_STRING: 336 | { 337 | bytestream2char(temp, src, offset, sizeof(temp)); 338 | mString = new char[strlen(temp) + 1]; /* Flawfinder: ignore */ 339 | if (mString == NULL) 340 | { 341 | llerrs << "Memory Allocation Failed" << llendl; 342 | return; 343 | } 344 | strcpy(mString, temp); /* Flawfinder: ignore */ 345 | } 346 | break; 347 | case LST_LIST: 348 | break; 349 | case LST_VECTOR: 350 | bytestream2vector(mVec, src, offset); 351 | break; 352 | case LST_QUATERNION: 353 | bytestream2quaternion(mQuat, src, offset); 354 | break; 355 | default: 356 | break; 357 | } 358 | } 359 | 360 | void print(std::ostream &s, BOOL b_prepend_comma); 361 | void print_separator(std::ostream& ostr, BOOL b_prepend_sep, char* sep); 362 | 363 | void setFromCSV(const char *src) 364 | { 365 | mType = LST_STRING; 366 | mString = new char[strlen(src) + 1]; /* Flawfinder: ignore */ 367 | if (mString == NULL) 368 | { 369 | llerrs << "Memory Allocation Failed" << llendl; 370 | return; 371 | } 372 | strcpy(mString, src); /* Flawfinder: ignore */ 373 | } 374 | 375 | LLScriptLibData(S32 integer) : mType(LST_INTEGER), mInteger(integer), mFP(0.f), mKey(NULL), mString(NULL), mVec(), mQuat(), mListp(NULL) 376 | { 377 | } 378 | 379 | LLScriptLibData(F32 fp) : mType(LST_FLOATINGPOINT), mInteger(0), mFP(fp), mKey(NULL), mString(NULL), mVec(), mQuat(), mListp(NULL) 380 | { 381 | } 382 | 383 | LLScriptLibData(const LLUUID &id) : mType(LST_KEY), mInteger(0), mFP(0.f), mKey(NULL), mString(NULL), mVec(), mQuat(), mListp(NULL) 384 | { 385 | std::string idstr; 386 | id.toString(idstr); 387 | mKey = new char[idstr.length()+1]; 388 | LLStringUtil::copy(mKey,idstr.c_str(),idstr.length()+1); 389 | } 390 | 391 | LLScriptLibData(const char *string) : mType(LST_STRING), mInteger(0), mFP(0.f), mKey(NULL), mString(NULL), mVec(), mQuat(), mListp(NULL) 392 | { 393 | if (!string) 394 | { 395 | mString = new char[1]; 396 | mString[0] = 0; 397 | } 398 | else 399 | { 400 | mString = new char[strlen(string) + 1]; /* Flawfinder: ignore */ 401 | if (mString == NULL) 402 | { 403 | llerrs << "Memory Allocation Failed" << llendl; 404 | return; 405 | } 406 | strcpy(mString, string); /* Flawfinder: ignore */ 407 | } 408 | } 409 | 410 | LLScriptLibData(const LLVector3 &vec) : mType(LST_VECTOR), mInteger(0), mFP(0.f), mKey(NULL), mString(NULL), mVec(vec), mQuat(), mListp(NULL) 411 | { 412 | } 413 | 414 | LLScriptLibData(const LLQuaternion &quat) : mType(LST_QUATERNION), mInteger(0), mFP(0.f), mKey(NULL), mString(NULL), mVec(), mQuat(quat), mListp(NULL) 415 | { 416 | } 417 | 418 | ~LLScriptLibData() 419 | { 420 | delete mListp; 421 | delete [] mKey; 422 | delete [] mString; 423 | } 424 | #endif 425 | 426 | }; 427 | 428 | extern LLScriptLibrary gScriptLibrary; 429 | 430 | #endif 431 | -------------------------------------------------------------------------------- /indra.l.in: -------------------------------------------------------------------------------- 1 | 2 | N [0-9] 3 | L [a-zA-Z_] 4 | H [a-fA-F0-9] 5 | E [Ee][+-]?{N}+ 6 | FS (f|F) 7 | %e 10000 8 | %n 4000 9 | %p 5000 10 | 11 | %top { 12 | #include "linden_common.h" 13 | } 14 | 15 | %{ 16 | // Deal with the fact that lex/yacc generates unreachable code 17 | #ifdef LL_WINDOWS 18 | #pragma warning (disable : 4018) // warning C4018: signed/unsigned mismatch 19 | #pragma warning (disable : 4702) // warning C4702: unreachable code 20 | #endif // LL_WINDOWS 21 | //#include "llmath.h" 22 | #include "lscript_tree.h" 23 | #include "lscript_typecheck.h" 24 | #include "lscript_resource.h" 25 | #include "indra.y.hpp" 26 | //#include "lltimer.h" 27 | //#include "indra_constants.h" 28 | //#include "llagentconstants.h" 29 | //#include "lllslconstants.h" 30 | //#include "lluuid.h" 31 | //#include "llassetstorage.h" 32 | //#include "llpartdata.h" 33 | //#include "llvehicleparams.h" 34 | //#include "llpermissionsflags.h" 35 | //#include "llfollowcamparams.h" 36 | //#include "llparcelflags.h" 37 | //#include "llregionflags.h" 38 | //#include "lscript_http.h" 39 | //#include "llclickaction.h" 40 | //#include "llmediaentry.h" 41 | // Add OSSL constants for OS builds 42 | //#ifdef OPENSIM 43 | //#include "osslconstants.h" 44 | //#endif // OPENSIM 45 | // 46 | 47 | void count(); 48 | void line_comment(); 49 | void block_comment(); 50 | void parse_string(); 51 | 52 | #define YYLMAX 16384 53 | #define YY_NEVER_INTERACTIVE 1 /* stops flex from calling isatty() */ 54 | #ifdef LL_WINDOWS 55 | #define isatty(x) 0 /* hack for bug in cygwin flex 2.5.35 */ 56 | #endif 57 | 58 | #ifdef ECHO 59 | #undef ECHO 60 | #endif 61 | 62 | #define ECHO do { } while (0) 63 | 64 | #define yyparse indra_parse 65 | #define yyerror indra_error 66 | #define yylval indra_lval 67 | #define yy_create_buffer indra__create_buffer 68 | #define yy_delete_buffer indra__delete_buffer 69 | #define yy_flex_debug indra__flex_debug 70 | #define yy_init_buffer indra__init_buffer 71 | #define yy_flush_buffer indra__flush_buffer 72 | #define yy_load_buffer_state indra__load_buffer_state 73 | #define yy_switch_to_buffer indra__switch_to_buffer 74 | #define yyin indra_in 75 | #define yyleng indra_leng 76 | #define yylex indra_lex 77 | #define yylineno indra_lineno 78 | #define yyout indra_out 79 | #define yyrestart indra_restart 80 | #define yytext indra_text 81 | #define yywrap indra_wrap 82 | #define yyalloc indra_alloc 83 | #define yyrealloc indra_realloc 84 | #define yyfree indra_free 85 | 86 | 87 | int yylex( void ); 88 | int yyparse( void ); 89 | int yyerror(const char *fmt, ...); 90 | 91 | 92 | %} 93 | 94 | %% 95 | "//" { gInternalLine++; gInternalColumn = 0; line_comment(); } 96 | "/*" { block_comment(); } 97 | 98 | "integer" { count(); return(INTEGER); } 99 | "float" { count(); return(FLOAT_TYPE); } 100 | "string" { count(); return(STRING); } 101 | "key" { count(); return(LLKEY); } 102 | "vector" { count(); return(VECTOR); } 103 | "quaternion" { count(); return(QUATERNION); } 104 | "rotation" { count(); return(QUATERNION); } 105 | "list" { count(); return(LIST); } 106 | 107 | "default" { count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(STATE_DEFAULT); } 108 | "state" { count(); return(STATE); } 109 | "event" { count(); return(EVENT); } 110 | "jump" { count(); return(JUMP); } 111 | "return" { count(); return(RETURN); } 112 | "if" { count(); return(IF); } 113 | "else" { count(); return(ELSE); } 114 | "for" { count(); return(FOR); } 115 | "do" { count(); return(DO); } 116 | "while" { count(); return(WHILE); } 117 | 118 | "state_entry" { count(); return(STATE_ENTRY); } 119 | "state_exit" { count(); return(STATE_EXIT); } 120 | "touch_start" { count(); return(TOUCH_START); } 121 | "touch" { count(); return(TOUCH); } 122 | "touch_end" { count(); return(TOUCH_END); } 123 | "collision_start" { count(); return(COLLISION_START); } 124 | "collision" { count(); return(COLLISION); } 125 | "collision_end" { count(); return(COLLISION_END); } 126 | "land_collision_start" { count(); return(LAND_COLLISION_START); } 127 | "land_collision" { count(); return(LAND_COLLISION); } 128 | "land_collision_end" { count(); return(LAND_COLLISION_END); } 129 | "timer" { count(); return(TIMER); } 130 | "listen" { count(); return(CHAT); } 131 | "sensor" { count(); return(SENSOR); } 132 | "no_sensor" { count(); return(NO_SENSOR); } 133 | "control" { count(); return(CONTROL); } 134 | "print" { count(); return(PRINT); } 135 | "at_target" { count(); return(AT_TARGET); } 136 | "not_at_target" { count(); return(NOT_AT_TARGET); } 137 | "at_rot_target" { count(); return(AT_ROT_TARGET); } 138 | "not_at_rot_target" { count(); return(NOT_AT_ROT_TARGET); } 139 | "money" { count(); return(MONEY); } 140 | "email" { count(); return(EMAIL); } 141 | "run_time_permissions" { count(); return(RUN_TIME_PERMISSIONS); } 142 | "changed" { count(); return(INVENTORY); } 143 | "attach" { count(); return(ATTACH); } 144 | "dataserver" { count(); return(DATASERVER); } 145 | "moving_start" { count(); return(MOVING_START); } 146 | "moving_end" { count(); return(MOVING_END); } 147 | "link_message" { count(); return(LINK_MESSAGE); } 148 | "on_rez" { count(); return(REZ); } 149 | "object_rez" { count(); return(OBJECT_REZ); } 150 | "remote_data" { count(); return(REMOTE_DATA); } 151 | "http_response" { count(); return(HTTP_RESPONSE); } 152 | "http_request" { count(); return(HTTP_REQUEST); } 153 | "transaction_result" { count(); return(TRANSACTION_RESULT); } 154 | "path_update" { count(); return(PATH_UPDATE); } 155 | "experience_permissions" { count(); return(EXPERIENCE_PERMISSIONS); } 156 | "experience_permissions_denied" { count(); return(EXPERIENCE_PERMISSIONS_DENIED); } 157 | "." { count(); return(PERIOD); } 158 | 159 | 160 | 0[xX]{H}+ { count(); yylval.ival = strtoul(yytext, NULL, 0); return(INTEGER_CONSTANT); } 161 | {N}+ { count(); yylval.ival = strtoul(yytext, NULL, 10); return(INTEGER_CONSTANT); } 162 | "TRUE" { count(); yylval.ival = 1; return(INTEGER_TRUE); } 163 | "FALSE" { count(); yylval.ival = 0; return(INTEGER_FALSE); } 164 | 165 | "ZERO_VECTOR" { count(); return(ZERO_VECTOR); } 166 | "ZERO_ROTATION" { count(); return(ZERO_ROTATION); } 167 | "TOUCH_INVALID_VECTOR" { count(); return(TOUCH_INVALID_VECTOR); } 168 | "TOUCH_INVALID_TEXCOORD" { count(); return(TOUCH_INVALID_TEXCOORD); } 169 | 170 | <<< LSL KEYWORDS version >>> 171 | 172 | <<< LSL KEYWORDS integer_constants >>> 173 | <<< LSL KEYWORDS fp_constants >>> 174 | <<< LSL KEYWORDS string_constants >>> 175 | 176 | {L}({L}|{N})* { count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(IDENTIFIER); } 177 | 178 | {N}+{E} { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); } 179 | {N}*"."{N}+({E})?{FS}? { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); } 180 | {N}+"."{N}*({E})?{FS}? { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); } 181 | 182 | L?\"(\\.|[^\\"])*\" { parse_string(); count(); return(STRING_CONSTANT); } 183 | 184 | "++" { count(); return(INC_OP); } 185 | "--" { count(); return(DEC_OP); } 186 | "+=" { count(); return(ADD_ASSIGN); } 187 | "-=" { count(); return(SUB_ASSIGN); } 188 | "*=" { count(); return(MUL_ASSIGN); } 189 | "/=" { count(); return(DIV_ASSIGN); } 190 | "%=" { count(); return(MOD_ASSIGN); } 191 | ";" { count(); return(';'); } 192 | "{" { count(); return('{'); } 193 | "}" { count(); return('}'); } 194 | "," { count(); return(','); } 195 | "=" { count(); return('='); } 196 | "(" { count(); return('('); } 197 | ")" { count(); return(')'); } 198 | "-" { count(); return('-'); } 199 | "+" { count(); return('+'); } 200 | "*" { count(); return('*'); } 201 | "/" { count(); return('/'); } 202 | "%" { count(); return('%'); } 203 | "@" { count(); return('@'); } 204 | ":" { count(); return(':'); } 205 | ">" { count(); return('>'); } 206 | "<" { count(); return('<'); } 207 | "]" { count(); return(']'); } 208 | "[" { count(); return('['); } 209 | "==" { count(); return(EQ); } 210 | "!=" { count(); return(NEQ); } 211 | ">=" { count(); return(GEQ); } 212 | "<=" { count(); return(LEQ); } 213 | "&" { count(); return('&'); } 214 | "|" { count(); return('|'); } 215 | "^" { count(); return('^'); } 216 | "~" { count(); return('~'); } 217 | "!" { count(); return('!'); } 218 | "&&" { count(); return(BOOLEAN_AND); } 219 | "||" { count(); return(BOOLEAN_OR); } 220 | "<<" { count(); return(SHIFT_LEFT); } 221 | ">>" { count(); return(SHIFT_RIGHT); } 222 | 223 | [ \t\v\n\f] { count(); } 224 | . { /* ignore bad characters */ } 225 | 226 | %% 227 | 228 | LLScriptAllocationManager *gAllocationManager; 229 | LLScriptScript *gScriptp; 230 | 231 | // Prototype for the yacc parser entry point 232 | int yyparse(void); 233 | 234 | int yyerror(const char *fmt, ...) 235 | { 236 | gErrorToText.writeError(yyout, gLine, gColumn, LSERROR_SYNTAX_ERROR); 237 | return 0; 238 | } 239 | 240 | //#define EMERGENCY_DEBUG_PRINTOUTS 241 | //#define EMIT_CIL_ASSEMBLER 242 | 243 | BOOL lscript_compile(const char* src_filename, const char* dst_filename, 244 | const char* err_filename, BOOL compile_to_mono, const char* class_name, BOOL is_god_like) 245 | { 246 | BOOL b_parse_ok = FALSE; 247 | BOOL b_dummy = FALSE; 248 | U64 b_dummy_count = FALSE; 249 | LSCRIPTType type = LST_NULL; 250 | 251 | gInternalColumn = 0; 252 | gInternalLine = 0; 253 | gScriptp = NULL; 254 | 255 | gErrorToText.init(); 256 | init_supported_expressions(); 257 | init_temp_jumps(); 258 | gAllocationManager = new LLScriptAllocationManager(); 259 | 260 | yyin = LLFile::fopen(std::string(src_filename), "r"); 261 | if (yyin) 262 | { 263 | yyout = LLFile::fopen(std::string(err_filename), "w"); 264 | 265 | // Reset the lexer's internal buffering. 266 | 267 | yyrestart(yyin); 268 | 269 | b_parse_ok = !yyparse(); 270 | 271 | if (b_parse_ok) 272 | { 273 | #ifdef EMERGENCY_DEBUG_PRINTOUTS 274 | char compiled[256]; 275 | sprintf(compiled, "%s.pp", src_filename); 276 | LLFILE* compfile; 277 | compfile = LLFile::fopen(compiled, "w"); 278 | #endif 279 | 280 | if(dst_filename) 281 | { 282 | gScriptp->setBytecodeDest(dst_filename); 283 | } 284 | 285 | gScriptp->mGodLike = is_god_like; 286 | 287 | gScriptp->setClassName(class_name); 288 | 289 | gScopeStringTable = new LLStringTable(16384); 290 | #ifdef EMERGENCY_DEBUG_PRINTOUTS 291 | gScriptp->recurse(compfile, 0, 4, LSCP_PRETTY_PRINT, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL); 292 | #endif 293 | gScriptp->recurse(yyout, 0, 0, LSCP_PRUNE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL); 294 | gScriptp->recurse(yyout, 0, 0, LSCP_SCOPE_PASS1, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL); 295 | gScriptp->recurse(yyout, 0, 0, LSCP_SCOPE_PASS2, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL); 296 | gScriptp->recurse(yyout, 0, 0, LSCP_TYPE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL); 297 | if (!gErrorToText.getErrors()) 298 | { 299 | gScriptp->recurse(yyout, 0, 0, LSCP_RESOURCE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL); 300 | #ifdef EMERGENCY_DEBUG_PRINTOUTS 301 | gScriptp->recurse(yyout, 0, 0, LSCP_EMIT_ASSEMBLY, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL); 302 | #endif 303 | if(TRUE == compile_to_mono) 304 | { 305 | gScriptp->recurse(yyout, 0, 0, LSCP_EMIT_CIL_ASSEMBLY, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL); 306 | } 307 | else 308 | { 309 | gScriptp->recurse(yyout, 0, 0, LSCP_EMIT_BYTE_CODE, LSPRUNE_INVALID, b_dummy, NULL, type, type, b_dummy_count, NULL, NULL, 0, NULL, 0, NULL); 310 | } 311 | } 312 | delete gScopeStringTable; 313 | gScopeStringTable = NULL; 314 | #ifdef EMERGENCY_DEBUG_PRINTOUTS 315 | fclose(compfile); 316 | #endif 317 | } 318 | fclose(yyout); 319 | fclose(yyin); 320 | } 321 | 322 | delete gAllocationManager; 323 | delete gScopeStringTable; 324 | 325 | return b_parse_ok && !gErrorToText.getErrors(); 326 | } 327 | 328 | 329 | BOOL lscript_compile(char *filename, BOOL compile_to_mono, BOOL is_god_like = FALSE) 330 | { 331 | char src_filename[MAX_STRING]; 332 | sprintf(src_filename, "%s.lsl", filename); 333 | char err_filename[MAX_STRING]; 334 | sprintf(err_filename, "%s.out", filename); 335 | char class_name[MAX_STRING]; 336 | sprintf(class_name, "%s", filename); 337 | return lscript_compile(src_filename, NULL, err_filename, compile_to_mono, class_name, is_god_like); 338 | } 339 | 340 | 341 | S32 yywrap() 342 | { 343 | #if defined(FLEX_SCANNER) && !defined(LL_WINDOWS) 344 | // get gcc to stop complaining about lack of use of yyunput 345 | (void) yyunput; 346 | #endif 347 | return(1); 348 | } 349 | 350 | void line_comment() 351 | { 352 | char c; 353 | 354 | while ((c = yyinput()) != '\n' && c != 0 && c != EOF) 355 | ; 356 | } 357 | 358 | void block_comment() 359 | { 360 | char c1 = 0; 361 | char c2 = yyinput(); 362 | while (c2 != 0 && c2 != EOF && !(c1 == '*' && c2 == '/')) { 363 | if (c2 == '\n') 364 | { 365 | gInternalLine++; 366 | gInternalColumn = 0; 367 | } 368 | else if (c2 == '\t') 369 | gInternalColumn += 4 - (gInternalColumn % 8); 370 | else 371 | gInternalColumn++; 372 | c1 = c2; 373 | c2 = yyinput(); 374 | } 375 | } 376 | 377 | void count() 378 | { 379 | S32 i; 380 | 381 | gColumn = gInternalColumn; 382 | gLine = gInternalLine; 383 | 384 | for (i = 0; yytext[i] != '\0'; i++) 385 | if (yytext[i] == '\n') 386 | { 387 | gInternalLine++; 388 | gInternalColumn = 0; 389 | } 390 | else if (yytext[i] == '\t') 391 | gInternalColumn += 4 - (gInternalColumn % 8); 392 | else 393 | gInternalColumn++; 394 | } 395 | 396 | void parse_string() 397 | { 398 | S32 length = (S32)strlen(yytext); 399 | length = length - 2; 400 | char *temp = yytext + 1; 401 | 402 | S32 i; 403 | S32 escapes = 0; 404 | S32 tabs = 0; 405 | for (i = 0; i < length; i++) 406 | { 407 | if (temp[i] == '\\') 408 | { 409 | escapes++; 410 | i++; 411 | if (temp[i] == 't') 412 | tabs++; 413 | } 414 | } 415 | 416 | S32 newlength = length - escapes + tabs*3; 417 | yylval.sval = new char[newlength + 1]; 418 | 419 | char *dest = yylval.sval; 420 | 421 | for (i = 0; i < length; i++) 422 | { 423 | if (temp[i] == '\\') 424 | { 425 | i++; 426 | // linefeed 427 | if (temp[i] == 'n') 428 | { 429 | *dest++ = 10; 430 | } 431 | else if (temp[i] == 't') 432 | { 433 | *dest++ = ' '; 434 | *dest++ = ' '; 435 | *dest++ = ' '; 436 | *dest++ = ' '; 437 | } 438 | else 439 | { 440 | *dest++ = temp[i]; 441 | } 442 | } 443 | else 444 | { 445 | *dest++ = temp[i]; 446 | } 447 | } 448 | yylval.sval[newlength] = 0; 449 | } 450 | -------------------------------------------------------------------------------- /llcommon/llfile.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file llfile.h 3 | * @author Michael Schlachter 4 | * @date 2006-03-23 5 | * @brief Declaration of cross-platform POSIX file buffer and c++ 6 | * stream classes. 7 | * 8 | * $LicenseInfo:firstyear=2006&license=viewerlgpl$ 9 | * Second Life Viewer Source Code 10 | * Copyright (C) 2010, Linden Research, Inc. 11 | * 12 | * This library is free software; you can redistribute it and/or 13 | * modify it under the terms of the GNU Lesser General Public 14 | * License as published by the Free Software Foundation; 15 | * version 2.1 of the License only. 16 | * 17 | * This library is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | * Lesser General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU Lesser General Public 23 | * License along with this library; if not, write to the Free Software 24 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 25 | * 26 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 27 | * $/LicenseInfo$ 28 | */ 29 | 30 | #ifndef LL_LLFILE_H 31 | #define LL_LLFILE_H 32 | 33 | /** 34 | * This class provides a cross platform interface to the filesystem. 35 | * Attempts to mostly mirror the POSIX style IO functions. 36 | */ 37 | 38 | typedef FILE LLFILE; 39 | 40 | #include 41 | #include 42 | 43 | #if LL_WINDOWS 44 | // windows version of stat function and stat data structure are called _stat 45 | typedef struct _stat llstat; 46 | #else 47 | typedef struct stat llstat; 48 | #include 49 | #include 50 | #endif 51 | 52 | #ifndef S_ISREG 53 | # define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) 54 | #endif 55 | 56 | #ifndef S_ISDIR 57 | # define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) 58 | #endif 59 | 60 | #include "llstring.h" // safe char* -> std::string conversion 61 | 62 | class LL_COMMON_API LLFile 63 | { 64 | public: 65 | // All these functions take UTF8 path/filenames. 66 | static LLFILE* fopen(const std::string& filename,const char* accessmode); /* Flawfinder: ignore */ 67 | static LLFILE* _fsopen(const std::string& filename,const char* accessmode,int sharingFlag); 68 | 69 | static int close(LLFILE * file); 70 | 71 | // perms is a permissions mask like 0777 or 0700. In most cases it will 72 | // be overridden by the user's umask. It is ignored on Windows. 73 | static int mkdir(const std::string& filename, int perms = 0700); 74 | 75 | static int rmdir(const std::string& filename); 76 | static int remove(const std::string& filename); 77 | static int rename(const std::string& filename,const std::string& newname); 78 | static int stat(const std::string& filename,llstat* file_status); 79 | static bool isdir(const std::string& filename); 80 | static bool isfile(const std::string& filename); 81 | static LLFILE * _Fiopen(const std::string& filename, 82 | std::ios::openmode mode); 83 | 84 | static const char * tmpdir(); 85 | }; 86 | 87 | /** 88 | * @brief Provides a layer of compatibility for C/POSIX. 89 | * 90 | * This is taken from both the GNU __gnu_cxx::stdio_filebuf extension and 91 | * VC's basic_filebuf implementation. 92 | * This file buffer provides extensions for working with standard C FILE*'s 93 | * and POSIX file descriptors for platforms that support this. 94 | */ 95 | namespace 96 | { 97 | #if LL_WINDOWS 98 | typedef std::filebuf _Myfb; 99 | #else 100 | typedef __gnu_cxx::stdio_filebuf< char > _Myfb; 101 | typedef std::__c_file _Filet; 102 | #endif /* LL_WINDOWS */ 103 | } 104 | 105 | class LL_COMMON_API llstdio_filebuf : public _Myfb 106 | { 107 | public: 108 | /** 109 | * deferred initialization / destruction 110 | */ 111 | llstdio_filebuf() : _Myfb() {} 112 | virtual ~llstdio_filebuf() {} 113 | 114 | /** 115 | * @param f An open @c FILE*. 116 | * @param mode Same meaning as in a standard filebuf. 117 | * @param size Optimal or preferred size of internal buffer, in chars. 118 | * Defaults to system's @c BUFSIZ. 119 | * 120 | * This constructor associates a file stream buffer with an open 121 | * C @c FILE*. The @c FILE* will not be automatically closed when the 122 | * stdio_filebuf is closed/destroyed. 123 | */ 124 | llstdio_filebuf(_Filet* __f, std::ios_base::openmode __mode, 125 | //size_t __size = static_cast(BUFSIZ)) : 126 | size_t __size = static_cast(1)) : 127 | #if LL_WINDOWS 128 | _Myfb(__f) {} 129 | #else 130 | _Myfb(__f, __mode, __size) {} 131 | #endif 132 | 133 | /** 134 | * @brief Opens an external file. 135 | * @param s The name of the file. 136 | * @param mode The open mode flags. 137 | * @return @c this on success, NULL on failure 138 | * 139 | * If a file is already open, this function immediately fails. 140 | * Otherwise it tries to open the file named @a s using the flags 141 | * given in @a mode. 142 | */ 143 | //llstdio_filebuf* open(const char *_Filename, 144 | // std::ios_base::openmode _Mode); 145 | 146 | /** 147 | * @param fd An open file descriptor. 148 | * @param mode Same meaning as in a standard filebuf. 149 | * @param size Optimal or preferred size of internal buffer, in chars. 150 | * 151 | * This constructor associates a file stream buffer with an open 152 | * POSIX file descriptor. The file descriptor will be automatically 153 | * closed when the stdio_filebuf is closed/destroyed. 154 | */ 155 | #if !LL_WINDOWS 156 | llstdio_filebuf(int __fd, std::ios_base::openmode __mode, 157 | //size_t __size = static_cast(BUFSIZ)) : 158 | size_t __size = static_cast(1)) : 159 | _Myfb(__fd, __mode, __size) {} 160 | #endif 161 | 162 | // *TODO: Seek the underlying c stream for better cross-platform compatibility? 163 | #if !LL_WINDOWS 164 | protected: 165 | /** underflow() and uflow() functions are called to get the next 166 | * character from the real input source when the buffer is empty. 167 | * Buffered input uses underflow() 168 | */ 169 | /*virtual*/ int_type underflow(); 170 | 171 | /* Convert internal byte sequence to external, char-based 172 | * sequence via codecvt. 173 | */ 174 | bool _convert_to_external(char_type*, std::streamsize); 175 | 176 | /** The overflow() function is called to transfer characters to the 177 | * real output destination when the buffer is full. A call to 178 | * overflow(c) outputs the contents of the buffer plus the 179 | * character c. 180 | * Consume some sequence of the characters in the pending sequence. 181 | */ 182 | /*virtual*/ int_type overflow(int_type __c = traits_type::eof()); 183 | 184 | /** sync() flushes the underlying @c FILE* stream. 185 | */ 186 | /*virtual*/ int sync(); 187 | 188 | std::streamsize xsgetn(char_type*, std::streamsize); 189 | std::streamsize xsputn(char_type*, std::streamsize); 190 | #endif 191 | }; 192 | 193 | 194 | /** 195 | * @brief Controlling input for files. 196 | * 197 | * This class supports reading from named files, using the inherited 198 | * functions from std::basic_istream. To control the associated 199 | * sequence, an instance of std::basic_filebuf (or a platform-specific derivative) 200 | * which allows construction using a pre-exisintg file stream buffer. 201 | * We refer to this std::basic_filebuf (or derivative) as @c sb. 202 | */ 203 | class LL_COMMON_API llifstream : public std::istream 204 | { 205 | // input stream associated with a C stream 206 | public: 207 | // Constructors: 208 | /** 209 | * @brief Default constructor. 210 | * 211 | * Initializes @c sb using its default constructor, and passes 212 | * @c &sb to the base class initializer. Does not open any files 213 | * (you haven't given it a filename to open). 214 | */ 215 | llifstream(); 216 | 217 | /** 218 | * @brief Create an input file stream. 219 | * @param Filename String specifying the filename. 220 | * @param Mode Open file in specified mode (see std::ios_base). 221 | * 222 | * @c ios_base::in is automatically included in @a mode. 223 | */ 224 | explicit llifstream(const std::string& _Filename, 225 | ios_base::openmode _Mode = ios_base::in); 226 | explicit llifstream(const char* _Filename, 227 | ios_base::openmode _Mode = ios_base::in); 228 | 229 | /** 230 | * @brief Create a stream using an open c file stream. 231 | * @param File An open @c FILE*. 232 | @param Mode Same meaning as in a standard filebuf. 233 | @param Size Optimal or preferred size of internal buffer, in chars. 234 | Defaults to system's @c BUFSIZ. 235 | */ 236 | explicit llifstream(_Filet *_File, 237 | ios_base::openmode _Mode = ios_base::in, 238 | //size_t _Size = static_cast(BUFSIZ)); 239 | size_t _Size = static_cast(1)); 240 | 241 | /** 242 | * @brief Create a stream using an open file descriptor. 243 | * @param fd An open file descriptor. 244 | @param Mode Same meaning as in a standard filebuf. 245 | @param Size Optimal or preferred size of internal buffer, in chars. 246 | Defaults to system's @c BUFSIZ. 247 | */ 248 | #if !LL_WINDOWS 249 | explicit llifstream(int __fd, 250 | ios_base::openmode _Mode = ios_base::in, 251 | //size_t _Size = static_cast(BUFSIZ)); 252 | size_t _Size = static_cast(1)); 253 | #endif 254 | 255 | /** 256 | * @brief The destructor does nothing. 257 | * 258 | * The file is closed by the filebuf object, not the formatting 259 | * stream. 260 | */ 261 | virtual ~llifstream() {} 262 | 263 | // Members: 264 | /** 265 | * @brief Accessing the underlying buffer. 266 | * @return The current basic_filebuf buffer. 267 | * 268 | * This hides both signatures of std::basic_ios::rdbuf(). 269 | */ 270 | llstdio_filebuf* rdbuf() const 271 | { return const_cast(&_M_filebuf); } 272 | 273 | /** 274 | * @brief Wrapper to test for an open file. 275 | * @return @c rdbuf()->is_open() 276 | */ 277 | bool is_open() const; 278 | 279 | /** 280 | * @brief Opens an external file. 281 | * @param Filename The name of the file. 282 | * @param Node The open mode flags. 283 | * 284 | * Calls @c llstdio_filebuf::open(s,mode|in). If that function 285 | * fails, @c failbit is set in the stream's error state. 286 | */ 287 | void open(const std::string& _Filename, 288 | ios_base::openmode _Mode = ios_base::in) 289 | { open(_Filename.c_str(), _Mode); } 290 | void open(const char* _Filename, 291 | ios_base::openmode _Mode = ios_base::in); 292 | 293 | /** 294 | * @brief Close the file. 295 | * 296 | * Calls @c llstdio_filebuf::close(). If that function 297 | * fails, @c failbit is set in the stream's error state. 298 | */ 299 | void close(); 300 | 301 | private: 302 | llstdio_filebuf _M_filebuf; 303 | }; 304 | 305 | 306 | /** 307 | * @brief Controlling output for files. 308 | * 309 | * This class supports writing to named files, using the inherited 310 | * functions from std::basic_ostream. To control the associated 311 | * sequence, an instance of std::basic_filebuf (or a platform-specific derivative) 312 | * which allows construction using a pre-exisintg file stream buffer. 313 | * We refer to this std::basic_filebuf (or derivative) as @c sb. 314 | */ 315 | class LL_COMMON_API llofstream : public std::ostream 316 | { 317 | public: 318 | // Constructors: 319 | /** 320 | * @brief Default constructor. 321 | * 322 | * Initializes @c sb using its default constructor, and passes 323 | * @c &sb to the base class initializer. Does not open any files 324 | * (you haven't given it a filename to open). 325 | */ 326 | llofstream(); 327 | 328 | /** 329 | * @brief Create an output file stream. 330 | * @param Filename String specifying the filename. 331 | * @param Mode Open file in specified mode (see std::ios_base). 332 | * 333 | * @c ios_base::out|ios_base::trunc is automatically included in 334 | * @a mode. 335 | */ 336 | explicit llofstream(const std::string& _Filename, 337 | ios_base::openmode _Mode = ios_base::out|ios_base::trunc); 338 | explicit llofstream(const char* _Filename, 339 | ios_base::openmode _Mode = ios_base::out|ios_base::trunc); 340 | 341 | /** 342 | * @brief Create a stream using an open c file stream. 343 | * @param File An open @c FILE*. 344 | @param Mode Same meaning as in a standard filebuf. 345 | @param Size Optimal or preferred size of internal buffer, in chars. 346 | Defaults to system's @c BUFSIZ. 347 | */ 348 | explicit llofstream(_Filet *_File, 349 | ios_base::openmode _Mode = ios_base::out, 350 | //size_t _Size = static_cast(BUFSIZ)); 351 | size_t _Size = static_cast(1)); 352 | 353 | /** 354 | * @brief Create a stream using an open file descriptor. 355 | * @param fd An open file descriptor. 356 | @param Mode Same meaning as in a standard filebuf. 357 | @param Size Optimal or preferred size of internal buffer, in chars. 358 | Defaults to system's @c BUFSIZ. 359 | */ 360 | #if !LL_WINDOWS 361 | explicit llofstream(int __fd, 362 | ios_base::openmode _Mode = ios_base::out, 363 | //size_t _Size = static_cast(BUFSIZ)); 364 | size_t _Size = static_cast(1)); 365 | #endif 366 | 367 | /** 368 | * @brief The destructor does nothing. 369 | * 370 | * The file is closed by the filebuf object, not the formatting 371 | * stream. 372 | */ 373 | virtual ~llofstream() {} 374 | 375 | // Members: 376 | /** 377 | * @brief Accessing the underlying buffer. 378 | * @return The current basic_filebuf buffer. 379 | * 380 | * This hides both signatures of std::basic_ios::rdbuf(). 381 | */ 382 | llstdio_filebuf* rdbuf() const 383 | { return const_cast(&_M_filebuf); } 384 | 385 | /** 386 | * @brief Wrapper to test for an open file. 387 | * @return @c rdbuf()->is_open() 388 | */ 389 | bool is_open() const; 390 | 391 | /** 392 | * @brief Opens an external file. 393 | * @param Filename The name of the file. 394 | * @param Node The open mode flags. 395 | * 396 | * Calls @c llstdio_filebuf::open(s,mode|out). If that function 397 | * fails, @c failbit is set in the stream's error state. 398 | */ 399 | void open(const std::string& _Filename, 400 | ios_base::openmode _Mode = ios_base::out|ios_base::trunc) 401 | { open(_Filename.c_str(), _Mode); } 402 | void open(const char* _Filename, 403 | ios_base::openmode _Mode = ios_base::out|ios_base::trunc); 404 | 405 | /** 406 | * @brief Close the file. 407 | * 408 | * Calls @c llstdio_filebuf::close(). If that function 409 | * fails, @c failbit is set in the stream's error state. 410 | */ 411 | void close(); 412 | 413 | private: 414 | llstdio_filebuf _M_filebuf; 415 | }; 416 | 417 | 418 | /** 419 | * @breif filesize helpers. 420 | * 421 | * The file size helpers are not considered particularly efficient, 422 | * and should only be used for config files and the like -- not in a 423 | * loop. 424 | */ 425 | std::streamsize LL_COMMON_API llifstream_size(llifstream& fstr); 426 | std::streamsize LL_COMMON_API llofstream_size(llofstream& fstr); 427 | 428 | #endif // not LL_LLFILE_H 429 | -------------------------------------------------------------------------------- /lscript/lscript_byteformat.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lscript_byteformat.h 3 | * @brief Shared code between compiler and assembler and LSL 4 | * 5 | * $LicenseInfo:firstyear=2002&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #ifndef LL_LSCRIPT_BYTEFORMAT_H 28 | #define LL_LSCRIPT_BYTEFORMAT_H 29 | 30 | // Data shared between compiler/assembler and lscript execution code 31 | 32 | #include "stdtypes.h" 33 | 34 | const S32 LSL2_VERSION_NUMBER = 0x0200; 35 | const S32 LSL2_VERSION1_END_NUMBER = 0x0101; 36 | const S32 LSL2_VERSION2_START_NUMBER = 0x0200; 37 | 38 | const S32 LSL2_MAJOR_VERSION_ONE = 1; 39 | const S32 LSL2_MAJOR_VERSION_TWO = 2; 40 | const S32 LSL2_CURRENT_MAJOR_VERSION = LSL2_MAJOR_VERSION_TWO; 41 | 42 | const S32 TOP_OF_MEMORY = 16384; 43 | 44 | typedef enum e_lscript_registers 45 | { 46 | LREG_INVALID, 47 | LREG_IP, // instruction pointer 48 | LREG_VN, // version number 49 | LREG_BP, // base pointer - what local variables are referenced from 50 | LREG_SP, // stack pointer - where the top of the stack is 51 | LREG_HR, // heap register - where in memory does the heap start 52 | LREG_HP, // heap pointer - where is the top of the heap? 53 | LREG_CS, // current state - what state are we currently in? 54 | LREG_NS, // next state - what state are we currently in? 55 | LREG_CE, // current events - what events are waiting to be handled? 56 | LREG_IE, // in event - which event handler are we currently in? 57 | LREG_ER, // event register - what events do we have active handlers for? 58 | LREG_FR, // fault register - which errors are currently active? 59 | LREG_SLR, // sleep register - are we sleeping? 60 | LREG_GVR, // global variable register - where do global variables start 61 | LREG_GFR, // global function register - where do global functions start 62 | LREG_SR, // state register - where do states start 63 | LREG_TM, // top of memory - where is the top of memory 64 | LREG_PR, // parameter register - data passed to script from launcher 65 | LREG_ESR, // energy supply register - how much energy do we have on board? 66 | LREG_NCE, // 64 bit current envents - what events are waiting to be handled? 67 | LREG_NIE, // 64 bit in event - which event handler are we currently in? 68 | LREG_NER, // 64 bit event register - what events do we have active handlers for? 69 | LREG_EOF 70 | } LSCRIPTRegisters; 71 | 72 | const S32 gLSCRIPTRegisterAddresses[LREG_EOF] = /* Flawfinder: ignore */ 73 | { 74 | 0, // LREG_INVALID 75 | 4, // LREG_IP 76 | 8, // LREG_VN 77 | 12, // LREG_BP 78 | 16, // LREG_SP 79 | 20, // LREG_HR 80 | 24, // LREG_HP 81 | 28, // LREG_CS 82 | 32, // LREG_NS 83 | 36, // LREG_CE 84 | 40, // LREG_IE 85 | 44, // LREG_ER 86 | 48, // LREG_FR 87 | 52, // LREG_SLR 88 | 56, // LREG_GVR 89 | 60, // LREG_GFR 90 | 72, // LREG_SR 91 | 0, // LREG_TM 92 | 64, // LREG_PR 93 | 68, // LREG_ESR 94 | 76, // LREG_NCE 95 | 84, // LREG_NIE 96 | 92, // LREG_NER 97 | }; 98 | 99 | const char * const gLSCRIPTRegisterNames[LREG_EOF] = 100 | { 101 | "INVALID", // LREG_INVALID 102 | "IP", // LREG_IP 103 | "VN", // LREG_VN 104 | "BP", // LREG_BP 105 | "SP", // LREG_SP 106 | "HR", // LREG_HR 107 | "HP", // LREG_HP 108 | "CS", // LREG_CS 109 | "NS", // LREG_NS 110 | "CE", // LREG_CE 111 | "IE", // LREG_IE 112 | "ER", // LREG_ER 113 | "FR", // LREG_FR 114 | "SLR", // LREG_SLR 115 | "GVR", // LREG_GVR 116 | "GFR", // LREG_GFR 117 | "SR", // LREG_SR 118 | "TM", // LREG_TM 119 | "PR", // LREG_PR 120 | "ESR", // LREG_ESR 121 | "NCE", // LREG_NCE 122 | "NIE", // LREG_NIE 123 | "NER", // LREG_NER 124 | }; 125 | 126 | typedef enum e_lscript_op_codes 127 | { 128 | LOPC_INVALID, 129 | LOPC_NOOP, 130 | LOPC_POP, 131 | LOPC_POPS, 132 | LOPC_POPL, 133 | LOPC_POPV, 134 | LOPC_POPQ, 135 | LOPC_POPARG, 136 | LOPC_POPIP, 137 | LOPC_POPBP, 138 | LOPC_POPSP, 139 | LOPC_POPSLR, 140 | LOPC_DUP, 141 | LOPC_DUPS, 142 | LOPC_DUPL, 143 | LOPC_DUPV, 144 | LOPC_DUPQ, 145 | LOPC_STORE, 146 | LOPC_STORES, 147 | LOPC_STOREL, 148 | LOPC_STOREV, 149 | LOPC_STOREQ, 150 | LOPC_STOREG, 151 | LOPC_STOREGS, 152 | LOPC_STOREGL, 153 | LOPC_STOREGV, 154 | LOPC_STOREGQ, 155 | LOPC_LOADP, 156 | LOPC_LOADSP, 157 | LOPC_LOADLP, 158 | LOPC_LOADVP, 159 | LOPC_LOADQP, 160 | LOPC_LOADGP, 161 | LOPC_LOADGLP, 162 | LOPC_LOADGSP, 163 | LOPC_LOADGVP, 164 | LOPC_LOADGQP, 165 | LOPC_PUSH, 166 | LOPC_PUSHS, 167 | LOPC_PUSHL, 168 | LOPC_PUSHV, 169 | LOPC_PUSHQ, 170 | LOPC_PUSHG, 171 | LOPC_PUSHGS, 172 | LOPC_PUSHGL, 173 | LOPC_PUSHGV, 174 | LOPC_PUSHGQ, 175 | LOPC_PUSHIP, 176 | LOPC_PUSHBP, 177 | LOPC_PUSHSP, 178 | LOPC_PUSHARGB, 179 | LOPC_PUSHARGI, 180 | LOPC_PUSHARGF, 181 | LOPC_PUSHARGS, 182 | LOPC_PUSHARGV, 183 | LOPC_PUSHARGQ, 184 | LOPC_PUSHE, 185 | LOPC_PUSHEV, 186 | LOPC_PUSHEQ, 187 | LOPC_PUSHARGE, 188 | LOPC_ADD, 189 | LOPC_SUB, 190 | LOPC_MUL, 191 | LOPC_DIV, 192 | LOPC_MOD, 193 | LOPC_EQ, 194 | LOPC_NEQ, 195 | LOPC_LEQ, 196 | LOPC_GEQ, 197 | LOPC_LESS, 198 | LOPC_GREATER, 199 | LOPC_BITAND, 200 | LOPC_BITOR, 201 | LOPC_BITXOR, 202 | LOPC_BOOLAND, 203 | LOPC_BOOLOR, 204 | LOPC_NEG, 205 | LOPC_BITNOT, 206 | LOPC_BOOLNOT, 207 | LOPC_JUMP, 208 | LOPC_JUMPIF, 209 | LOPC_JUMPNIF, 210 | LOPC_STATE, 211 | LOPC_CALL, 212 | LOPC_RETURN, 213 | LOPC_CAST, 214 | LOPC_STACKTOS, 215 | LOPC_STACKTOL, 216 | LOPC_PRINT, 217 | LOPC_CALLLIB, 218 | LOPC_CALLLIB_TWO_BYTE, 219 | LOPC_SHL, 220 | LOPC_SHR, 221 | LOPC_EOF 222 | } LSCRIPTOpCodesEnum; 223 | 224 | const U8 LSCRIPTOpCodes[LOPC_EOF] = 225 | { 226 | 0x00, // LOPC_INVALID 227 | 0x00, // LOPC_NOOP 228 | 0x01, // LOPC_POP 229 | 0x02, // LOPC_POPS 230 | 0x03, // LOPC_POPL 231 | 0x04, // LOPC_POPV 232 | 0x05, // LOPC_POPQ 233 | 0x06, // LOPC_POPARG 234 | 0x07, // LOPC_POPIP 235 | 0x08, // LOPC_POPBP 236 | 0x09, // LOPC_POPSP 237 | 0x0a, // LOPC_POPSLR 238 | 0x20, // LOPC_DUP 239 | 0x21, // LOPC_DUPS 240 | 0x22, // LOPC_DUPL 241 | 0x23, // LOPC_DUPV 242 | 0x24, // LOPC_DUPQ 243 | 0x30, // LOPC_STORE 244 | 0x31, // LOPC_STORES 245 | 0x32, // LOPC_STOREL 246 | 0x33, // LOPC_STOREV 247 | 0x34, // LOPC_STOREQ 248 | 0x35, // LOPC_STOREG 249 | 0x36, // LOPC_STOREGS 250 | 0x37, // LOPC_STOREGL 251 | 0x38, // LOPC_STOREGV 252 | 0x39, // LOPC_STOREGQ 253 | 0x3a, // LOPC_LOADP 254 | 0x3b, // LOPC_LOADSP 255 | 0x3c, // LOPC_LOADLP 256 | 0x3d, // LOPC_LOADVP 257 | 0x3e, // LOPC_LOADQP 258 | 0x3f, // LOPC_LOADGP 259 | 0x40, // LOPC_LOADGSP 260 | 0x41, // LOPC_LOADGLP 261 | 0x42, // LOPC_LOADGVP 262 | 0x43, // LOPC_LOADGQP 263 | 0x50, // LOPC_PUSH 264 | 0x51, // LOPC_PUSHS 265 | 0x52, // LOPC_PUSHL 266 | 0x53, // LOPC_PUSHV 267 | 0x54, // LOPC_PUSHQ 268 | 0x55, // LOPC_PUSHG 269 | 0x56, // LOPC_PUSHGS 270 | 0x57, // LOPC_PUSHGL 271 | 0x58, // LOPC_PUSHGV 272 | 0x59, // LOPC_PUSHGQ 273 | 0x5a, // LOPC_PUSHIP 274 | 0x5b, // LOPC_PUSHBP 275 | 0x5c, // LOPC_PUSHSP 276 | 0x5d, // LOPC_PUSHARGB 277 | 0x5e, // LOPC_PUSHARGI 278 | 0x5f, // LOPC_PUSHARGF 279 | 0x60, // LOPC_PUSHARGS 280 | 0x61, // LOPC_PUSHARGV 281 | 0x62, // LOPC_PUSHARGQ 282 | 0x63, // LOPC_PUSHE 283 | 0x64, // LOPC_PUSHEV 284 | 0x65, // LOPC_PUSHEQ 285 | 0x66, // LOPC_PUSHARGE 286 | 0x70, // LOPC_ADD 287 | 0x71, // LOPC_SUB 288 | 0x72, // LOPC_MUL 289 | 0x73, // LOPC_DIV 290 | 0x74, // LOPC_MOD 291 | 0x75, // LOPC_EQ 292 | 0x76, // LOPC_NEQ 293 | 0x77, // LOPC_LEQ 294 | 0x78, // LOPC_GEQ 295 | 0x79, // LOPC_LESS 296 | 0x7a, // LOPC_GREATER 297 | 0x7b, // LOPC_BITAND 298 | 0x7c, // LOPC_BITOR 299 | 0x7d, // LOPC_BITXOR 300 | 0x7e, // LOPC_BOOLAND 301 | 0x7f, // LOPC_BOOLOR 302 | 0x80, // LOPC_NEG 303 | 0x81, // LOPC_BITNOT 304 | 0x82, // LOPC_BOOLNOT 305 | 0x90, // LOPC_JUMP 306 | 0x91, // LOPC_JUMPIF 307 | 0x92, // LOPC_JUMPNIF 308 | 0x93, // LOPC_STATE 309 | 0x94, // LOPC_CALL 310 | 0x95, // LOPC_RETURN 311 | 0xa0, // LOPC_CAST 312 | 0xb0, // LOPC_STACKTOS 313 | 0xb1, // LOPC_STACKTOL 314 | 0xc0, // LOPC_PRINT 315 | 0xd0, // LOPC_CALLLIB 316 | 0xd1, // LOPC_CALLLIB_TWO_BYTE 317 | 0xe0, // LOPC_SHL 318 | 0xe1 // LOPC_SHR 319 | }; 320 | 321 | typedef enum e_lscript_state_event_type 322 | { 323 | LSTT_NULL, 324 | LSTT_STATE_ENTRY, 325 | LSTT_STATE_EXIT, 326 | LSTT_TOUCH_START, 327 | LSTT_TOUCH, 328 | LSTT_TOUCH_END, 329 | LSTT_COLLISION_START, 330 | LSTT_COLLISION, 331 | LSTT_COLLISION_END, 332 | LSTT_LAND_COLLISION_START, 333 | LSTT_LAND_COLLISION, 334 | LSTT_LAND_COLLISION_END, 335 | LSTT_TIMER, 336 | LSTT_CHAT, 337 | LSTT_REZ, 338 | LSTT_SENSOR, 339 | LSTT_NO_SENSOR, 340 | LSTT_CONTROL, 341 | LSTT_MONEY, 342 | LSTT_EMAIL, 343 | LSTT_AT_TARGET, 344 | LSTT_NOT_AT_TARGET, 345 | LSTT_AT_ROT_TARGET, 346 | LSTT_NOT_AT_ROT_TARGET, 347 | LSTT_RTPERMISSIONS, 348 | LSTT_INVENTORY, 349 | LSTT_ATTACH, 350 | LSTT_DATASERVER, 351 | LSTT_LINK_MESSAGE, 352 | LSTT_MOVING_START, 353 | LSTT_MOVING_END, 354 | LSTT_OBJECT_REZ, 355 | LSTT_REMOTE_DATA, 356 | LSTT_HTTP_RESPONSE, 357 | LSTT_HTTP_REQUEST, 358 | LSTT_TRANSACTION_RESULT, 359 | LSTT_PATH_UPDATE, 360 | LSTT_EXPERIENCE_PERMISSIONS, 361 | LSTT_EXPERIENCE_PERMISSIONS_DENIED, 362 | LSTT_EOF, 363 | 364 | LSTT_STATE_BEGIN = LSTT_STATE_ENTRY, 365 | LSTT_STATE_END = LSTT_EOF 366 | } LSCRIPTStateEventType; 367 | 368 | const U64 LSCRIPTStateBitField[LSTT_EOF] = 369 | { 370 | 0x0000000000000000, // LSTT_NULL 371 | 0x0000000000000001, // LSTT_STATE_ENTRY 372 | 0x0000000000000002, // LSTT_STATE_EXIT 373 | 0x0000000000000004, // LSTT_TOUCH_START 374 | 0x0000000000000008, // LSTT_TOUCH 375 | 0x0000000000000010, // LSTT_TOUCH_END 376 | 0x0000000000000020, // LSTT_COLLISION_START 377 | 0x0000000000000040, // LSTT_COLLISION 378 | 0x0000000000000080, // LSTT_COLLISION_END 379 | 0x0000000000000100, // LSTT_LAND_COLLISION_START 380 | 0x0000000000000200, // LSTT_LAND_COLLISION 381 | 0x0000000000000400, // LSTT_LAND_COLLISION_END 382 | 0x0000000000000800, // LSTT_TIMER 383 | 0x0000000000001000, // LSTT_CHAT 384 | 0x0000000000002000, // LSTT_REZ 385 | 0x0000000000004000, // LSTT_SENSOR 386 | 0x0000000000008000, // LSTT_NO_SENSOR 387 | 0x0000000000010000, // LSTT_CONTROL 388 | 0x0000000000020000, // LSTT_MONEY 389 | 0x0000000000040000, // LSTT_EMAIL 390 | 0x0000000000080000, // LSTT_AT_TARGET 391 | 0x0000000000100000, // LSTT_NOT_AT_TARGET 392 | 0x0000000000200000, // LSTT_AT_ROT_TARGET 393 | 0x0000000000400000, // LSTT_NOT_AT_ROT_TARGET 394 | 0x0000000000800000, // LSTT_RTPERMISSIONS 395 | 0x0000000001000000, // LSTT_INVENTORY 396 | 0x0000000002000000, // LSTT_ATTACH 397 | 0x0000000004000000, // LSTT_DATASERVER 398 | 0x0000000008000000, // LSTT_LINK_MESSAGE 399 | 0x0000000010000000, // LSTT_MOVING_START 400 | 0x0000000020000000, // LSTT_MOVING_END 401 | 0x0000000040000000, // LSTT_OBJECT_REZ 402 | 0x0000000080000000, // LSTT_REMOTE_DATA 403 | 0x0000000100000000LL, // LSTT_HTTP_RESPOSE 404 | 0x0000000200000000LL, // LSTT_HTTP_REQUEST 405 | 0x0000000400000000LL, // LSTT_TRANSACTION_RESULT 406 | 0x0000000800000000LL, // LSTT_PATH_UPDATE 407 | 0x0000001000000000LL, // LSTT_EXPERIENCE_PERMISSIONS 408 | 0x0000002000000000LL, // LSTT_EXPERIENCE_PERMISSIONS_DENIED 409 | }; 410 | 411 | inline S32 get_event_handler_jump_position(U64 bit_field, LSCRIPTStateEventType type) 412 | { 413 | S32 count = 0, position = LSTT_STATE_ENTRY; 414 | while (position < type) 415 | { 416 | if (bit_field & 0x1) 417 | { 418 | count++; 419 | } 420 | bit_field >>= 1; 421 | position++; 422 | } 423 | return count; 424 | } 425 | 426 | inline S32 get_number_of_event_handlers(U64 bit_field) 427 | { 428 | S32 count = 0, position = 0; 429 | while (position < LSTT_EOF) 430 | { 431 | if (bit_field & 0x1) 432 | { 433 | count++; 434 | } 435 | bit_field >>= 1; 436 | position++; 437 | } 438 | return count; 439 | } 440 | 441 | typedef enum e_lscript_types 442 | { 443 | LST_NULL, 444 | LST_INTEGER, 445 | LST_FLOATINGPOINT, 446 | LST_STRING, 447 | LST_KEY, 448 | LST_VECTOR, 449 | LST_QUATERNION, 450 | LST_LIST, 451 | LST_UNDEFINED, 452 | LST_EOF 453 | } LSCRIPTType; 454 | 455 | const U8 LSCRIPTTypeByte[LST_EOF] = 456 | { 457 | LST_NULL, 458 | LST_INTEGER, 459 | LST_FLOATINGPOINT, 460 | LST_STRING, 461 | LST_KEY, 462 | LST_VECTOR, 463 | LST_QUATERNION, 464 | LST_LIST, 465 | LST_NULL, 466 | }; 467 | 468 | const U8 LSCRIPTTypeHi4Bits[LST_EOF] = 469 | { 470 | LST_NULL, 471 | LST_INTEGER << 4, 472 | LST_FLOATINGPOINT << 4, 473 | LST_STRING << 4, 474 | LST_KEY << 4, 475 | LST_VECTOR << 4, 476 | LST_QUATERNION << 4, 477 | LST_LIST << 4, 478 | LST_UNDEFINED << 4, 479 | }; 480 | 481 | const char * const LSCRIPTTypeNames[LST_EOF] = /*Flawfinder: ignore*/ 482 | { 483 | "VOID", 484 | "integer", 485 | "float", 486 | "string", 487 | "key", 488 | "vector", 489 | "quaternion", 490 | "list", 491 | "invalid" 492 | }; 493 | 494 | const S32 LSCRIPTDataSize[LST_EOF] = 495 | { 496 | 0, // VOID 497 | 4, // integer 498 | 4, // float 499 | 4, // string 500 | 4, // key 501 | 12, // vector 502 | 16, // quaternion 503 | 4, // list 504 | 0 // invalid 505 | }; 506 | 507 | 508 | typedef enum e_lscript_runtime_faults 509 | { 510 | LSRF_INVALID, 511 | LSRF_MATH, 512 | LSRF_STACK_HEAP_COLLISION, 513 | LSRF_BOUND_CHECK_ERROR, 514 | LSRF_HEAP_ERROR, 515 | LSRF_VERSION_MISMATCH, 516 | LSRF_MISSING_INVENTORY, 517 | LSRF_SANDBOX, 518 | LSRF_CHAT_OVERRUN, 519 | LSRF_TOO_MANY_LISTENS, 520 | LSRF_NESTING_LISTS, 521 | LSRF_CLI, 522 | LSRF_EOF 523 | } LSCRIPTRunTimeFaults; 524 | 525 | extern const char* LSCRIPTRunTimeFaultStrings[LSRF_EOF]; /*Flawfinder: ignore*/ 526 | 527 | typedef enum e_lscript_runtime_permissions 528 | { 529 | SCRIPT_PERMISSION_DEBIT, 530 | SCRIPT_PERMISSION_TAKE_CONTROLS, 531 | SCRIPT_PERMISSION_REMAP_CONTROLS, 532 | SCRIPT_PERMISSION_TRIGGER_ANIMATION, 533 | SCRIPT_PERMISSION_ATTACH, 534 | SCRIPT_PERMISSION_RELEASE_OWNERSHIP, 535 | SCRIPT_PERMISSION_CHANGE_LINKS, 536 | SCRIPT_PERMISSION_CHANGE_JOINTS, 537 | SCRIPT_PERMISSION_CHANGE_PERMISSIONS, 538 | SCRIPT_PERMISSION_TRACK_CAMERA, 539 | SCRIPT_PERMISSION_CONTROL_CAMERA, 540 | SCRIPT_PERMISSION_TELEPORT, 541 | SCRIPT_PERMISSION_EXPERIENCE, 542 | SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT, 543 | SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS, 544 | SCRIPT_PERMISSION_RETURN_OBJECTS, 545 | SCRIPT_PERMISSION_EOF 546 | } LSCRIPTRunTimePermissions; 547 | 548 | const U32 LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_EOF] = 549 | { 550 | (0x1 << 1), // SCRIPT_PERMISSION_DEBIT, 551 | (0x1 << 2), // SCRIPT_PERMISSION_TAKE_CONTROLS, 552 | (0x1 << 3), // SCRIPT_PERMISSION_REMAP_CONTROLS, 553 | (0x1 << 4), // SCRIPT_PERMISSION_TRIGGER_ANIMATION, 554 | (0x1 << 5), // SCRIPT_PERMISSION_ATTACH, 555 | (0x1 << 6), // SCRIPT_PERMISSION_RELEASE_OWNERSHIP, 556 | (0x1 << 7), // SCRIPT_PERMISSION_CHANGE_LINKS, 557 | (0x1 << 8), // SCRIPT_PERMISSION_CHANGE_JOINTS, 558 | (0x1 << 9), // SCRIPT_PERMISSION_CHANGE_PERMISSIONS 559 | (0x1 << 10),// SCRIPT_PERMISSION_TRACK_CAMERA 560 | (0x1 << 11),// SCRIPT_PERMISSION_CONTROL_CAMERA 561 | (0x1 << 12),// SCRIPT_PERMISSION_TELEPORT 562 | (0x1 << 13),// SCRIPT_PERMISSION_EXPERIENCE 563 | (0x1 << 14),// SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT 564 | (0x1 << 15),// SCRIPT_PERMISSION_OVERRIDE_ANIMATIONS 565 | (0x1 << 16),// SCRIPT_PERMISSION_RETURN_OBJECTS 566 | }; 567 | 568 | // http_request string constants 569 | extern const char* URL_REQUEST_GRANTED; 570 | extern const char* URL_REQUEST_DENIED; 571 | extern const U64 LSL_HTTP_REQUEST_TIMEOUT_USEC; 572 | 573 | #endif 574 | 575 | -------------------------------------------------------------------------------- /llcommon/llstl.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file llstl.h 3 | * @brief helper object & functions for use with the stl. 4 | * 5 | * $LicenseInfo:firstyear=2003&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #ifndef LL_LLSTL_H 28 | #define LL_LLSTL_H 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | // Use to compare the first element only of a pair 39 | // e.g. typedef std::set, compare_pair > some_pair_set_t; 40 | template 41 | struct compare_pair_first 42 | { 43 | bool operator()(const std::pair& a, const std::pair& b) const 44 | { 45 | return a.first < b.first; 46 | } 47 | }; 48 | 49 | template 50 | struct compare_pair_greater 51 | { 52 | bool operator()(const std::pair& a, const std::pair& b) const 53 | { 54 | if (!(a.first < b.first)) 55 | return true; 56 | else if (!(b.first < a.first)) 57 | return false; 58 | else 59 | return !(a.second < b.second); 60 | } 61 | }; 62 | 63 | // Use to compare the contents of two pointers (e.g. std::string*) 64 | template 65 | struct compare_pointer_contents 66 | { 67 | typedef const T* Tptr; 68 | bool operator()(const Tptr& a, const Tptr& b) const 69 | { 70 | return *a < *b; 71 | } 72 | }; 73 | 74 | // DeletePointer is a simple helper for deleting all pointers in a container. 75 | // The general form is: 76 | // 77 | // std::for_each(cont.begin(), cont.end(), DeletePointer()); 78 | // somemap.clear(); 79 | // 80 | // Don't forget to clear()! 81 | 82 | struct DeletePointer 83 | { 84 | template void operator()(T* ptr) const 85 | { 86 | delete ptr; 87 | } 88 | }; 89 | struct DeletePointerArray 90 | { 91 | template void operator()(T* ptr) const 92 | { 93 | delete[] ptr; 94 | } 95 | }; 96 | 97 | // DeletePairedPointer is a simple helper for deleting all pointers in a map. 98 | // The general form is: 99 | // 100 | // std::for_each(somemap.begin(), somemap.end(), DeletePairedPointer()); 101 | 102 | struct DeletePairedPointer 103 | { 104 | template void operator()(T &ptr) const 105 | { 106 | delete ptr.second; 107 | ptr.second = NULL; 108 | } 109 | }; 110 | struct DeletePairedPointerArray 111 | { 112 | template void operator()(T &ptr) const 113 | { 114 | delete[] ptr.second; 115 | ptr.second = NULL; 116 | } 117 | }; 118 | 119 | 120 | // Alternate version of the above so that has a more cumbersome 121 | // syntax, but it can be used with compositional functors. 122 | // NOTE: The functor retuns a bool because msdev bombs during the 123 | // composition if you return void. Once we upgrade to a newer 124 | // compiler, the second unary_function template parameter can be set 125 | // to void. 126 | // 127 | // Here's a snippit showing how you use this object: 128 | // 129 | // typedef std::map map_type; 130 | // map_type widget_map; 131 | // ... // add elements 132 | // // delete them all 133 | // for_each(widget_map.begin(), 134 | // widget_map.end(), 135 | // llcompose1(DeletePointerFunctor(), 136 | // llselect2nd())); 137 | 138 | template 139 | struct DeletePointerFunctor : public std::unary_function 140 | { 141 | bool operator()(T* ptr) const 142 | { 143 | delete ptr; 144 | return true; 145 | } 146 | }; 147 | 148 | // See notes about DeleteArray for why you should consider avoiding this. 149 | template 150 | struct DeleteArrayFunctor : public std::unary_function 151 | { 152 | bool operator()(T* ptr) const 153 | { 154 | delete[] ptr; 155 | return true; 156 | } 157 | }; 158 | 159 | // CopyNewPointer is a simple helper which accepts a pointer, and 160 | // returns a new pointer built with the copy constructor. Example: 161 | // 162 | // transform(in.begin(), in.end(), out.end(), CopyNewPointer()); 163 | 164 | struct CopyNewPointer 165 | { 166 | template T* operator()(const T* ptr) const 167 | { 168 | return new T(*ptr); 169 | } 170 | }; 171 | 172 | // Simple function to help with finding pointers in maps. 173 | // For example: 174 | // typedef map_t; 175 | // std::map foo; 176 | // foo[18] = "there"; 177 | // foo[2] = "hello"; 178 | // const char* bar = get_ptr_in_map(foo, 2); // bar -> "hello" 179 | // const char* baz = get_ptr_in_map(foo, 3); // baz == NULL 180 | template 181 | inline T* get_ptr_in_map(const std::map& inmap, const K& key) 182 | { 183 | // Typedef here avoids warnings because of new c++ naming rules. 184 | typedef typename std::map::const_iterator map_iter; 185 | map_iter iter = inmap.find(key); 186 | if(iter == inmap.end()) 187 | { 188 | return NULL; 189 | } 190 | else 191 | { 192 | return iter->second; 193 | } 194 | }; 195 | 196 | // helper function which returns true if key is in inmap. 197 | template 198 | inline bool is_in_map(const std::map& inmap, const K& key) 199 | { 200 | typedef typename std::map::const_iterator map_iter; 201 | if(inmap.find(key) == inmap.end()) 202 | { 203 | return false; 204 | } 205 | else 206 | { 207 | return true; 208 | } 209 | } 210 | 211 | // Similar to get_ptr_in_map, but for any type with a valid T(0) constructor. 212 | // To replace LLSkipMap getIfThere, use: 213 | // get_if_there(map, key, 0) 214 | // WARNING: Make sure default_value (generally 0) is not a valid map entry! 215 | template 216 | inline T get_if_there(const std::map& inmap, const K& key, T default_value) 217 | { 218 | // Typedef here avoids warnings because of new c++ naming rules. 219 | typedef typename std::map::const_iterator map_iter; 220 | map_iter iter = inmap.find(key); 221 | if(iter == inmap.end()) 222 | { 223 | return default_value; 224 | } 225 | else 226 | { 227 | return iter->second; 228 | } 229 | }; 230 | 231 | // Useful for replacing the removeObj() functionality of LLDynamicArray 232 | // Example: 233 | // for (std::vector::iterator iter = mList.begin(); iter != mList.end(); ) 234 | // { 235 | // if ((*iter)->isMarkedForRemoval()) 236 | // iter = vector_replace_with_last(mList, iter); 237 | // else 238 | // ++iter; 239 | // } 240 | template 241 | inline Iter vector_replace_with_last(std::vector& invec, Iter iter) 242 | { 243 | typename std::vector::iterator last = invec.end(); --last; 244 | if (iter == invec.end()) 245 | { 246 | return iter; 247 | } 248 | else if (iter == last) 249 | { 250 | invec.pop_back(); 251 | return invec.end(); 252 | } 253 | else 254 | { 255 | *iter = *last; 256 | invec.pop_back(); 257 | return iter; 258 | } 259 | }; 260 | 261 | // Useful for replacing the removeObj() functionality of LLDynamicArray 262 | // Example: 263 | // vector_replace_with_last(mList, x); 264 | template 265 | inline bool vector_replace_with_last(std::vector& invec, const T& val) 266 | { 267 | typename std::vector::iterator iter = std::find(invec.begin(), invec.end(), val); 268 | if (iter != invec.end()) 269 | { 270 | typename std::vector::iterator last = invec.end(); --last; 271 | *iter = *last; 272 | invec.pop_back(); 273 | return true; 274 | } 275 | return false; 276 | } 277 | 278 | // Append N elements to the vector and return a pointer to the first new element. 279 | template 280 | inline T* vector_append(std::vector& invec, S32 N) 281 | { 282 | U32 sz = invec.size(); 283 | invec.resize(sz+N); 284 | return &(invec[sz]); 285 | } 286 | 287 | // call function f to n members starting at first. similar to std::for_each 288 | template 289 | Function ll_for_n(InputIter first, Size n, Function f) 290 | { 291 | for ( ; n > 0; --n, ++first) 292 | f(*first); 293 | return f; 294 | } 295 | 296 | // copy first to result n times, incrementing each as we go 297 | template 298 | OutputIter ll_copy_n(InputIter first, Size n, OutputIter result) 299 | { 300 | for ( ; n > 0; --n, ++result, ++first) 301 | *result = *first; 302 | return result; 303 | } 304 | 305 | // set *result = op(*f) for n elements of f 306 | template 307 | OutputIter ll_transform_n( 308 | InputIter first, 309 | Size n, 310 | OutputIter result, 311 | UnaryOp op) 312 | { 313 | for ( ; n > 0; --n, ++result, ++first) 314 | *result = op(*first); 315 | return result; 316 | } 317 | 318 | 319 | 320 | /* 321 | * 322 | * Copyright (c) 1994 323 | * Hewlett-Packard Company 324 | * 325 | * Permission to use, copy, modify, distribute and sell this software 326 | * and its documentation for any purpose is hereby granted without fee, 327 | * provided that the above copyright notice appear in all copies and 328 | * that both that copyright notice and this permission notice appear 329 | * in supporting documentation. Hewlett-Packard Company makes no 330 | * representations about the suitability of this software for any 331 | * purpose. It is provided "as is" without express or implied warranty. 332 | * 333 | * 334 | * Copyright (c) 1996-1998 335 | * Silicon Graphics Computer Systems, Inc. 336 | * 337 | * Permission to use, copy, modify, distribute and sell this software 338 | * and its documentation for any purpose is hereby granted without fee, 339 | * provided that the above copyright notice appear in all copies and 340 | * that both that copyright notice and this permission notice appear 341 | * in supporting documentation. Silicon Graphics makes no 342 | * representations about the suitability of this software for any 343 | * purpose. It is provided "as is" without express or implied warranty. 344 | */ 345 | 346 | 347 | // helper to deal with the fact that MSDev does not package 348 | // select... with the stl. Look up usage on the sgi website. 349 | 350 | template 351 | struct _LLSelect1st : public std::unary_function<_Pair, typename _Pair::first_type> { 352 | const typename _Pair::first_type& operator()(const _Pair& __x) const { 353 | return __x.first; 354 | } 355 | }; 356 | 357 | template 358 | struct _LLSelect2nd : public std::unary_function<_Pair, typename _Pair::second_type> 359 | { 360 | const typename _Pair::second_type& operator()(const _Pair& __x) const { 361 | return __x.second; 362 | } 363 | }; 364 | 365 | template struct llselect1st : public _LLSelect1st<_Pair> {}; 366 | template struct llselect2nd : public _LLSelect2nd<_Pair> {}; 367 | 368 | // helper to deal with the fact that MSDev does not package 369 | // compose... with the stl. Look up usage on the sgi website. 370 | 371 | template 372 | class ll_unary_compose : 373 | public std::unary_function 375 | { 376 | protected: 377 | _Operation1 __op1; 378 | _Operation2 __op2; 379 | public: 380 | ll_unary_compose(const _Operation1& __x, const _Operation2& __y) 381 | : __op1(__x), __op2(__y) {} 382 | typename _Operation1::result_type 383 | operator()(const typename _Operation2::argument_type& __x) const { 384 | return __op1(__op2(__x)); 385 | } 386 | }; 387 | 388 | template 389 | inline ll_unary_compose<_Operation1,_Operation2> 390 | llcompose1(const _Operation1& __op1, const _Operation2& __op2) 391 | { 392 | return ll_unary_compose<_Operation1,_Operation2>(__op1, __op2); 393 | } 394 | 395 | template 396 | class ll_binary_compose 397 | : public std::unary_function { 399 | protected: 400 | _Operation1 _M_op1; 401 | _Operation2 _M_op2; 402 | _Operation3 _M_op3; 403 | public: 404 | ll_binary_compose(const _Operation1& __x, const _Operation2& __y, 405 | const _Operation3& __z) 406 | : _M_op1(__x), _M_op2(__y), _M_op3(__z) { } 407 | typename _Operation1::result_type 408 | operator()(const typename _Operation2::argument_type& __x) const { 409 | return _M_op1(_M_op2(__x), _M_op3(__x)); 410 | } 411 | }; 412 | 413 | template 414 | inline ll_binary_compose<_Operation1, _Operation2, _Operation3> 415 | llcompose2(const _Operation1& __op1, const _Operation2& __op2, 416 | const _Operation3& __op3) 417 | { 418 | return ll_binary_compose<_Operation1,_Operation2,_Operation3> 419 | (__op1, __op2, __op3); 420 | } 421 | 422 | // helpers to deal with the fact that MSDev does not package 423 | // bind... with the stl. Again, this is from sgi. 424 | template 425 | class llbinder1st : 426 | public std::unary_function { 428 | protected: 429 | _Operation op; 430 | typename _Operation::first_argument_type value; 431 | public: 432 | llbinder1st(const _Operation& __x, 433 | const typename _Operation::first_argument_type& __y) 434 | : op(__x), value(__y) {} 435 | typename _Operation::result_type 436 | operator()(const typename _Operation::second_argument_type& __x) const { 437 | return op(value, __x); 438 | } 439 | }; 440 | 441 | template 442 | inline llbinder1st<_Operation> 443 | llbind1st(const _Operation& __oper, const _Tp& __x) 444 | { 445 | typedef typename _Operation::first_argument_type _Arg1_type; 446 | return llbinder1st<_Operation>(__oper, _Arg1_type(__x)); 447 | } 448 | 449 | template 450 | class llbinder2nd 451 | : public std::unary_function { 453 | protected: 454 | _Operation op; 455 | typename _Operation::second_argument_type value; 456 | public: 457 | llbinder2nd(const _Operation& __x, 458 | const typename _Operation::second_argument_type& __y) 459 | : op(__x), value(__y) {} 460 | typename _Operation::result_type 461 | operator()(const typename _Operation::first_argument_type& __x) const { 462 | return op(__x, value); 463 | } 464 | }; 465 | 466 | template 467 | inline llbinder2nd<_Operation> 468 | llbind2nd(const _Operation& __oper, const _Tp& __x) 469 | { 470 | typedef typename _Operation::second_argument_type _Arg2_type; 471 | return llbinder2nd<_Operation>(__oper, _Arg2_type(__x)); 472 | } 473 | 474 | /** 475 | * Compare std::type_info* pointers a la std::less. We break this out as a 476 | * separate function for use in two different std::less specializations. 477 | */ 478 | inline 479 | bool before(const std::type_info* lhs, const std::type_info* rhs) 480 | { 481 | #if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) 482 | // If we're building on Linux with gcc, and it's either gcc 3.x or 483 | // 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on 484 | // Mac too, and some people build with gcc on Windows (cygwin or mingw). 485 | // On Linux, different load modules may produce different type_info* 486 | // pointers for the same type. Have to compare name strings to get good 487 | // results. 488 | return strcmp(lhs->name(), rhs->name()) < 0; 489 | #else // not Linux, or gcc 4.4+ 490 | // Just use before(), as we normally would 491 | return lhs->before(*rhs); 492 | #endif 493 | } 494 | 495 | /** 496 | * Specialize std::less to use std::type_info::before(). 497 | * See MAINT-1175. It is NEVER a good idea to directly compare std::type_info* 498 | * because, on Linux, you might get different std::type_info* pointers for the 499 | * same type (from different load modules)! 500 | */ 501 | namespace std 502 | { 503 | template <> 504 | struct less: 505 | public std::binary_function 506 | { 507 | bool operator()(const std::type_info* lhs, const std::type_info* rhs) const 508 | { 509 | return before(lhs, rhs); 510 | } 511 | }; 512 | 513 | template <> 514 | struct less: 515 | public std::binary_function 516 | { 517 | bool operator()(std::type_info* lhs, std::type_info* rhs) const 518 | { 519 | return before(lhs, rhs); 520 | } 521 | }; 522 | } // std 523 | 524 | #endif // LL_LLSTL_H 525 | -------------------------------------------------------------------------------- /lscript_typecheck.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lscript_typecheck.cpp 3 | * @brief typechecks script 4 | * 5 | * $LicenseInfo:firstyear=2002&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #include "linden_common.h" 28 | 29 | #include "lscript_tree.h" 30 | 31 | /* 32 | LScript automatic type casting 33 | 34 | LST_INTEGER -> LST_INTEGER 35 | 36 | LST_FLOATINGPOINT -> LST_FLOATINGPOINT 37 | LST_INTEGER -> LST_FLOATINGPOINT 38 | 39 | LST_FLOATINGPOINT -> LST_STRING 40 | LST_INTEGER -> LST_STRING 41 | LST_STRING -> LST_STRING 42 | LST_VECTOR -> LST_STRING 43 | LST_QUATERNION -> LST_STRING 44 | LST_LIST -> LST_STRING 45 | 46 | LST_VECTOR -> LST_VECTOR 47 | 48 | LST_QUATERNION -> LST_QUATERNION 49 | 50 | LST_FLOATINGPOINT -> LST_LIST 51 | LST_INTEGER -> LST_LIST 52 | LST_STRING -> LST_LIST 53 | LST_VECTOR -> LST_LIST 54 | LST_QUATERNION -> LST_LIST 55 | LST_LIST -> LST_LIST 56 | */ 57 | 58 | LSCRIPTType implicit_casts(LSCRIPTType left_side, LSCRIPTType right_side) 59 | { 60 | switch(left_side) 61 | { 62 | // shouldn't be doing an operation on void types 63 | case LST_NULL: 64 | switch(right_side) 65 | { 66 | case LST_NULL: 67 | return LST_NULL; 68 | default: 69 | return LST_UNDEFINED; 70 | } 71 | // shouldn't be doing an operation on undefined types 72 | case LST_UNDEFINED: 73 | return LST_UNDEFINED; 74 | // only integers can become integers 75 | case LST_INTEGER: 76 | switch(right_side) 77 | { 78 | case LST_INTEGER: 79 | return LST_INTEGER; 80 | default: 81 | return LST_UNDEFINED; 82 | } 83 | // only integers and floats can become floats 84 | case LST_FLOATINGPOINT: 85 | switch(right_side) 86 | { 87 | case LST_INTEGER: 88 | case LST_FLOATINGPOINT: 89 | return LST_FLOATINGPOINT; 90 | default: 91 | return LST_UNDEFINED; 92 | } 93 | // only strings and keys can become strings 94 | case LST_STRING: 95 | switch(right_side) 96 | { 97 | case LST_STRING: 98 | case LST_KEY: 99 | return LST_STRING; 100 | default: 101 | return LST_UNDEFINED; 102 | } 103 | // only strings and keys can become keys 104 | case LST_KEY: 105 | switch(right_side) 106 | { 107 | case LST_STRING: 108 | case LST_KEY: 109 | return LST_KEY; 110 | default: 111 | return LST_UNDEFINED; 112 | } 113 | // only vectors can become vectors 114 | case LST_VECTOR: 115 | switch(right_side) 116 | { 117 | case LST_VECTOR: 118 | return LST_VECTOR; 119 | default: 120 | return LST_UNDEFINED; 121 | } 122 | // only quaternions can become quaternions 123 | case LST_QUATERNION: 124 | switch(right_side) 125 | { 126 | case LST_QUATERNION: 127 | return LST_QUATERNION; 128 | default: 129 | return LST_UNDEFINED; 130 | } 131 | // only lists can become lists 132 | case LST_LIST: 133 | switch(right_side) 134 | { 135 | case LST_LIST: 136 | return LST_LIST; 137 | default: 138 | return LST_UNDEFINED; 139 | } 140 | default: 141 | return LST_UNDEFINED; 142 | } 143 | } 144 | 145 | LSCRIPTType promote(LSCRIPTType left_side, LSCRIPTType right_side) 146 | { 147 | LSCRIPTType type; 148 | type = implicit_casts(left_side, right_side); 149 | if (type != LST_UNDEFINED) 150 | { 151 | return type; 152 | } 153 | type = implicit_casts(right_side, left_side); 154 | if (type != LST_UNDEFINED) 155 | { 156 | return type; 157 | } 158 | return LST_UNDEFINED; 159 | } 160 | 161 | BOOL legal_assignment(LSCRIPTType left_side, LSCRIPTType right_side) 162 | { 163 | // this is to prevent cascading errors 164 | if ( (left_side == LST_UNDEFINED) 165 | ||(right_side == LST_UNDEFINED)) 166 | { 167 | return TRUE; 168 | } 169 | 170 | if (implicit_casts(left_side, right_side) != LST_UNDEFINED) 171 | { 172 | return TRUE; 173 | } 174 | else 175 | { 176 | return FALSE; 177 | } 178 | } 179 | 180 | BOOL legal_casts(LSCRIPTType cast, LSCRIPTType base) 181 | { 182 | switch(base) 183 | { 184 | // shouldn't be doing an operation on void types 185 | case LST_NULL: 186 | return FALSE; 187 | // shouldn't be doing an operation on undefined types 188 | case LST_UNDEFINED: 189 | return FALSE; 190 | case LST_INTEGER: 191 | switch(cast) 192 | { 193 | case LST_INTEGER: 194 | case LST_FLOATINGPOINT: 195 | case LST_STRING: 196 | case LST_LIST: 197 | return TRUE; 198 | break; 199 | default: 200 | return FALSE; 201 | break; 202 | } 203 | break; 204 | case LST_FLOATINGPOINT: 205 | switch(cast) 206 | { 207 | case LST_INTEGER: 208 | case LST_FLOATINGPOINT: 209 | case LST_STRING: 210 | case LST_LIST: 211 | return TRUE; 212 | break; 213 | default: 214 | return FALSE; 215 | break; 216 | } 217 | break; 218 | case LST_STRING: 219 | switch(cast) 220 | { 221 | case LST_INTEGER: 222 | case LST_FLOATINGPOINT: 223 | case LST_STRING: 224 | case LST_KEY: 225 | case LST_VECTOR: 226 | case LST_QUATERNION: 227 | case LST_LIST: 228 | return TRUE; 229 | break; 230 | default: 231 | return FALSE; 232 | break; 233 | } 234 | break; 235 | case LST_KEY: 236 | switch(cast) 237 | { 238 | case LST_STRING: 239 | case LST_KEY: 240 | case LST_LIST: 241 | return TRUE; 242 | break; 243 | default: 244 | return FALSE; 245 | break; 246 | } 247 | break; 248 | case LST_VECTOR: 249 | switch(cast) 250 | { 251 | case LST_VECTOR: 252 | case LST_STRING: 253 | case LST_LIST: 254 | return TRUE; 255 | break; 256 | default: 257 | return FALSE; 258 | break; 259 | } 260 | break; 261 | case LST_QUATERNION: 262 | switch(cast) 263 | { 264 | case LST_QUATERNION: 265 | case LST_STRING: 266 | case LST_LIST: 267 | return TRUE; 268 | break; 269 | default: 270 | return FALSE; 271 | break; 272 | } 273 | break; 274 | // lists can only be cast to lists and strings 275 | case LST_LIST: 276 | switch(cast) 277 | { 278 | case LST_LIST: 279 | case LST_STRING: 280 | return TRUE; 281 | break; 282 | default: 283 | return FALSE; 284 | break; 285 | } 286 | break; 287 | default: 288 | return FALSE; 289 | break; 290 | } 291 | } 292 | 293 | LSCRIPTType gSupportedExpressionArray[LET_EOF][LST_EOF][LST_EOF]; 294 | 295 | void init_supported_expressions(void) 296 | { 297 | S32 i, j, k; 298 | // zero out, then set the ones that matter 299 | for (i = 0; i < LET_EOF; i++) 300 | { 301 | for (j = 0; j < LST_EOF; j++) 302 | { 303 | for (k = 0; k < LST_EOF; k++) 304 | { 305 | gSupportedExpressionArray[i][j][k] = LST_NULL; 306 | } 307 | } 308 | } 309 | 310 | // LET_ASSIGNMENT 311 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 312 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT; 313 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 314 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 315 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_STRING][LST_STRING] = LST_STRING; 316 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_KEY][LST_KEY] = LST_KEY; 317 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_VECTOR][LST_VECTOR] = LST_VECTOR; 318 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION; 319 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_INTEGER] = LST_LIST; 320 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_FLOATINGPOINT] = LST_LIST; 321 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_STRING] = LST_LIST; 322 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_KEY] = LST_LIST; 323 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_VECTOR] = LST_LIST; 324 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_QUATERNION] = LST_LIST; 325 | gSupportedExpressionArray[LET_ASSIGNMENT][LST_LIST][LST_LIST] = LST_LIST; 326 | 327 | // LET_ADD_ASSIGN 328 | gSupportedExpressionArray[LET_ADD_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 329 | gSupportedExpressionArray[LET_ADD_ASSIGN][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT; 330 | gSupportedExpressionArray[LET_ADD_ASSIGN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 331 | gSupportedExpressionArray[LET_ADD_ASSIGN][LST_STRING][LST_STRING] = LST_STRING; 332 | gSupportedExpressionArray[LET_ADD_ASSIGN][LST_VECTOR][LST_VECTOR] = LST_VECTOR; 333 | gSupportedExpressionArray[LET_ADD_ASSIGN][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION; 334 | gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_INTEGER] = LST_LIST; 335 | gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_FLOATINGPOINT] = LST_LIST; 336 | gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_STRING] = LST_LIST; 337 | gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_KEY] = LST_LIST; 338 | gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_VECTOR] = LST_LIST; 339 | gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_QUATERNION] = LST_LIST; 340 | gSupportedExpressionArray[LET_ADD_ASSIGN][LST_LIST][LST_LIST] = LST_LIST; 341 | 342 | // LET_SUB_ASSIGN 343 | gSupportedExpressionArray[LET_SUB_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 344 | gSupportedExpressionArray[LET_SUB_ASSIGN][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT; 345 | gSupportedExpressionArray[LET_SUB_ASSIGN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 346 | gSupportedExpressionArray[LET_SUB_ASSIGN][LST_VECTOR][LST_VECTOR] = LST_VECTOR; 347 | gSupportedExpressionArray[LET_SUB_ASSIGN][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION; 348 | 349 | // LET_MUL_ASSIGN 350 | gSupportedExpressionArray[LET_MUL_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 351 | gSupportedExpressionArray[LET_MUL_ASSIGN][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT; 352 | gSupportedExpressionArray[LET_MUL_ASSIGN][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 353 | gSupportedExpressionArray[LET_MUL_ASSIGN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 354 | gSupportedExpressionArray[LET_MUL_ASSIGN][LST_VECTOR][LST_INTEGER] = LST_VECTOR; 355 | //gSupportedExpressionArray[LET_MUL_ASSIGN][LST_INTEGER][LST_VECTOR] = LST_VECTOR; 356 | gSupportedExpressionArray[LET_MUL_ASSIGN][LST_VECTOR][LST_FLOATINGPOINT] = LST_VECTOR; 357 | //gSupportedExpressionArray[LET_MUL_ASSIGN][LST_FLOATINGPOINT][LST_VECTOR] = LST_VECTOR; 358 | //gSupportedExpressionArray[LET_MUL_ASSIGN][LST_VECTOR][LST_VECTOR] = LST_FLOATINGPOINT; 359 | gSupportedExpressionArray[LET_MUL_ASSIGN][LST_VECTOR][LST_QUATERNION] = LST_VECTOR; 360 | gSupportedExpressionArray[LET_MUL_ASSIGN][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION; 361 | 362 | // LET_DIV_ASSIGN 363 | gSupportedExpressionArray[LET_DIV_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 364 | gSupportedExpressionArray[LET_DIV_ASSIGN][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT; 365 | gSupportedExpressionArray[LET_DIV_ASSIGN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 366 | gSupportedExpressionArray[LET_DIV_ASSIGN][LST_VECTOR][LST_INTEGER] = LST_VECTOR; 367 | gSupportedExpressionArray[LET_DIV_ASSIGN][LST_VECTOR][LST_FLOATINGPOINT] = LST_VECTOR; 368 | gSupportedExpressionArray[LET_DIV_ASSIGN][LST_VECTOR][LST_QUATERNION] = LST_VECTOR; 369 | gSupportedExpressionArray[LET_DIV_ASSIGN][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION; 370 | 371 | // LET_MOD_ASSIGN 372 | gSupportedExpressionArray[LET_MOD_ASSIGN][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 373 | gSupportedExpressionArray[LET_MOD_ASSIGN][LST_VECTOR][LST_VECTOR] = LST_VECTOR; 374 | 375 | // LET_EQUALITY 376 | gSupportedExpressionArray[LET_EQUALITY][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 377 | gSupportedExpressionArray[LET_EQUALITY][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER; 378 | gSupportedExpressionArray[LET_EQUALITY][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER; 379 | gSupportedExpressionArray[LET_EQUALITY][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER; 380 | gSupportedExpressionArray[LET_EQUALITY][LST_STRING][LST_STRING] = LST_INTEGER; 381 | gSupportedExpressionArray[LET_EQUALITY][LST_STRING][LST_KEY] = LST_INTEGER; 382 | gSupportedExpressionArray[LET_EQUALITY][LST_KEY][LST_STRING] = LST_INTEGER; 383 | gSupportedExpressionArray[LET_EQUALITY][LST_KEY][LST_KEY] = LST_INTEGER; 384 | gSupportedExpressionArray[LET_EQUALITY][LST_VECTOR][LST_VECTOR] = LST_INTEGER; 385 | gSupportedExpressionArray[LET_EQUALITY][LST_QUATERNION][LST_QUATERNION] = LST_INTEGER; 386 | gSupportedExpressionArray[LET_EQUALITY][LST_LIST][LST_LIST] = LST_INTEGER; 387 | 388 | // LET_NOT_EQUALS 389 | gSupportedExpressionArray[LET_NOT_EQUALS][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 390 | gSupportedExpressionArray[LET_NOT_EQUALS][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER; 391 | gSupportedExpressionArray[LET_NOT_EQUALS][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER; 392 | gSupportedExpressionArray[LET_NOT_EQUALS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER; 393 | gSupportedExpressionArray[LET_NOT_EQUALS][LST_STRING][LST_STRING] = LST_INTEGER; 394 | gSupportedExpressionArray[LET_NOT_EQUALS][LST_STRING][LST_KEY] = LST_INTEGER; 395 | gSupportedExpressionArray[LET_NOT_EQUALS][LST_KEY][LST_STRING] = LST_INTEGER; 396 | gSupportedExpressionArray[LET_NOT_EQUALS][LST_KEY][LST_KEY] = LST_INTEGER; 397 | gSupportedExpressionArray[LET_NOT_EQUALS][LST_VECTOR][LST_VECTOR] = LST_INTEGER; 398 | gSupportedExpressionArray[LET_NOT_EQUALS][LST_QUATERNION][LST_QUATERNION] = LST_INTEGER; 399 | gSupportedExpressionArray[LET_NOT_EQUALS][LST_LIST][LST_LIST] = LST_INTEGER; 400 | 401 | // LET_LESS_EQUALS 402 | gSupportedExpressionArray[LET_LESS_EQUALS][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 403 | gSupportedExpressionArray[LET_LESS_EQUALS][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER; 404 | gSupportedExpressionArray[LET_LESS_EQUALS][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER; 405 | gSupportedExpressionArray[LET_LESS_EQUALS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER; 406 | 407 | // LET_GREATER_EQUALS 408 | gSupportedExpressionArray[LET_GREATER_EQUALS][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 409 | gSupportedExpressionArray[LET_GREATER_EQUALS][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER; 410 | gSupportedExpressionArray[LET_GREATER_EQUALS][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER; 411 | gSupportedExpressionArray[LET_GREATER_EQUALS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER; 412 | 413 | // LET_LESS_THAN 414 | gSupportedExpressionArray[LET_LESS_THAN][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 415 | gSupportedExpressionArray[LET_LESS_THAN][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER; 416 | gSupportedExpressionArray[LET_LESS_THAN][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER; 417 | gSupportedExpressionArray[LET_LESS_THAN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER; 418 | 419 | // LET_GREATER_THAN 420 | gSupportedExpressionArray[LET_GREATER_THAN][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 421 | gSupportedExpressionArray[LET_GREATER_THAN][LST_INTEGER][LST_FLOATINGPOINT] = LST_INTEGER; 422 | gSupportedExpressionArray[LET_GREATER_THAN][LST_FLOATINGPOINT][LST_INTEGER] = LST_INTEGER; 423 | gSupportedExpressionArray[LET_GREATER_THAN][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_INTEGER; 424 | 425 | // LET_PLUS 426 | gSupportedExpressionArray[LET_PLUS][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 427 | gSupportedExpressionArray[LET_PLUS][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT; 428 | gSupportedExpressionArray[LET_PLUS][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 429 | gSupportedExpressionArray[LET_PLUS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 430 | gSupportedExpressionArray[LET_PLUS][LST_STRING][LST_STRING] = LST_STRING; 431 | gSupportedExpressionArray[LET_PLUS][LST_VECTOR][LST_VECTOR] = LST_VECTOR; 432 | gSupportedExpressionArray[LET_PLUS][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION; 433 | gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_INTEGER] = LST_LIST; 434 | gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_FLOATINGPOINT] = LST_LIST; 435 | gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_STRING] = LST_LIST; 436 | gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_KEY] = LST_LIST; 437 | gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_VECTOR] = LST_LIST; 438 | gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_QUATERNION] = LST_LIST; 439 | gSupportedExpressionArray[LET_PLUS][LST_INTEGER][LST_LIST] = LST_LIST; 440 | gSupportedExpressionArray[LET_PLUS][LST_FLOATINGPOINT][LST_LIST] = LST_LIST; 441 | gSupportedExpressionArray[LET_PLUS][LST_STRING][LST_LIST] = LST_LIST; 442 | gSupportedExpressionArray[LET_PLUS][LST_KEY][LST_LIST] = LST_LIST; 443 | gSupportedExpressionArray[LET_PLUS][LST_VECTOR][LST_LIST] = LST_LIST; 444 | gSupportedExpressionArray[LET_PLUS][LST_QUATERNION][LST_LIST] = LST_LIST; 445 | gSupportedExpressionArray[LET_PLUS][LST_LIST][LST_LIST] = LST_LIST; 446 | 447 | // LET_MINUS 448 | gSupportedExpressionArray[LET_MINUS][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 449 | gSupportedExpressionArray[LET_MINUS][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT; 450 | gSupportedExpressionArray[LET_MINUS][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 451 | gSupportedExpressionArray[LET_MINUS][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 452 | gSupportedExpressionArray[LET_MINUS][LST_VECTOR][LST_VECTOR] = LST_VECTOR; 453 | gSupportedExpressionArray[LET_MINUS][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION; 454 | 455 | // LET_TIMES 456 | gSupportedExpressionArray[LET_TIMES][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 457 | gSupportedExpressionArray[LET_TIMES][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT; 458 | gSupportedExpressionArray[LET_TIMES][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 459 | gSupportedExpressionArray[LET_TIMES][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 460 | gSupportedExpressionArray[LET_TIMES][LST_VECTOR][LST_INTEGER] = LST_VECTOR; 461 | gSupportedExpressionArray[LET_TIMES][LST_INTEGER][LST_VECTOR] = LST_VECTOR; 462 | gSupportedExpressionArray[LET_TIMES][LST_VECTOR][LST_FLOATINGPOINT] = LST_VECTOR; 463 | gSupportedExpressionArray[LET_TIMES][LST_FLOATINGPOINT][LST_VECTOR] = LST_VECTOR; 464 | gSupportedExpressionArray[LET_TIMES][LST_VECTOR][LST_VECTOR] = LST_FLOATINGPOINT; 465 | gSupportedExpressionArray[LET_TIMES][LST_VECTOR][LST_QUATERNION] = LST_VECTOR; 466 | gSupportedExpressionArray[LET_TIMES][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION; 467 | 468 | // LET_DIVIDE 469 | gSupportedExpressionArray[LET_DIVIDE][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 470 | gSupportedExpressionArray[LET_DIVIDE][LST_INTEGER][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 471 | gSupportedExpressionArray[LET_DIVIDE][LST_FLOATINGPOINT][LST_INTEGER] = LST_FLOATINGPOINT; 472 | gSupportedExpressionArray[LET_DIVIDE][LST_FLOATINGPOINT][LST_FLOATINGPOINT] = LST_FLOATINGPOINT; 473 | gSupportedExpressionArray[LET_DIVIDE][LST_VECTOR][LST_INTEGER] = LST_VECTOR; 474 | gSupportedExpressionArray[LET_DIVIDE][LST_VECTOR][LST_FLOATINGPOINT] = LST_VECTOR; 475 | gSupportedExpressionArray[LET_DIVIDE][LST_VECTOR][LST_QUATERNION] = LST_VECTOR; 476 | gSupportedExpressionArray[LET_DIVIDE][LST_QUATERNION][LST_QUATERNION] = LST_QUATERNION; 477 | 478 | // LET_MOD 479 | gSupportedExpressionArray[LET_MOD][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 480 | gSupportedExpressionArray[LET_MOD][LST_VECTOR][LST_VECTOR] = LST_VECTOR; 481 | 482 | // LET_BIT_AND 483 | gSupportedExpressionArray[LET_BIT_AND][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 484 | 485 | // LET_BIT_OR 486 | gSupportedExpressionArray[LET_BIT_OR][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 487 | 488 | // LET_BIT_XOR 489 | gSupportedExpressionArray[LET_BIT_XOR][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 490 | 491 | // LET_BOOLEAN_AND 492 | gSupportedExpressionArray[LET_BOOLEAN_AND][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 493 | 494 | // LET_BOOLEAN_OR 495 | gSupportedExpressionArray[LET_BOOLEAN_OR][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 496 | 497 | // LET_SHIFT_LEFT 498 | gSupportedExpressionArray[LET_SHIFT_LEFT][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 499 | 500 | // LET_SHIFT_RIGHT 501 | gSupportedExpressionArray[LET_SHIFT_RIGHT][LST_INTEGER][LST_INTEGER] = LST_INTEGER; 502 | 503 | // LET_PARENTHESIS 504 | gSupportedExpressionArray[LET_PARENTHESIS][LST_INTEGER][LST_NULL] = LST_INTEGER; 505 | gSupportedExpressionArray[LET_PARENTHESIS][LST_FLOATINGPOINT][LST_NULL] = LST_INTEGER; 506 | gSupportedExpressionArray[LET_PARENTHESIS][LST_STRING][LST_NULL] = LST_INTEGER; 507 | gSupportedExpressionArray[LET_PARENTHESIS][LST_LIST][LST_NULL] = LST_INTEGER; 508 | 509 | // LET_UNARY_MINUS 510 | gSupportedExpressionArray[LET_UNARY_MINUS][LST_INTEGER][LST_NULL] = LST_INTEGER; 511 | gSupportedExpressionArray[LET_UNARY_MINUS][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT; 512 | gSupportedExpressionArray[LET_UNARY_MINUS][LST_VECTOR][LST_NULL] = LST_VECTOR; 513 | gSupportedExpressionArray[LET_UNARY_MINUS][LST_QUATERNION][LST_NULL] = LST_QUATERNION; 514 | 515 | // LET_BOOLEAN_NOT 516 | gSupportedExpressionArray[LET_BOOLEAN_NOT][LST_INTEGER][LST_NULL] = LST_INTEGER; 517 | 518 | // LET_BIT_NOT 519 | gSupportedExpressionArray[LET_BIT_NOT][LST_INTEGER][LST_NULL] = LST_INTEGER; 520 | 521 | // LET_PRE_INCREMENT 522 | gSupportedExpressionArray[LET_PRE_INCREMENT][LST_INTEGER][LST_NULL] = LST_INTEGER; 523 | gSupportedExpressionArray[LET_PRE_INCREMENT][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT; 524 | 525 | // LET_PRE_DECREMENT 526 | gSupportedExpressionArray[LET_PRE_DECREMENT][LST_INTEGER][LST_NULL] = LST_INTEGER; 527 | gSupportedExpressionArray[LET_PRE_DECREMENT][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT; 528 | 529 | // LET_POST_INCREMENT 530 | gSupportedExpressionArray[LET_POST_INCREMENT][LST_INTEGER][LST_NULL] = LST_INTEGER; 531 | gSupportedExpressionArray[LET_POST_INCREMENT][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT; 532 | 533 | // LET_POST_DECREMENT 534 | gSupportedExpressionArray[LET_POST_DECREMENT][LST_INTEGER][LST_NULL] = LST_INTEGER; 535 | gSupportedExpressionArray[LET_POST_DECREMENT][LST_FLOATINGPOINT][LST_NULL] = LST_FLOATINGPOINT; 536 | } 537 | 538 | BOOL legal_binary_expression(LSCRIPTType &result, LSCRIPTType left_side, LSCRIPTType right_side, LSCRIPTExpressionType expression) 539 | { 540 | if ( (left_side == LST_UNDEFINED) 541 | ||(right_side == LST_UNDEFINED)) 542 | { 543 | result = LST_UNDEFINED; 544 | return TRUE; 545 | } 546 | 547 | if ( (left_side == LST_NULL) 548 | ||(right_side == LST_NULL)) 549 | { 550 | result = LST_UNDEFINED; 551 | return FALSE; 552 | } 553 | 554 | result = gSupportedExpressionArray[expression][left_side][right_side]; 555 | if (result) 556 | return TRUE; 557 | else 558 | { 559 | result = LST_UNDEFINED; 560 | return FALSE; 561 | } 562 | } 563 | 564 | BOOL legal_unary_expression(LSCRIPTType &result, LSCRIPTType left_side, LSCRIPTExpressionType expression) 565 | { 566 | if (left_side == LST_UNDEFINED) 567 | { 568 | result = LST_UNDEFINED; 569 | return TRUE; 570 | } 571 | 572 | if (left_side == LST_NULL) 573 | { 574 | result = LST_UNDEFINED; 575 | return FALSE; 576 | } 577 | 578 | result = gSupportedExpressionArray[expression][left_side][LST_NULL]; 579 | if (result) 580 | return TRUE; 581 | else 582 | { 583 | result = LST_UNDEFINED; 584 | return FALSE; 585 | } 586 | } 587 | -------------------------------------------------------------------------------- /llcommon/linked_lists.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file linked_lists.h 3 | * @brief LLLinkedList class header amd implementation file. 4 | * 5 | * $LicenseInfo:firstyear=2001&license=viewerlgpl$ 6 | * Second Life Viewer Source Code 7 | * Copyright (C) 2010, Linden Research, Inc. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; 12 | * version 2.1 of the License only. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA 24 | * $/LicenseInfo$ 25 | */ 26 | 27 | #ifndef LL_LINKED_LISTS_H 28 | #define LL_LINKED_LISTS_H 29 | 30 | /** 31 | * Provides a standard doubly linked list for fun and profit 32 | * Utilizes a neat trick off of Flipcode where the back pointer is a 33 | * pointer to a pointer, allowing easier transfer of nodes between lists, &c 34 | * And a template class, of course 35 | */ 36 | 37 | #include "llerror.h" 38 | 39 | 40 | template class LLLinkedList 41 | { 42 | public: 43 | friend class LLLinkNode; 44 | // External interface 45 | 46 | // basic constructor 47 | LLLinkedList() : mHead(NULL), mCurrentp(NULL), mInsertBefore(NULL) 48 | { 49 | mCurrentp = mHead.mNextp; 50 | mCurrentOperatingp = mHead.mNextp; 51 | mCount = 0; 52 | } 53 | 54 | // basic constructor 55 | LLLinkedList(BOOL (*insert_before)(DATA_TYPE *data_new, DATA_TYPE *data_tested)) : mHead(NULL), mCurrentp(NULL), mInsertBefore(insert_before) 56 | { 57 | mCurrentp = mHead.mNextp; 58 | mCurrentOperatingp = mHead.mNextp; 59 | mCount = 0; 60 | } 61 | 62 | // destructor destroys list and nodes, but not data in nodes 63 | ~LLLinkedList() 64 | { 65 | removeAllNodes(); 66 | } 67 | 68 | // set mInsertBefore 69 | void setInsertBefore(BOOL (*insert_before)(DATA_TYPE *data_new, DATA_TYPE *data_tested)) 70 | { 71 | mInsertBefore = insert_before; 72 | } 73 | 74 | // 75 | // WARNING!!!!!!! 76 | // addData and addDataSorted are NOT O(1) operations, but O(n) because they check 77 | // for existence of the data in the linked list first. Why, I don't know - djs 78 | // If you don't care about dupes, use addDataNoCheck 79 | // 80 | 81 | // put data into a node and stick it at the front of the list 82 | inline BOOL addData(DATA_TYPE *data); 83 | 84 | // put data into a node and sort into list by mInsertBefore() 85 | // calls normal add if mInsertBefore isn't set 86 | inline BOOL addDataSorted(DATA_TYPE *data); 87 | 88 | inline BOOL addDataNoCheck(DATA_TYPE *data); 89 | 90 | // bubbleSortList 91 | // does an improved bubble sort of the list . . . works best with almost sorted data 92 | // does nothing if mInsertBefore isn't set 93 | // Nota Bene: Swaps are accomplished by swapping data pointers 94 | inline void bubbleSortList(); 95 | 96 | // put data into a node and stick it at the end of the list 97 | inline BOOL addDataAtEnd(DATA_TYPE *data); 98 | 99 | // returns number of items in the list 100 | inline S32 getLength() const; 101 | 102 | inline BOOL isEmpty(); 103 | 104 | // search the list starting at mHead.mNextp and remove the link with mDatap == data 105 | // leave mCurrentp and mCurrentOperatingp on the next entry 106 | // return TRUE if found, FALSE if not found 107 | inline BOOL removeData(DATA_TYPE *data); 108 | 109 | // search the list starting at mHead.mNextp and delete the link with mDatap == data 110 | // leave mCurrentp and mCurrentOperatingp on the next entry 111 | // return TRUE if found, FALSE if not found 112 | inline BOOL deleteData(DATA_TYPE *data); 113 | 114 | // remove all nodes from the list and delete the associated data 115 | inline void deleteAllData(); 116 | 117 | // remove all nodes from the list but do not delete data 118 | inline void removeAllNodes(); 119 | 120 | // check to see if data is in list 121 | // if TRUE then mCurrentp and mCurrentOperatingp point to data 122 | inline BOOL checkData(DATA_TYPE *data); 123 | 124 | // place mCurrentp on first node 125 | inline void resetList(); 126 | 127 | // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp 128 | inline DATA_TYPE *getCurrentData(); 129 | 130 | // same as getCurrentData() but a more intuitive name for the operation 131 | inline DATA_TYPE *getNextData(); 132 | 133 | // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp 134 | inline DATA_TYPE *getFirstData(); 135 | 136 | // reset the list and return the data at position n, set mCurentOperatingp to that node and bump mCurrentp 137 | // Note: n is zero-based 138 | inline DATA_TYPE *getNthData( U32 n); 139 | 140 | // reset the list and return the last data in it, set mCurentOperatingp to that node and bump mCurrentp 141 | inline DATA_TYPE *getLastData(); 142 | 143 | // remove the Node at mCurentOperatingp 144 | // leave mCurrentp and mCurentOperatingp on the next entry 145 | inline void removeCurrentData(); 146 | 147 | // remove the Node at mCurentOperatingp and add it to newlist 148 | // leave mCurrentp and mCurentOperatingp on the next entry 149 | void moveCurrentData(LLLinkedList *newlist, BOOL b_sort); 150 | 151 | BOOL moveData(DATA_TYPE *data, LLLinkedList *newlist, BOOL b_sort); 152 | 153 | // delete the Node at mCurentOperatingp 154 | // leave mCurrentp anf mCurentOperatingp on the next entry 155 | void deleteCurrentData(); 156 | 157 | private: 158 | // node that actually contains the data 159 | class LLLinkNode 160 | { 161 | public: 162 | // assign the mDatap pointer 163 | LLLinkNode(DATA_TYPE *data) : mDatap(data), mNextp(NULL), mPrevpp(NULL) 164 | { 165 | } 166 | 167 | // destructor does not, by default, destroy associated data 168 | // however, the mDatap must be NULL to ensure that we aren't causing memory leaks 169 | ~LLLinkNode() 170 | { 171 | if (mDatap) 172 | { 173 | llerror("Attempting to call LLLinkNode destructor with a non-null mDatap!", 1); 174 | } 175 | } 176 | 177 | // delete associated data and NULL out pointer 178 | void deleteData() 179 | { 180 | delete mDatap; 181 | mDatap = NULL; 182 | } 183 | 184 | // NULL out pointer 185 | void removeData() 186 | { 187 | mDatap = NULL; 188 | } 189 | 190 | DATA_TYPE *mDatap; 191 | LLLinkNode *mNextp; 192 | LLLinkNode **mPrevpp; 193 | }; 194 | 195 | // add a node at the front of the list 196 | void addData(LLLinkNode *node) 197 | { 198 | // don't allow NULL to be passed to addData 199 | if (!node) 200 | { 201 | llerror("NULL pointer passed to LLLinkedList::addData", 0); 202 | } 203 | 204 | // add the node to the front of the list 205 | node->mPrevpp = &mHead.mNextp; 206 | node->mNextp = mHead.mNextp; 207 | 208 | // if there's something in the list, fix its back pointer 209 | if (node->mNextp) 210 | { 211 | node->mNextp->mPrevpp = &node->mNextp; 212 | } 213 | 214 | mHead.mNextp = node; 215 | } 216 | 217 | LLLinkNode mHead; // fake head node. . . makes pointer operations faster and easier 218 | LLLinkNode *mCurrentp; // mCurrentp is the Node that getCurrentData returns 219 | LLLinkNode *mCurrentOperatingp; // this is the node that the various mumbleCurrentData functions act on 220 | BOOL (*mInsertBefore)(DATA_TYPE *data_new, DATA_TYPE *data_tested); // user function set to allow sorted lists 221 | U32 mCount; 222 | }; 223 | 224 | template 225 | BOOL LLLinkedList::addData(DATA_TYPE *data) 226 | { 227 | // don't allow NULL to be passed to addData 228 | if (!data) 229 | { 230 | llerror("NULL pointer passed to LLLinkedList::addData", 0); 231 | } 232 | 233 | LLLinkNode *tcurr = mCurrentp; 234 | LLLinkNode *tcurrop = mCurrentOperatingp; 235 | 236 | if ( checkData(data)) 237 | { 238 | mCurrentp = tcurr; 239 | mCurrentOperatingp = tcurrop; 240 | return FALSE; 241 | } 242 | 243 | // make the new node 244 | LLLinkNode *temp = new LLLinkNode(data); 245 | 246 | // add the node to the front of the list 247 | temp->mPrevpp = &mHead.mNextp; 248 | temp->mNextp = mHead.mNextp; 249 | 250 | // if there's something in the list, fix its back pointer 251 | if (temp->mNextp) 252 | { 253 | temp->mNextp->mPrevpp = &temp->mNextp; 254 | } 255 | 256 | mHead.mNextp = temp; 257 | mCurrentp = tcurr; 258 | mCurrentOperatingp = tcurrop; 259 | mCount++; 260 | return TRUE; 261 | } 262 | 263 | 264 | template 265 | BOOL LLLinkedList::addDataNoCheck(DATA_TYPE *data) 266 | { 267 | // don't allow NULL to be passed to addData 268 | if (!data) 269 | { 270 | llerror("NULL pointer passed to LLLinkedList::addData", 0); 271 | } 272 | 273 | LLLinkNode *tcurr = mCurrentp; 274 | LLLinkNode *tcurrop = mCurrentOperatingp; 275 | 276 | // make the new node 277 | LLLinkNode *temp = new LLLinkNode(data); 278 | 279 | // add the node to the front of the list 280 | temp->mPrevpp = &mHead.mNextp; 281 | temp->mNextp = mHead.mNextp; 282 | 283 | // if there's something in the list, fix its back pointer 284 | if (temp->mNextp) 285 | { 286 | temp->mNextp->mPrevpp = &temp->mNextp; 287 | } 288 | 289 | mHead.mNextp = temp; 290 | mCurrentp = tcurr; 291 | mCurrentOperatingp = tcurrop; 292 | mCount++; 293 | return TRUE; 294 | } 295 | 296 | 297 | template 298 | BOOL LLLinkedList::addDataSorted(DATA_TYPE *data) 299 | { 300 | LLLinkNode *tcurr = mCurrentp; 301 | LLLinkNode *tcurrop = mCurrentOperatingp; 302 | // don't allow NULL to be passed to addData 303 | if (!data) 304 | { 305 | llerror("NULL pointer passed to LLLinkedList::addDataSorted", 0); 306 | } 307 | 308 | if (checkData(data)) 309 | { 310 | // restore 311 | mCurrentp = tcurr; 312 | mCurrentOperatingp = tcurrop; 313 | return FALSE; 314 | } 315 | 316 | // mInsertBefore not set? 317 | if (!mInsertBefore) 318 | { 319 | addData(data); 320 | // restore 321 | mCurrentp = tcurr; 322 | mCurrentOperatingp = tcurrop; 323 | return FALSE; 324 | } 325 | 326 | // empty list? 327 | if (!mHead.mNextp) 328 | { 329 | addData(data); 330 | // restore 331 | mCurrentp = tcurr; 332 | mCurrentOperatingp = tcurrop; 333 | return TRUE; 334 | } 335 | 336 | // make the new node 337 | LLLinkNode *temp = new LLLinkNode(data); 338 | 339 | // walk the list until mInsertBefore returns true 340 | mCurrentp = mHead.mNextp; 341 | while (mCurrentp->mNextp) 342 | { 343 | if (mInsertBefore(data, mCurrentp->mDatap)) 344 | { 345 | // insert before the current one 346 | temp->mPrevpp = mCurrentp->mPrevpp; 347 | temp->mNextp = mCurrentp; 348 | *(temp->mPrevpp) = temp; 349 | mCurrentp->mPrevpp = &temp->mNextp; 350 | // restore 351 | mCurrentp = tcurr; 352 | mCurrentOperatingp = tcurrop; 353 | mCount++; 354 | return TRUE; 355 | } 356 | else 357 | { 358 | mCurrentp = mCurrentp->mNextp; 359 | } 360 | } 361 | 362 | // on the last element, add before? 363 | if (mInsertBefore(data, mCurrentp->mDatap)) 364 | { 365 | // insert before the current one 366 | temp->mPrevpp = mCurrentp->mPrevpp; 367 | temp->mNextp = mCurrentp; 368 | *(temp->mPrevpp) = temp; 369 | mCurrentp->mPrevpp = &temp->mNextp; 370 | // restore 371 | mCurrentp = tcurr; 372 | mCurrentOperatingp = tcurrop; 373 | } 374 | else // insert after 375 | { 376 | temp->mPrevpp = &mCurrentp->mNextp; 377 | temp->mNextp = NULL; 378 | mCurrentp->mNextp = temp; 379 | 380 | // restore 381 | mCurrentp = tcurr; 382 | mCurrentOperatingp = tcurrop; 383 | } 384 | mCount++; 385 | return TRUE; 386 | } 387 | 388 | template 389 | void LLLinkedList::bubbleSortList() 390 | { 391 | // mInsertBefore not set 392 | if (!mInsertBefore) 393 | { 394 | return; 395 | } 396 | 397 | LLLinkNode *tcurr = mCurrentp; 398 | LLLinkNode *tcurrop = mCurrentOperatingp; 399 | 400 | BOOL b_swapped = FALSE; 401 | DATA_TYPE *temp; 402 | 403 | // Nota Bene: This will break if more than 0x7FFFFFFF members in list! 404 | S32 length = 0x7FFFFFFF; 405 | S32 count = 0; 406 | do 407 | { 408 | b_swapped = FALSE; 409 | mCurrentp = mHead.mNextp; 410 | count = 0; 411 | while ( (count + 1 < length) 412 | &&(mCurrentp)) 413 | { 414 | if (mCurrentp->mNextp) 415 | { 416 | if (!mInsertBefore(mCurrentp->mDatap, mCurrentp->mNextp->mDatap)) 417 | { 418 | // swap data pointers! 419 | temp = mCurrentp->mDatap; 420 | mCurrentp->mDatap = mCurrentp->mNextp->mDatap; 421 | mCurrentp->mNextp->mDatap = temp; 422 | b_swapped = TRUE; 423 | } 424 | } 425 | else 426 | { 427 | break; 428 | } 429 | count++; 430 | mCurrentp = mCurrentp->mNextp; 431 | } 432 | length = count; 433 | } while (b_swapped); 434 | 435 | // restore 436 | mCurrentp = tcurr; 437 | mCurrentOperatingp = tcurrop; 438 | } 439 | 440 | 441 | template 442 | BOOL LLLinkedList::addDataAtEnd(DATA_TYPE *data) 443 | { 444 | LLLinkNode *tcurr = mCurrentp; 445 | LLLinkNode *tcurrop = mCurrentOperatingp; 446 | 447 | // don't allow NULL to be passed to addData 448 | if (!data) 449 | { 450 | llerror("NULL pointer passed to LLLinkedList::addData", 0); 451 | } 452 | 453 | if (checkData(data)) 454 | { 455 | mCurrentp = tcurr; 456 | mCurrentOperatingp = tcurrop; 457 | return FALSE; 458 | } 459 | 460 | // make the new node 461 | LLLinkNode *temp = new LLLinkNode(data); 462 | 463 | // add the node to the end of the list 464 | 465 | // if empty, add to the front and be done with it 466 | if (!mHead.mNextp) 467 | { 468 | temp->mPrevpp = &mHead.mNextp; 469 | temp->mNextp = NULL; 470 | mHead.mNextp = temp; 471 | } 472 | else 473 | { 474 | // otherwise, walk to the end of the list 475 | mCurrentp = mHead.mNextp; 476 | while (mCurrentp->mNextp) 477 | { 478 | mCurrentp = mCurrentp->mNextp; 479 | } 480 | temp->mPrevpp = &mCurrentp->mNextp; 481 | temp->mNextp = NULL; 482 | mCurrentp->mNextp = temp; 483 | } 484 | 485 | // restore 486 | mCurrentp = tcurr; 487 | mCurrentOperatingp = tcurrop; 488 | mCount++; 489 | return TRUE; 490 | } 491 | 492 | 493 | // returns number of items in the list 494 | template 495 | S32 LLLinkedList::getLength() const 496 | { 497 | // S32 length = 0; 498 | // for (LLLinkNode* temp = mHead.mNextp; temp != NULL; temp = temp->mNextp) 499 | // { 500 | // length++; 501 | // } 502 | return mCount; 503 | } 504 | 505 | 506 | template 507 | BOOL LLLinkedList::isEmpty() 508 | { 509 | return (mCount == 0); 510 | } 511 | 512 | 513 | // search the list starting at mHead.mNextp and remove the link with mDatap == data 514 | // leave mCurrentp and mCurrentOperatingp on the next entry 515 | // return TRUE if found, FALSE if not found 516 | template 517 | BOOL LLLinkedList::removeData(DATA_TYPE *data) 518 | { 519 | BOOL b_found = FALSE; 520 | // don't allow NULL to be passed to addData 521 | if (!data) 522 | { 523 | llerror("NULL pointer passed to LLLinkedList::removeData", 0); 524 | } 525 | 526 | LLLinkNode *tcurr = mCurrentp; 527 | LLLinkNode *tcurrop = mCurrentOperatingp; 528 | 529 | mCurrentp = mHead.mNextp; 530 | mCurrentOperatingp = mHead.mNextp; 531 | 532 | while (mCurrentOperatingp) 533 | { 534 | if (mCurrentOperatingp->mDatap == data) 535 | { 536 | b_found = TRUE; 537 | 538 | // remove the node 539 | 540 | // if there is a next one, fix it 541 | if (mCurrentOperatingp->mNextp) 542 | { 543 | mCurrentOperatingp->mNextp->mPrevpp = mCurrentOperatingp->mPrevpp; 544 | } 545 | *(mCurrentOperatingp->mPrevpp) = mCurrentOperatingp->mNextp; 546 | 547 | // remove the LLLinkNode 548 | 549 | // if we were on the one we want to delete, bump the cached copies 550 | if (mCurrentOperatingp == tcurrop) 551 | { 552 | tcurrop = tcurr = mCurrentOperatingp->mNextp; 553 | } 554 | else if (mCurrentOperatingp == tcurr) 555 | { 556 | tcurrop = tcurr = mCurrentOperatingp->mNextp; 557 | } 558 | 559 | mCurrentp = mCurrentOperatingp->mNextp; 560 | 561 | mCurrentOperatingp->removeData(); 562 | delete mCurrentOperatingp; 563 | mCurrentOperatingp = mCurrentp; 564 | mCount--; 565 | break; 566 | } 567 | mCurrentOperatingp = mCurrentOperatingp->mNextp; 568 | } 569 | // restore 570 | mCurrentp = tcurr; 571 | mCurrentOperatingp = tcurrop; 572 | return b_found; 573 | } 574 | 575 | // search the list starting at mHead.mNextp and delete the link with mDatap == data 576 | // leave mCurrentp and mCurrentOperatingp on the next entry 577 | // return TRUE if found, FALSE if not found 578 | template 579 | BOOL LLLinkedList::deleteData(DATA_TYPE *data) 580 | { 581 | BOOL b_found = FALSE; 582 | // don't allow NULL to be passed to addData 583 | if (!data) 584 | { 585 | llerror("NULL pointer passed to LLLinkedList::removeData", 0); 586 | } 587 | 588 | LLLinkNode *tcurr = mCurrentp; 589 | LLLinkNode *tcurrop = mCurrentOperatingp; 590 | 591 | mCurrentp = mHead.mNextp; 592 | mCurrentOperatingp = mHead.mNextp; 593 | 594 | while (mCurrentOperatingp) 595 | { 596 | if (mCurrentOperatingp->mDatap == data) 597 | { 598 | b_found = TRUE; 599 | 600 | // remove the node 601 | // if there is a next one, fix it 602 | if (mCurrentOperatingp->mNextp) 603 | { 604 | mCurrentOperatingp->mNextp->mPrevpp = mCurrentOperatingp->mPrevpp; 605 | } 606 | *(mCurrentOperatingp->mPrevpp) = mCurrentOperatingp->mNextp; 607 | 608 | // delete the LLLinkNode 609 | // if we were on the one we want to delete, bump the cached copies 610 | if (mCurrentOperatingp == tcurrop) 611 | { 612 | tcurrop = tcurr = mCurrentOperatingp->mNextp; 613 | } 614 | 615 | // and delete the associated data 616 | llassert(mCurrentOperatingp); 617 | mCurrentp = mCurrentOperatingp->mNextp; 618 | mCurrentOperatingp->deleteData(); 619 | delete mCurrentOperatingp; 620 | mCurrentOperatingp = mCurrentp; 621 | mCount--; 622 | break; 623 | } 624 | mCurrentOperatingp = mCurrentOperatingp->mNextp; 625 | } 626 | // restore 627 | mCurrentp = tcurr; 628 | mCurrentOperatingp = tcurrop; 629 | return b_found; 630 | } 631 | 632 | // remove all nodes from the list and delete the associated data 633 | template 634 | void LLLinkedList::deleteAllData() 635 | { 636 | LLLinkNode *temp; 637 | // reset mCurrentp 638 | mCurrentp = mHead.mNextp; 639 | 640 | while (mCurrentp) 641 | { 642 | temp = mCurrentp->mNextp; 643 | mCurrentp->deleteData(); 644 | delete mCurrentp; 645 | mCurrentp = temp; 646 | } 647 | 648 | // reset mHead and mCurrentp 649 | mHead.mNextp = NULL; 650 | mCurrentp = mHead.mNextp; 651 | mCurrentOperatingp = mHead.mNextp; 652 | mCount = 0; 653 | } 654 | 655 | // remove all nodes from the list but do not delete data 656 | template 657 | void LLLinkedList::removeAllNodes() 658 | { 659 | LLLinkNode *temp; 660 | // reset mCurrentp 661 | mCurrentp = mHead.mNextp; 662 | 663 | while (mCurrentp) 664 | { 665 | temp = mCurrentp->mNextp; 666 | mCurrentp->removeData(); 667 | delete mCurrentp; 668 | mCurrentp = temp; 669 | } 670 | 671 | // reset mHead and mCurrentp 672 | mHead.mNextp = NULL; 673 | mCurrentp = mHead.mNextp; 674 | mCurrentOperatingp = mHead.mNextp; 675 | mCount = 0; 676 | } 677 | 678 | // check to see if data is in list 679 | // if TRUE then mCurrentp and mCurrentOperatingp point to data 680 | template 681 | BOOL LLLinkedList::checkData(DATA_TYPE *data) 682 | { 683 | // reset mCurrentp 684 | mCurrentp = mHead.mNextp; 685 | 686 | while (mCurrentp) 687 | { 688 | if (mCurrentp->mDatap == data) 689 | { 690 | mCurrentOperatingp = mCurrentp; 691 | return TRUE; 692 | } 693 | mCurrentp = mCurrentp->mNextp; 694 | } 695 | mCurrentOperatingp = mCurrentp; 696 | return FALSE; 697 | } 698 | 699 | // place mCurrentp on first node 700 | template 701 | void LLLinkedList::resetList() 702 | { 703 | mCurrentp = mHead.mNextp; 704 | mCurrentOperatingp = mHead.mNextp; 705 | } 706 | 707 | // return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp 708 | template 709 | DATA_TYPE *LLLinkedList::getCurrentData() 710 | { 711 | if (mCurrentp) 712 | { 713 | mCurrentOperatingp = mCurrentp; 714 | mCurrentp = mCurrentp->mNextp; 715 | return mCurrentOperatingp->mDatap; 716 | } 717 | else 718 | { 719 | return NULL; 720 | } 721 | } 722 | 723 | // same as getCurrentData() but a more intuitive name for the operation 724 | template 725 | DATA_TYPE *LLLinkedList::getNextData() 726 | { 727 | if (mCurrentp) 728 | { 729 | mCurrentOperatingp = mCurrentp; 730 | mCurrentp = mCurrentp->mNextp; 731 | return mCurrentOperatingp->mDatap; 732 | } 733 | else 734 | { 735 | return NULL; 736 | } 737 | } 738 | 739 | // reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp 740 | template 741 | DATA_TYPE *LLLinkedList::getFirstData() 742 | { 743 | mCurrentp = mHead.mNextp; 744 | mCurrentOperatingp = mHead.mNextp; 745 | if (mCurrentp) 746 | { 747 | mCurrentOperatingp = mCurrentp; 748 | mCurrentp = mCurrentp->mNextp; 749 | return mCurrentOperatingp->mDatap; 750 | } 751 | else 752 | { 753 | return NULL; 754 | } 755 | } 756 | 757 | // Note: n is zero-based 758 | template 759 | DATA_TYPE *LLLinkedList::getNthData( U32 n ) 760 | { 761 | mCurrentOperatingp = mHead.mNextp; 762 | 763 | // if empty, return NULL 764 | if (!mCurrentOperatingp) 765 | { 766 | return NULL; 767 | } 768 | 769 | for( U32 i = 0; i < n; i++ ) 770 | { 771 | mCurrentOperatingp = mCurrentOperatingp->mNextp; 772 | if( !mCurrentOperatingp ) 773 | { 774 | return NULL; 775 | } 776 | } 777 | 778 | mCurrentp = mCurrentOperatingp->mNextp; 779 | return mCurrentOperatingp->mDatap; 780 | } 781 | 782 | 783 | // reset the list and return the last data in it, set mCurentOperatingp to that node and bump mCurrentp 784 | template 785 | DATA_TYPE *LLLinkedList::getLastData() 786 | { 787 | mCurrentOperatingp = mHead.mNextp; 788 | 789 | // if empty, return NULL 790 | if (!mCurrentOperatingp) 791 | return NULL; 792 | 793 | // walk until we're pointing at the last entry 794 | while (mCurrentOperatingp->mNextp) 795 | { 796 | mCurrentOperatingp = mCurrentOperatingp->mNextp; 797 | } 798 | mCurrentp = mCurrentOperatingp->mNextp; 799 | return mCurrentOperatingp->mDatap; 800 | } 801 | 802 | // remove the Node at mCurentOperatingp 803 | // leave mCurrentp and mCurentOperatingp on the next entry 804 | // return TRUE if found, FALSE if not found 805 | template 806 | void LLLinkedList::removeCurrentData() 807 | { 808 | if (mCurrentOperatingp) 809 | { 810 | // remove the node 811 | // if there is a next one, fix it 812 | if (mCurrentOperatingp->mNextp) 813 | { 814 | mCurrentOperatingp->mNextp->mPrevpp = mCurrentOperatingp->mPrevpp; 815 | } 816 | *(mCurrentOperatingp->mPrevpp) = mCurrentOperatingp->mNextp; 817 | 818 | // remove the LLLinkNode 819 | mCurrentp = mCurrentOperatingp->mNextp; 820 | 821 | mCurrentOperatingp->removeData(); 822 | delete mCurrentOperatingp; 823 | mCount--; 824 | mCurrentOperatingp = mCurrentp; 825 | } 826 | } 827 | 828 | // remove the Node at mCurentOperatingp and add it to newlist 829 | // leave mCurrentp and mCurentOperatingp on the next entry 830 | // return TRUE if found, FALSE if not found 831 | template 832 | void LLLinkedList::moveCurrentData(LLLinkedList *newlist, BOOL b_sort) 833 | { 834 | if (mCurrentOperatingp) 835 | { 836 | // remove the node 837 | // if there is a next one, fix it 838 | if (mCurrentOperatingp->mNextp) 839 | { 840 | mCurrentOperatingp->mNextp->mPrevpp = mCurrentOperatingp->mPrevpp; 841 | } 842 | *(mCurrentOperatingp->mPrevpp) = mCurrentOperatingp->mNextp; 843 | 844 | // remove the LLLinkNode 845 | mCurrentp = mCurrentOperatingp->mNextp; 846 | // move the node to the new list 847 | newlist->addData(mCurrentOperatingp); 848 | if (b_sort) 849 | bubbleSortList(); 850 | mCurrentOperatingp = mCurrentp; 851 | } 852 | } 853 | 854 | template 855 | BOOL LLLinkedList::moveData(DATA_TYPE *data, LLLinkedList *newlist, BOOL b_sort) 856 | { 857 | BOOL b_found = FALSE; 858 | // don't allow NULL to be passed to addData 859 | if (!data) 860 | { 861 | llerror("NULL pointer passed to LLLinkedList::removeData", 0); 862 | } 863 | 864 | LLLinkNode *tcurr = mCurrentp; 865 | LLLinkNode *tcurrop = mCurrentOperatingp; 866 | 867 | mCurrentp = mHead.mNextp; 868 | mCurrentOperatingp = mHead.mNextp; 869 | 870 | while (mCurrentOperatingp) 871 | { 872 | if (mCurrentOperatingp->mDatap == data) 873 | { 874 | b_found = TRUE; 875 | 876 | // remove the node 877 | 878 | // if there is a next one, fix it 879 | if (mCurrentOperatingp->mNextp) 880 | { 881 | mCurrentOperatingp->mNextp->mPrevpp = mCurrentOperatingp->mPrevpp; 882 | } 883 | *(mCurrentOperatingp->mPrevpp) = mCurrentOperatingp->mNextp; 884 | 885 | // if we were on the one we want to delete, bump the cached copies 886 | if ( (mCurrentOperatingp == tcurrop) 887 | ||(mCurrentOperatingp == tcurr)) 888 | { 889 | tcurrop = tcurr = mCurrentOperatingp->mNextp; 890 | } 891 | 892 | // remove the LLLinkNode 893 | mCurrentp = mCurrentOperatingp->mNextp; 894 | // move the node to the new list 895 | newlist->addData(mCurrentOperatingp); 896 | if (b_sort) 897 | newlist->bubbleSortList(); 898 | mCurrentOperatingp = mCurrentp; 899 | break; 900 | } 901 | mCurrentOperatingp = mCurrentOperatingp->mNextp; 902 | } 903 | // restore 904 | mCurrentp = tcurr; 905 | mCurrentOperatingp = tcurrop; 906 | return b_found; 907 | } 908 | 909 | // delete the Node at mCurentOperatingp 910 | // leave mCurrentp anf mCurentOperatingp on the next entry 911 | // return TRUE if found, FALSE if not found 912 | template 913 | void LLLinkedList::deleteCurrentData() 914 | { 915 | if (mCurrentOperatingp) 916 | { 917 | // remove the node 918 | // if there is a next one, fix it 919 | if (mCurrentOperatingp->mNextp) 920 | { 921 | mCurrentOperatingp->mNextp->mPrevpp = mCurrentOperatingp->mPrevpp; 922 | } 923 | *(mCurrentOperatingp->mPrevpp) = mCurrentOperatingp->mNextp; 924 | 925 | // remove the LLLinkNode 926 | mCurrentp = mCurrentOperatingp->mNextp; 927 | 928 | mCurrentOperatingp->deleteData(); 929 | if (mCurrentOperatingp->mDatap) 930 | llerror("This is impossible!", 0); 931 | delete mCurrentOperatingp; 932 | mCurrentOperatingp = mCurrentp; 933 | mCount--; 934 | } 935 | } 936 | 937 | #endif 938 | --------------------------------------------------------------------------------