diff options
author | Jose Fonseca <jfonseca@vmware.com> | 2016-02-10 21:44:36 +0000 |
---|---|---|
committer | Jose Fonseca <jfonseca@vmware.com> | 2016-02-10 21:46:30 +0000 |
commit | 80f0f0532dabf2d4c4bb3dd17aea16a574d1db44 (patch) | |
tree | 5a4eaee09f086a82e129e1a37af91cef4819ad2a /common | |
parent | 2257503ff3fc87d76309bd58b3206ee4cac33c37 (diff) | |
parent | f6305d3d105376de5306f6d0e70ff666df38d2e0 (diff) |
Merge branch 'master' into virtual-memory-regionsvirtual-memory-regions
Diffstat (limited to 'common')
54 files changed, 7439 insertions, 744 deletions
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt new file mode 100644 index 00000000..e4eab722 --- /dev/null +++ b/common/CMakeLists.txt @@ -0,0 +1,52 @@ +include_directories ( + ${CMAKE_SOURCE_DIR}/guids +) + +if (WIN32) + set (os os_win32.cpp) +else () + set (os os_posix.cpp) +endif () + +add_convenience_library (common + trace_callset.cpp + trace_dump.cpp + trace_fast_callset.cpp + trace_file.cpp + trace_file_read.cpp + trace_file_zlib.cpp + trace_file_snappy.cpp + trace_model.cpp + trace_parser.cpp + trace_parser_flags.cpp + trace_parser_loop.cpp + trace_writer.cpp + trace_writer_local.cpp + trace_writer_model.cpp + trace_profiler.cpp + trace_option.cpp + trace_ostream_snappy.cpp + trace_ostream_zlib.cpp + ${os} + os_backtrace.cpp + os_crtdbg.cpp + highlight.cpp +) + +target_link_libraries (common + guids + ${LIBBACKTRACE_LIBRARIES} +) +if (WIN32) + target_link_libraries (common + shell32 + ) +endif () +if (ANDROID) + target_link_libraries (common + log + ) +endif () + +add_gtest (trace_parser_flags_test trace_parser_flags_test.cpp) +target_link_libraries (trace_parser_flags_test common) diff --git a/common/highlight.cpp b/common/highlight.cpp index a80a2b02..a03fcf76 100644 --- a/common/highlight.cpp +++ b/common/highlight.cpp @@ -32,6 +32,7 @@ #include <windows.h> #include <io.h> // _isatty +#include <stdio.h> // _fileno #ifndef COMMON_LVB_LEADING_BYTE #define COMMON_LVB_LEADING_BYTE 0x0100 @@ -229,7 +230,7 @@ haveAnsi(void) static bool result = false; if (!checked) { - // https://code.google.com/p/conemu-maximus5/wiki/AnsiEscapeCodes#Environment_variable + // https://conemu.github.io/en/ConEmuEnvironment.html // XXX: Didn't quite work for me if (0) { const char *conEmuANSI = getenv("ConEmuANSI"); @@ -241,11 +242,21 @@ haveAnsi(void) } } + // Cygwin shell + if (1) { + const char *term = getenv("TERM"); + if (term && + strcmp(term, "xterm") == 0) { + result = true; + checked = true; + return result; + } + } + // http://wiki.winehq.org/DeveloperFaq#detect-wine - HMODULE hNtDll = LoadLibraryA("ntdll"); + HMODULE hNtDll = GetModuleHandleA("ntdll"); if (hNtDll) { result = GetProcAddress(hNtDll, "wine_get_version") != NULL; - FreeLibrary(hNtDll); } checked = true; diff --git a/common/highlight.hpp b/common/highlight.hpp index 9f6be8d4..bda49142 100644 --- a/common/highlight.hpp +++ b/common/highlight.hpp @@ -27,8 +27,7 @@ * Helpers for coloring output. */ -#ifndef _HIGHLIGHT_HPP_ -#define _HIGHLIGHT_HPP_ +#pragma once #include <iostream> @@ -85,4 +84,3 @@ defaultHighlighter(std::ostream & os); } /* namespace highlight */ -#endif /* _HIGHLIGHT_HPP_ */ diff --git a/common/os.hpp b/common/os.hpp index 62bb954a..10c7b7c7 100644 --- a/common/os.hpp +++ b/common/os.hpp @@ -27,8 +27,7 @@ * Simple OS abstraction layer. */ -#ifndef _OS_HPP_ -#define _OS_HPP_ +#pragma once #include <stdlib.h> #include <stdarg.h> @@ -64,13 +63,8 @@ void log(const char *format, ...) #endif #define PRIVATE #else - #if __GNUC__ >= 4 - #define PUBLIC __attribute__ ((visibility("default"))) - #define PRIVATE __attribute__ ((visibility("hidden"))) - #else - #define PUBLIC - #define PRIVATE - #endif + #define PUBLIC __attribute__ ((visibility("default"))) + #define PRIVATE __attribute__ ((visibility("hidden"))) #endif /** @@ -79,7 +73,19 @@ void log(const char *format, ...) * This should be called only from the wrappers, when there is no safe way of * failing gracefully. */ -void abort(void); +// coverity[+kill] +#ifdef _MSC_VER +__declspec(noreturn) +#endif +void abort(void) +#ifdef __GNUC__ + __attribute__((__noreturn__)) +#endif +; + +void +breakpoint(void); + void setExceptionCallback(void (*callback)(void)); void resetExceptionCallback(void); @@ -106,4 +112,3 @@ bool queryVirtualAddress(const void *address, MemoryInfo *info); } /* namespace os */ -#endif /* _OS_HPP_ */ diff --git a/common/os_backtrace.hpp b/common/os_backtrace.hpp index 27dcc90f..72869c26 100644 --- a/common/os_backtrace.hpp +++ b/common/os_backtrace.hpp @@ -24,8 +24,7 @@ * **************************************************************************/ -#ifndef _OS_BACKTRACE_HPP_ -#define _OS_BACKTRACE_HPP_ +#pragma once #include <vector> @@ -43,5 +42,3 @@ void dump_backtrace(); } /* namespace os */ - -#endif diff --git a/common/os_binary.hpp b/common/os_binary.hpp index a231c709..c3a1d6ea 100644 --- a/common/os_binary.hpp +++ b/common/os_binary.hpp @@ -27,8 +27,7 @@ * Force binary mode standard files on Windows. */ -#ifndef _OS_BINARY_HPP_ -#define _OS_BINARY_HPP_ +#pragma once #include <stdio.h> @@ -58,4 +57,3 @@ void setBinaryMode(FILE *fp) { } /* namespace os */ -#endif /* _OS_BINARY_HPP_ */ diff --git a/common/os_crtdbg.cpp b/common/os_crtdbg.cpp new file mode 100644 index 00000000..21dec6ec --- /dev/null +++ b/common/os_crtdbg.cpp @@ -0,0 +1,92 @@ +/************************************************************************** + * + * Copyright 2015 VMware, Inc + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + +#include "os_crtdbg.hpp" + +#include <assert.h> +#include <stdio.h> + +#ifdef _WIN32 +#include <windows.h> +#include <crtdbg.h> +#endif + +#include "os.hpp" + + +namespace os { + + +#ifdef _WIN32 + +static void +invalidParameterHandler(const wchar_t* expression, + const wchar_t* function, + const wchar_t* file, + unsigned int line, + uintptr_t pReserved) +{ + fprintf(stderr, "Invalid parameter detected in function %S. File: %S Line: %d\n", function, file, line); + fprintf(stderr, "Expression: %S\n", expression); + if (IsDebuggerPresent()) { + os::breakpoint(); + } + os::abort(); +} + +#endif // _WIN32 + + +void +setDebugOutput(Output output) +{ + +#ifdef _WIN32 + // Disable assertion failure message box + // http://msdn.microsoft.com/en-us/library/sas1dkb2.aspx + _set_error_mode(_OUT_TO_STDERR); +#ifdef _MSC_VER + // Disable abort message box + // http://msdn.microsoft.com/en-us/library/e631wekh.aspx + _set_abort_behavior(0, _WRITE_ABORT_MSG); + // Direct debug reports to stderr + // https://msdn.microsoft.com/en-us/library/1y71x448.aspx + for (int reportType = 0; reportType < _CRT_ERRCNT; ++reportType) { + _CrtSetReportMode(reportType, _CRTDBG_MODE_FILE); + _CrtSetReportFile(reportType, _CRTDBG_FILE_STDERR); + } +#endif /* _MSC_VER */ + // Set our own invalid_parameter handler + // https://msdn.microsoft.com/en-us/library/a9yf33zb.aspx + _set_invalid_parameter_handler(invalidParameterHandler); +#endif /* _WIN32 */ + + + assert(output == OUTPUT_STDERR); +} + + +} /* namespace os */ diff --git a/common/trace_file_write.cpp b/common/os_crtdbg.hpp index 4cc8984e..87a018ba 100644 --- a/common/trace_file_write.cpp +++ b/common/os_crtdbg.hpp @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2011 Jose Fonseca + * Copyright 2015 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -23,28 +23,35 @@ * **************************************************************************/ +/* + * Abstrations to force where CRT debug output should go. + */ -#include "os.hpp" -#include "trace_file.hpp" +#pragma once -using namespace trace; +#include <stdio.h> +#ifdef _WIN32 +#include <assert.h> -File * -File::createForWrite(const char *filename) -{ - File *file; - file = File::createSnappy(); - if (!file) { - return NULL; - } +#include <fcntl.h> +#include <io.h> +#endif - if (!file->open(filename, File::Write)) { - os::log("error: could not open %s for writing\n", filename); - delete file; - return NULL; - } - return file; -} +namespace os { + + +enum Output { + OUTPUT_STDERR, + OUTPUT_OUTDBG +}; + + +void +setDebugOutput(Output output); + + +} /* namespace os */ + diff --git a/common/os_dl.hpp b/common/os_dl.hpp index da51d414..bf79d507 100644 --- a/common/os_dl.hpp +++ b/common/os_dl.hpp @@ -27,8 +27,7 @@ * Dynamic library linking abstraction. */ -#ifndef _OS_DL_HPP_ -#define _OS_DL_HPP_ +#pragma once #if defined(_WIN32) @@ -86,4 +85,3 @@ namespace os { } /* namespace os */ -#endif /* _OS_DL_HPP_ */ diff --git a/common/os_memory.hpp b/common/os_memory.hpp index 4774412d..5a852516 100644 --- a/common/os_memory.hpp +++ b/common/os_memory.hpp @@ -28,13 +28,16 @@ * Simple OS time measurement abstraction. */ -#ifndef _OS_MEMORY_HPP_ -#define _OS_MEMORY_HPP_ +#pragma once #ifdef HAVE_READPROC_H #include <proc/readproc.h> +#endif namespace os { + +#if defined(HAVE_READPROC_H) + inline long long getVsize(void) { proc_t proc; @@ -48,10 +51,17 @@ namespace os { look_up_our_self(&proc); return proc.rss; } -} /* namespace os */ + +#elif defined(__ANDROID__) + + long long + getVsize(void); + + long long + getRss(void); #else -namespace os { + inline long long getVsize(void) { return 0; @@ -61,7 +71,8 @@ namespace os { getRss(void) { return 0; } -} /* namespace os */ + #endif -#endif /* _OS_MEMORY_HPP_ */ +} /* namespace os */ + diff --git a/common/os_posix.cpp b/common/os_posix.cpp index e29f9fbf..7f3b3f90 100644 --- a/common/os_posix.cpp +++ b/common/os_posix.cpp @@ -32,8 +32,11 @@ #include <stdint.h> #include <unistd.h> +#include <errno.h> #include <sys/wait.h> #include <sys/stat.h> +#include <sys/types.h> +#include <pwd.h> #include <fcntl.h> #include <signal.h> @@ -58,6 +61,10 @@ #define PATH_MAX 4096 #endif +#ifdef __QNXNTO__ +#define SA_RESTART 0 // QNX does not have SA_RESTART +#endif + #include "os.hpp" #include "os_string.hpp" #include "os_backtrace.hpp" @@ -107,8 +114,18 @@ getProcessName(void) } } } + +#ifdef __GLIBC__ + // fallback to `program_invocation_name` + if (len <= 0) { + len = strlen(program_invocation_name); + buf = path.buf(len + 1); + strcpy(buf, program_invocation_name); + } +#endif + + // fallback to process ID if (len <= 0) { - // fallback to process ID len = snprintf(buf, size, "%i", (int)getpid()); if (len >= size) { len = size - 1; @@ -127,10 +144,52 @@ getCurrentDir(void) size_t size = PATH_MAX; char *buf = path.buf(size); - getcwd(buf, size); - buf[size - 1] = 0; + if (getcwd(buf, size)) { + buf[size - 1] = 0; + path.truncate(); + } else { + path.truncate(0); + } - path.truncate(); + return path; +} + +String +getConfigDir(void) +{ + String path; + +#ifdef __APPLE__ + // Library/Preferences + const char *homeDir = getenv("HOME"); + assert(homeDir); + if (homeDir) { + path = homeDir; + path.join("Library/Preferences"); + } +#else + // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + const char *configHomeDir = getenv("XDG_CONFIG_HOME"); + if (configHomeDir) { + path = configHomeDir; + } else { + const char *homeDir = getenv("HOME"); + if (!homeDir) { + struct passwd *user = getpwuid(getuid()); + if (user != NULL) { + homeDir = user->pw_dir; + } + } + assert(homeDir); + if (homeDir) { + path = homeDir; +#if !defined(ANDROID) + path.join(".config"); +#endif + } + } +#endif + return path; } @@ -227,6 +286,17 @@ abort(void) } +void +breakpoint(void) +{ +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + asm("int3"); +#else + kill(getpid(), SIGTRAP); +#endif +} + + static void (*gCallback)(void) = NULL; #define NUM_SIGNALS 16 @@ -346,7 +416,6 @@ resetExceptionCallback(void) gCallback = NULL; } - #ifdef __linux__ struct MapRegion { @@ -684,6 +753,42 @@ bool queryVirtualAddress(const void *address, MemoryInfo *info) #endif /* __APPLE__ */ +#ifdef __ANDROID__ +#include "os_memory.hpp" +#include <cassert> +#include <cstdio> + +#include <fcntl.h> +#include <unistd.h> + +char statmBuff[256]; +static __uint64_t pageSize = sysconf(_SC_PAGESIZE); + +static long size, resident; + +static inline void parseStatm() +{ + int fd = open("/proc/self/statm", O_RDONLY, 0); + int sz = read(fd, statmBuff, 255); + close(fd); + statmBuff[sz] = 0; + sz = sscanf(statmBuff, "%ld %ld", + &size, &resident); + assert(sz == 2); +} + +long long getVsize() +{ + parseStatm(); + return pageSize * size; +} + +long long getRss() +{ + parseStatm(); + return pageSize * resident; +} +#endif } /* namespace os */ diff --git a/common/os_process.hpp b/common/os_process.hpp index e1b1df17..880242f8 100644 --- a/common/os_process.hpp +++ b/common/os_process.hpp @@ -27,8 +27,7 @@ * Sub-process abstraction. */ -#ifndef _OS_PROCESS_HPP_ -#define _OS_PROCESS_HPP_ +#pragma once #ifdef _WIN32 @@ -88,4 +87,3 @@ int execute(char * const * args); } /* namespace os */ -#endif /* _OS_PROCESS_HPP_ */ diff --git a/common/os_string.hpp b/common/os_string.hpp index 996c6191..1feca2c5 100644 --- a/common/os_string.hpp +++ b/common/os_string.hpp @@ -27,8 +27,7 @@ * String manipulation. */ -#ifndef _OS_STRING_HPP_ -#define _OS_STRING_HPP_ +#pragma once #include <assert.h> @@ -424,6 +423,8 @@ public: String getProcessName(); String getCurrentDir(); +String getConfigDir(); + bool createDirectory(const String &path); bool copyFile(const String &srcFileName, const String &dstFileName, bool override = true); @@ -432,4 +433,3 @@ bool removeFile(const String &fileName); } /* namespace os */ -#endif /* _OS_STRING_HPP_ */ diff --git a/common/os_thread.hpp b/common/os_thread.hpp index 5d19f301..830ceb06 100644 --- a/common/os_thread.hpp +++ b/common/os_thread.hpp @@ -26,39 +26,53 @@ /* * OS native thread abstraction. * - * Mimics C++11 threads. + * Mimics/leverages C++11 threads. */ -#ifndef _OS_THREAD_HPP_ -#define _OS_THREAD_HPP_ +#pragma once -#ifdef _WIN32 -#include <windows.h> -#else -#include <pthread.h> -#endif +/* XXX: We still use our own implementation: + * + * - MSVC's C++11 threads implementation are hardcoded to use C++ exceptions + * + * - MinGW's C++11 threads implementation is often either missing or relies on + * winpthreads + * + * - clang 3.4 (used in Travis) fails to compile some of libstdc++ C++11 thread + * headers + */ -/* - * This feature is not supported on Windows XP - */ -#define USE_WIN32_CONDITION_VARIABLES 0 +#ifdef HAVE_CXX11_THREADS +#include <thread> +#include <mutex> +#include <condition_variable> -/** - * Compiler TLS. - * - * See also: - * - http://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Thread_002dLocal.html - * - http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx - */ -#if defined(HAVE_COMPILER_TLS) -# define OS_THREAD_SPECIFIC(_type) HAVE_COMPILER_TLS _type +namespace os { + + using std::mutex; + using std::recursive_mutex; + using std::unique_lock; + using std::condition_variable; + using std::thread; + +} /* namespace os */ + + +#else /* !HAVE_CXX11_THREADS */ + + +#ifdef _WIN32 +# include <process.h> +# include <windows.h> +# if _WIN32_WINNT >= 0x0600 +# define HAVE_WIN32_CONDITION_VARIABLES +# endif #else -# define OS_THREAD_SPECIFIC(_type) os::thread_specific< _type > +# include <pthread.h> #endif -#define OS_THREAD_SPECIFIC_PTR(_type) OS_THREAD_SPECIFIC(_type *) namespace os { @@ -76,18 +90,11 @@ namespace os { typedef pthread_mutex_t native_handle_type; #endif + protected: _base_mutex(void) { -#ifdef _WIN32 - InitializeCriticalSection(&_native_handle); -#else - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&_native_handle, &attr); - pthread_mutexattr_destroy(&attr); -#endif } + public: ~_base_mutex() { #ifdef _WIN32 DeleteCriticalSection(&_native_handle); @@ -171,34 +178,34 @@ namespace os { typedef Mutex mutex_type; inline explicit - unique_lock(mutex_type & mutex) : - _mutex(&mutex) + unique_lock(mutex_type &m) : + _mutex(m) { - _mutex->lock(); + _mutex.lock(); } inline ~unique_lock() { - _mutex->unlock(); + _mutex.unlock(); } inline void lock() { - _mutex->lock(); + _mutex.lock(); } inline void unlock() { - _mutex->unlock(); + _mutex.unlock(); } mutex_type * mutex() const { - return _mutex; + return &_mutex; } protected: - mutex_type *_mutex; + mutex_type &_mutex; }; @@ -209,8 +216,8 @@ namespace os { { private: #ifdef _WIN32 -# if USE_WIN32_CONDITION_VARIABLES - // XXX: Only supported on Vista an higher. Not yet supported by WINE. +# ifdef HAVE_WIN32_CONDITION_VARIABLES + // Only supported on Vista an higher. Not yet supported by WINE. typedef CONDITION_VARIABLE native_handle_type; native_handle_type _native_handle; #else @@ -226,7 +233,7 @@ namespace os { public: condition_variable() { #ifdef _WIN32 -# if USE_WIN32_CONDITION_VARIABLES +# ifdef HAVE_WIN32_CONDITION_VARIABLES InitializeConditionVariable(&_native_handle); # else cWaiters = 0; @@ -239,7 +246,7 @@ namespace os { ~condition_variable() { #ifdef _WIN32 -# if USE_WIN32_CONDITION_VARIABLES +# ifdef HAVE_WIN32_CONDITION_VARIABLES /* No-op */ # else CloseHandle(hEvent); @@ -250,9 +257,9 @@ namespace os { } inline void - signal(void) { + notify_one(void) { #ifdef _WIN32 -# if USE_WIN32_CONDITION_VARIABLES +# ifdef HAVE_WIN32_CONDITION_VARIABLES WakeConditionVariable(&_native_handle); # else if (cWaiters) { @@ -268,7 +275,7 @@ namespace os { wait(unique_lock<mutex> & lock) { mutex::native_handle_type & mutex_native_handle = lock.mutex()->native_handle(); #ifdef _WIN32 -# if USE_WIN32_CONDITION_VARIABLES +# ifdef HAVE_WIN32_CONDITION_VARIABLES SleepConditionVariableCS(&_native_handle, &mutex_native_handle, INFINITE); # else InterlockedIncrement(&cWaiters); @@ -386,13 +393,10 @@ namespace os { } template< class Function, class Arg > - explicit thread( Function& f, Arg arg ) { -#ifdef _WIN32 - DWORD id = 0; - _native_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)f, (LPVOID)arg, 0, &id); -#else - pthread_create(&_native_handle, NULL, (void *(*) (void *))f, (void *)arg); -#endif + explicit thread( Function &f, Arg arg ) { + typedef CallbackParam< Function, Arg > Param; + Param *pParam = new Param(f, arg); + _native_handle = _create(pParam); } inline thread & @@ -418,17 +422,71 @@ namespace os { private: native_handle_type _native_handle; -#if 0 -#ifdef _WIN32 - template< class Function, class Arg > - static DWORD WINAPI - ThreadProc(LPVOID lpParameter) { + template< typename Function, typename Arg > + struct CallbackParam { + Function &f; + Arg arg; - ); + inline + CallbackParam(Function &_f, Arg _arg) : + f(_f), + arg(_arg) + {} + + inline void + operator () (void) { + f(arg); + } + }; + + template< typename Param > + static +#ifdef _WIN32 + unsigned __stdcall +#else + void * #endif + _callback(void *lpParameter) { + Param *pParam = static_cast<Param *>(lpParameter); + (*pParam)(); + delete pParam; + return 0; + } + + template< typename Param > + static inline native_handle_type + _create(Param *pParam) { +#ifdef _WIN32 + uintptr_t handle =_beginthreadex(NULL, 0, &_callback<Param>, static_cast<void *>(pParam), 0, NULL); + return reinterpret_cast<HANDLE>(handle); +#else + pthread_t t; + pthread_create(&t, NULL, &_callback<Param>, static_cast<void *>(pParam)); + return t; #endif + } }; } /* namespace os */ -#endif /* _OS_THREAD_HPP_ */ + +#endif /* !HAVE_CXX11_THREADS */ + + +/** + * Compiler TLS. + * + * See also: + * - http://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Thread_002dLocal.html + * - http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx + */ +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600 +# define OS_THREAD_SPECIFIC(_type) os::thread_specific< _type > +#elif defined(__GNUC__) +# define OS_THREAD_SPECIFIC(_type) __thread _type +#elif defined(_MSC_VER) +# define OS_THREAD_SPECIFIC(_type) __declspec(thread) _type +#else +# define OS_THREAD_SPECIFIC(_type) os::thread_specific< _type > +#endif +#define OS_THREAD_SPECIFIC_PTR(_type) OS_THREAD_SPECIFIC(_type *) diff --git a/common/os_time.hpp b/common/os_time.hpp index 3e4960e7..e3f63aff 100644 --- a/common/os_time.hpp +++ b/common/os_time.hpp @@ -27,8 +27,7 @@ * Simple OS time measurement abstraction. */ -#ifndef _OS_TIME_HPP_ -#define _OS_TIME_HPP_ +#pragma once #if defined(_WIN32) @@ -103,4 +102,3 @@ namespace os { } /* namespace os */ -#endif /* _OS_TIME_HPP_ */ diff --git a/common/os_version.hpp b/common/os_version.hpp new file mode 100644 index 00000000..ad85de7d --- /dev/null +++ b/common/os_version.hpp @@ -0,0 +1,61 @@ +/************************************************************************** + * + * Copyright 2014 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + +#pragma once + + +#ifdef _WIN32 + + +#include <windows.h> + + +/** + * VersionHelpers.h is not yet widely available (only available on certain MSVC + * and Windows SDK versions), so just define our own helpers. + * + * See http://msdn.microsoft.com/en-gb/library/windows/desktop/ms725491.aspx + */ +static inline bool +IsWindows8OrGreater() +{ + OSVERSIONINFOEXW osvi; + ZeroMemory(&osvi, sizeof osvi); + osvi.dwOSVersionInfoSize = sizeof osvi; + osvi.dwMajorVersion = 6; + osvi.dwMinorVersion = 2; + osvi.wServicePackMajor = 0; + DWORDLONG dwlConditionMask = 0; + VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); + return VerifyVersionInfoW(&osvi, + VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, + dwlConditionMask); +} + + +#endif /* _WIN32 */ diff --git a/common/os_win32.cpp b/common/os_win32.cpp index cc7b2813..cce75395 100644 --- a/common/os_win32.cpp +++ b/common/os_win32.cpp @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2010 VMware, Inc. + * Copyright 2010-2015 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -26,6 +26,7 @@ #ifdef _WIN32 #include <windows.h> +#include <shlobj.h> #include <assert.h> #include <string.h> @@ -71,6 +72,20 @@ getCurrentDir(void) return path; } +String +getConfigDir(void) +{ + String path; + char *buf = path.buf(MAX_PATH); + HRESULT hr = SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, buf); + if (SUCCEEDED(hr)) { + path.truncate(); + } else { + path.truncate(0); + } + return path; +} + bool createDirectory(const String &path) { @@ -239,7 +254,23 @@ long long timeFrequency = 0LL; void abort(void) { - TerminateProcess(GetCurrentProcess(), 1); + TerminateProcess(GetCurrentProcess(), 3); +#if defined(__GNUC__) + __builtin_unreachable(); +#endif +} + + +void +breakpoint(void) +{ +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + asm("int3"); +#elif defined(_MSC_VER) + __debugbreak(); +#else + DebugBreak(); +#endif } @@ -247,60 +278,88 @@ abort(void) #define DBG_PRINTEXCEPTION_C 0x40010006 #endif +#ifndef DBG_PRINTEXCEPTION_WIDE_C +#define DBG_PRINTEXCEPTION_WIDE_C 0x4001000A +#endif + static PVOID prevExceptionFilter = NULL; static void (*gCallback)(void) = NULL; static LONG CALLBACK unhandledExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo) { + /* + * Before Vista KiUserExceptionDispatcher does not clear the direction + * flag. + * + * See also: + * - https://bugs.chromium.org/p/nativeclient/issues/detail?id=1495 + */ +#ifdef _MSC_VER +#ifndef _WIN64 + __asm cld; +#endif +#else + asm("cld"); +#endif + PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord; + DWORD ExceptionCode = pExceptionRecord->ExceptionCode; + + // https://msdn.microsoft.com/en-us/library/het71c37.aspx + switch (ExceptionCode >> 30) { + case 0: // success + return EXCEPTION_CONTINUE_SEARCH; + case 1: // informational + case 2: // warning + case 3: // error + break; + } /* - * Ignore OutputDebugStringA exception. + * Ignore OutputDebugStringA/W exceptions. */ - if (pExceptionRecord->ExceptionCode == DBG_PRINTEXCEPTION_C) { + if (ExceptionCode == DBG_PRINTEXCEPTION_C || + ExceptionCode == DBG_PRINTEXCEPTION_WIDE_C) { return EXCEPTION_CONTINUE_SEARCH; } /* - * Ignore C++ exceptions + * Ignore C++ exceptions, as some applications generate a lot of these with + * no harm. But don't ignore them on debug builds, as bugs in apitrace can + * easily lead the applicationa and/or runtime to raise them, and catching + * them helps debugging. * - * http://support.microsoft.com/kb/185294 - * http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx + * See also: + * - http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx + * - http://support.microsoft.com/kb/185294 */ - if (pExceptionRecord->ExceptionCode == 0xe06d7363) { +#ifdef NDEBUG + if (ExceptionCode == 0xe06d7363) { return EXCEPTION_CONTINUE_SEARCH; } +#endif /* * Ignore thread naming exception. * * http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx */ - if (pExceptionRecord->ExceptionCode == 0x406d1388) { + if (ExceptionCode == 0x406d1388) { return EXCEPTION_CONTINUE_SEARCH; } /* - * Ignore .NET exception. + * Ignore .NET exceptions. * * http://ig2600.blogspot.co.uk/2011/01/why-do-i-keep-getting-exception-code.html + * https://github.com/dotnet/coreclr/blob/master/src/jit/importer.cpp */ - if (pExceptionRecord->ExceptionCode == 0xe0434352) { + if (ExceptionCode == 0xe0434352 || + ExceptionCode == 0xe0564552) { return EXCEPTION_CONTINUE_SEARCH; } - // Clear direction flag -#ifdef _MSC_VER -#ifndef _WIN64 - __asm { - cld - }; -#endif -#else - asm("cld"); -#endif - log("apitrace: warning: caught exception 0x%08lx\n", pExceptionRecord->ExceptionCode); static int recursion_count = 0; diff --git a/common/trace_api.hpp b/common/trace_api.hpp index 3d491fe1..3b119f8e 100644 --- a/common/trace_api.hpp +++ b/common/trace_api.hpp @@ -23,8 +23,7 @@ * **************************************************************************/ -#ifndef _TRACE_API_HPP_ -#define _TRACE_API_HPP_ +#pragma once #include <stdlib.h> @@ -49,9 +48,9 @@ enum API { API_D3D8, API_D3D9, API_DXGI, // D3D10.x, D3D11.x + API_D2D1, // Direct2D }; } /* namespace trace */ -#endif /* _TRACE_API_HPP_ */ diff --git a/common/trace_callset.cpp b/common/trace_callset.cpp index dca39d09..3722ea65 100644 --- a/common/trace_callset.cpp +++ b/common/trace_callset.cpp @@ -27,10 +27,9 @@ #include <assert.h> #include <stdlib.h> -#include <limits> #include <fstream> #include <iostream> -#include <string> +#include <sstream> #include <trace_callset.hpp> @@ -233,12 +232,22 @@ CallSet::merge(const char *string) firstmerge = false; } - if (*string == '@') { - FileCallSetParser parser(*this, &string[1]); - parser.parse(); - } else { - StringCallSetParser parser(*this, string); - parser.parse(); + /* + * Parse a comma-separated list of files or ranges + */ + std::stringstream calls_arg(string); + std::string token; + const char *str; + + while (std::getline(calls_arg, token, ',')) { + str = token.c_str(); + if (str[0] == '@') { + FileCallSetParser parser(*this, &str[1]); + parser.parse(); + } else { + StringCallSetParser parser(*this, str); + parser.parse(); + } } } diff --git a/common/trace_callset.hpp b/common/trace_callset.hpp index 53bad986..4070a4b8 100644 --- a/common/trace_callset.hpp +++ b/common/trace_callset.hpp @@ -44,8 +44,7 @@ * */ -#ifndef _TRACE_CALLSET_HPP_ -#define _TRACE_CALLSET_HPP_ +#pragma once #include <limits> @@ -194,4 +193,3 @@ namespace trace { } /* namespace trace */ -#endif /* _TRACE_CALLSET_HPP_ */ diff --git a/common/trace_dump.cpp b/common/trace_dump.cpp index f81c1473..5147e806 100644 --- a/common/trace_dump.cpp +++ b/common/trace_dump.cpp @@ -26,8 +26,12 @@ #include <limits> +#include <assert.h> +#include <string.h> + #include "highlight.hpp" #include "trace_dump.hpp" +#include "guids.hpp" namespace trace { @@ -93,24 +97,30 @@ public: os.precision(oldPrecision); } - void visit(String *node) { + template< typename C > + void visitString(const C *value) { os << literal << "\""; - for (const char *it = node->value; *it; ++it) { - unsigned char c = (unsigned char) *it; + for (const C *it = value; *it; ++it) { + unsigned c = (unsigned) *it; if (c == '\"') os << "\\\""; else if (c == '\\') os << "\\\\"; else if (c >= 0x20 && c <= 0x7e) - os << c; + os << (char)c; else if (c == '\t') { os << "\t"; } else if (c == '\r') { // Ignore carriage-return } else if (c == '\n') { - // Reset formatting so that it looks correct with 'less -R' - os << normal << '\n' << literal; + if (dumpFlags & DUMP_FLAG_NO_MULTILINE) { + os << "\\n"; + } else { + // Reset formatting so that it looks correct with 'less -R' + os << normal << '\n' << literal; + } } else { + // FIXME: handle wchar_t octals properly unsigned octal0 = c & 0x7; unsigned octal1 = (c >> 3) & 0x7; unsigned octal2 = (c >> 3) & 0x7; @@ -125,6 +135,15 @@ public: os << "\"" << normal; } + void visit(String *node) { + visitString(node->value); + } + + void visit(WString *node) { + os << literal << "L"; + visitString(node->value); + } + void visit(Enum *node) { const EnumValue *it = node->lookup(); if (it) { @@ -185,6 +204,25 @@ public: } void visit(Struct *s) { + // Replace GUIDs with their symbolic name + // TODO: Move this to parsing, so it can be shared everywhere + if (s->members.size() == 4 && + strcmp(s->sig->name, "GUID") == 0) { + GUID guid; + guid.Data1 = s->members[0]->toUInt(); + guid.Data2 = s->members[1]->toUInt(); + guid.Data3 = s->members[2]->toUInt(); + Array *data4 = s->members[3]->toArray(); + assert(data4); + assert(data4->values.size() == 8); + for (int i = 0; i < sizeof guid.Data4; ++i) { + guid.Data4[i] = data4->values[i]->toUInt(); + } + const char *name = getGuidName(guid); + os << literal << name << normal; + return; + } + os << "{"; visitMembers(s); os << "}"; @@ -274,14 +312,16 @@ public: os << " // " << red << "incomplete" << normal; } - os << "\n"; - - if (call->backtrace != NULL) { - os << bold << red << "Backtrace:\n" << normal; - visit(*call->backtrace); - } - if (callFlags & CALL_FLAG_END_FRAME) { + if (!(dumpFlags & DUMP_FLAG_NO_MULTILINE)) { os << "\n"; + + if (call->backtrace != NULL) { + os << bold << red << "Backtrace:\n" << normal; + visit(*call->backtrace); + } + if (callFlags & CALL_FLAG_END_FRAME) { + os << "\n"; + } } } }; diff --git a/common/trace_dump.hpp b/common/trace_dump.hpp index 2d22027e..4c756ca4 100644 --- a/common/trace_dump.hpp +++ b/common/trace_dump.hpp @@ -27,8 +27,7 @@ * Human-readible dumping. */ -#ifndef _TRACE_DUMP_HPP_ -#define _TRACE_DUMP_HPP_ +#pragma once #include <iostream> @@ -46,6 +45,7 @@ enum { DUMP_FLAG_NO_ARG_NAMES = (1 << 1), DUMP_FLAG_NO_CALL_NO = (1 << 2), DUMP_FLAG_THREAD_IDS = (1 << 3), + DUMP_FLAG_NO_MULTILINE = (1 << 4), }; @@ -74,4 +74,3 @@ inline std::ostream & operator <<(std::ostream &os, Call &call) { } /* namespace trace */ -#endif /* _TRACE_DUMP_HPP_ */ diff --git a/common/trace_fast_callset.hpp b/common/trace_fast_callset.hpp index 4b27c7ac..55d507df 100644 --- a/common/trace_fast_callset.hpp +++ b/common/trace_fast_callset.hpp @@ -26,8 +26,7 @@ * *********************************************************************/ -#ifndef _TRACE_FAST_CALLSET_HPP_ -#define _TRACE_FAST_CALLSET_HPP_ +#pragma once #include "trace_model.hpp" @@ -139,4 +138,3 @@ public: } /* namespace trace */ -#endif /* _TRACE_FAST_CALLSET_HPP_ */ diff --git a/common/trace_file.cpp b/common/trace_file.cpp index 3657fd29..8bd255d1 100644 --- a/common/trace_file.cpp +++ b/common/trace_file.cpp @@ -32,13 +32,11 @@ using namespace trace; -File::File(const std::string &filename, - File::Mode mode) - : m_mode(mode), - m_isOpened(false) +File::File(const std::string &filename) + : m_isOpened(false) { if (!filename.empty()) { - open(filename, m_mode); + open(filename); } } diff --git a/common/trace_file.hpp b/common/trace_file.hpp index 0c176aab..17e6756b 100644 --- a/common/trace_file.hpp +++ b/common/trace_file.hpp @@ -24,26 +24,17 @@ **************************************************************************/ -#ifndef TRACE_FILE_HPP -#define TRACE_FILE_HPP +#pragma once #include <string> #include <fstream> #include <stdint.h> -#define SNAPPY_BYTE1 'a' -#define SNAPPY_BYTE2 't' - - namespace trace { class File { public: - enum Mode { - Read, - Write - }; struct Offset { Offset(uint64_t _chunk = 0, uint32_t _offsetInChunk = 0) : chunk(_chunk), @@ -57,20 +48,15 @@ public: static File *createZLib(void); static File *createSnappy(void); static File *createForRead(const char *filename); - static File *createForWrite(const char *filename); public: - File(const std::string &filename = std::string(), - File::Mode mode = File::Read); + File(const std::string &filename = std::string()); virtual ~File(); bool isOpened() const; - File::Mode mode() const; - bool open(const std::string &filename, File::Mode mode); - bool write(const void *buffer, size_t length); + bool open(const std::string &filename); size_t read(void *buffer, size_t length); void close(); - void flush(void); int getc(); bool skip(size_t length); int percentRead(); @@ -79,17 +65,14 @@ public: virtual File::Offset currentOffset() = 0; virtual void setCurrentOffset(const File::Offset &offset); protected: - virtual bool rawOpen(const std::string &filename, File::Mode mode) = 0; - virtual bool rawWrite(const void *buffer, size_t length) = 0; + virtual bool rawOpen(const std::string &filename) = 0; virtual size_t rawRead(void *buffer, size_t length) = 0; virtual int rawGetc() = 0; virtual void rawClose() = 0; - virtual void rawFlush() = 0; virtual bool rawSkip(size_t length) = 0; virtual int rawPercentRead() = 0; protected: - File::Mode m_mode; bool m_isOpened; }; @@ -98,33 +81,19 @@ inline bool File::isOpened() const return m_isOpened; } -inline File::Mode File::mode() const -{ - return m_mode; -} - -inline bool File::open(const std::string &filename, File::Mode mode) +inline bool File::open(const std::string &filename) { if (m_isOpened) { close(); } - m_isOpened = rawOpen(filename, mode); - m_mode = mode; + m_isOpened = rawOpen(filename); return m_isOpened; } -inline bool File::write(const void *buffer, size_t length) -{ - if (!m_isOpened || m_mode != File::Write) { - return false; - } - return rawWrite(buffer, length); -} - inline size_t File::read(void *buffer, size_t length) { - if (!m_isOpened || m_mode != File::Read) { + if (!m_isOpened) { return 0; } return rawRead(buffer, length); @@ -132,7 +101,7 @@ inline size_t File::read(void *buffer, size_t length) inline int File::percentRead() { - if (!m_isOpened || m_mode != File::Read) { + if (!m_isOpened) { return 0; } return rawPercentRead(); @@ -146,16 +115,9 @@ inline void File::close() } } -inline void File::flush(void) -{ - if (m_mode == File::Write) { - rawFlush(); - } -} - inline int File::getc() { - if (!m_isOpened || m_mode != File::Read) { + if (!m_isOpened) { return -1; } return rawGetc(); @@ -163,7 +125,7 @@ inline int File::getc() inline bool File::skip(size_t length) { - if (!m_isOpened || m_mode != File::Read) { + if (!m_isOpened) { return false; } return rawSkip(length); @@ -205,5 +167,3 @@ operator<=(const File::Offset &one, const File::Offset &two) } /* namespace trace */ - -#endif diff --git a/common/trace_file_read.cpp b/common/trace_file_read.cpp index 46c83ff2..c4198550 100644 --- a/common/trace_file_read.cpp +++ b/common/trace_file_read.cpp @@ -28,6 +28,7 @@ #include "os.hpp" #include "trace_file.hpp" +#include "trace_snappy.hpp" using namespace trace; @@ -59,7 +60,7 @@ File::createForRead(const char *filename) return NULL; } - if (!file->open(filename, File::Read)) { + if (!file->open(filename)) { os::log("error: could not open %s for reading\n", filename); delete file; return NULL; diff --git a/common/trace_file_snappy.cpp b/common/trace_file_snappy.cpp index 41d86ea0..1154c68e 100644 --- a/common/trace_file_snappy.cpp +++ b/common/trace_file_snappy.cpp @@ -60,6 +60,7 @@ #include <string.h> #include "trace_file.hpp" +#include "trace_snappy.hpp" #define SNAPPY_CHUNK_SIZE (1 * 1024 * 1024) @@ -71,20 +72,17 @@ using namespace trace; class SnappyFile : public File { public: - SnappyFile(const std::string &filename = std::string(), - File::Mode mode = File::Read); + SnappyFile(const std::string &filename = std::string()); virtual ~SnappyFile(); virtual bool supportsOffsets() const; virtual File::Offset currentOffset(); virtual void setCurrentOffset(const File::Offset &offset); protected: - virtual bool rawOpen(const std::string &filename, File::Mode mode); - virtual bool rawWrite(const void *buffer, size_t length); + virtual bool rawOpen(const std::string &filename); virtual size_t rawRead(void *buffer, size_t length); virtual int rawGetc(); virtual void rawClose(); - virtual void rawFlush(); virtual bool rawSkip(size_t length); virtual int rawPercentRead(); @@ -125,8 +123,7 @@ private: std::streampos m_endPos; }; -SnappyFile::SnappyFile(const std::string &filename, - File::Mode mode) +SnappyFile::SnappyFile(const std::string &filename) : File(), m_cacheMaxSize(SNAPPY_CHUNK_SIZE), m_cacheSize(m_cacheMaxSize), @@ -145,20 +142,15 @@ SnappyFile::~SnappyFile() delete [] m_cache; } -bool SnappyFile::rawOpen(const std::string &filename, File::Mode mode) +bool SnappyFile::rawOpen(const std::string &filename) { - std::ios_base::openmode fmode = std::fstream::binary; - if (mode == File::Write) { - fmode |= (std::fstream::out | std::fstream::trunc); - createCache(SNAPPY_CHUNK_SIZE); - } else if (mode == File::Read) { - fmode |= std::fstream::in; - } + std::ios_base::openmode fmode = std::fstream::binary + | std::fstream::in; m_stream.open(filename.c_str(), fmode); //read in the initial buffer if we're reading - if (m_stream.is_open() && mode == File::Read) { + if (m_stream.is_open()) { m_stream.seekg(0, std::ios::end); m_endPos = m_stream.tellg(); m_stream.seekg(0, std::ios::beg); @@ -170,44 +162,10 @@ bool SnappyFile::rawOpen(const std::string &filename, File::Mode mode) assert(byte1 == SNAPPY_BYTE1 && byte2 == SNAPPY_BYTE2); flushReadCache(); - } else if (m_stream.is_open() && mode == File::Write) { - // write the snappy file identifier - m_stream << SNAPPY_BYTE1; - m_stream << SNAPPY_BYTE2; } return m_stream.is_open(); } -bool SnappyFile::rawWrite(const void *buffer, size_t length) -{ - if (freeCacheSize() > length) { - memcpy(m_cachePtr, buffer, length); - m_cachePtr += length; - } else if (freeCacheSize() == length) { - memcpy(m_cachePtr, buffer, length); - m_cachePtr += length; - flushWriteCache(); - } else { - size_t sizeToWrite = length; - - while (sizeToWrite >= freeCacheSize()) { - size_t endSize = freeCacheSize(); - size_t offset = length - sizeToWrite; - memcpy(m_cachePtr, (const char*)buffer + offset, endSize); - sizeToWrite -= endSize; - m_cachePtr += endSize; - flushWriteCache(); - } - if (sizeToWrite) { - size_t offset = length - sizeToWrite; - memcpy(m_cachePtr, (const char*)buffer + offset, sizeToWrite); - m_cachePtr += sizeToWrite; - } - } - - return true; -} - size_t SnappyFile::rawRead(void *buffer, size_t length) { if (endOfData()) { @@ -248,57 +206,38 @@ int SnappyFile::rawGetc() void SnappyFile::rawClose() { - if (m_mode == File::Write) { - flushWriteCache(); - } m_stream.close(); delete [] m_cache; m_cache = NULL; m_cachePtr = NULL; } -void SnappyFile::rawFlush() -{ - assert(m_mode == File::Write); - flushWriteCache(); - m_stream.flush(); -} - -void SnappyFile::flushWriteCache() -{ - size_t inputLength = usedCacheSize(); - - if (inputLength) { - size_t compressedLength; - - ::snappy::RawCompress(m_cache, inputLength, - m_compressedCache, &compressedLength); - - writeCompressedLength(compressedLength); - m_stream.write(m_compressedCache, compressedLength); - m_cachePtr = m_cache; - } - assert(m_cachePtr == m_cache); -} - void SnappyFile::flushReadCache(size_t skipLength) { //assert(m_cachePtr == m_cache + m_cacheSize); m_currentOffset.chunk = m_stream.tellg(); size_t compressedLength; compressedLength = readCompressedLength(); + if (!compressedLength) { + // Reached end of file + createCache(0); + return; + } - if (compressedLength) { - m_stream.read((char*)m_compressedCache, compressedLength); - ::snappy::GetUncompressedLength(m_compressedCache, compressedLength, - &m_cacheSize); - createCache(m_cacheSize); - if (skipLength < m_cacheSize) { - ::snappy::RawUncompress(m_compressedCache, compressedLength, - m_cache); - } - } else { + m_stream.read((char*)m_compressedCache, compressedLength); + if (m_stream.fail()) { + // XXX: Unforunately Snappy's interface is not expressive enough + // to allow recovering part of the uncompressed bytes. + std::cerr << "warning: unexpected end of file while reading trace\n"; createCache(0); + return; + } + ::snappy::GetUncompressedLength(m_compressedCache, compressedLength, + &m_cacheSize); + createCache(m_cacheSize); + if (skipLength < m_cacheSize) { + ::snappy::RawUncompress(m_compressedCache, compressedLength, + m_cache); } } diff --git a/common/trace_file_zlib.cpp b/common/trace_file_zlib.cpp index a432ccde..db54427e 100644 --- a/common/trace_file_zlib.cpp +++ b/common/trace_file_zlib.cpp @@ -31,9 +31,8 @@ #include <string.h> #include <zlib.h> -#include <gzguts.h> -// for lseek +#include <fcntl.h> #ifdef _WIN32 #include <io.h> #else @@ -51,30 +50,27 @@ using namespace trace; class ZLibFile : public File { public: - ZLibFile(const std::string &filename = std::string(), - File::Mode mode = File::Read); + ZLibFile(const std::string &filename = std::string()); virtual ~ZLibFile(); virtual bool supportsOffsets() const; virtual File::Offset currentOffset(); protected: - virtual bool rawOpen(const std::string &filename, File::Mode mode); - virtual bool rawWrite(const void *buffer, size_t length); + virtual bool rawOpen(const std::string &filename); virtual size_t rawRead(void *buffer, size_t length); virtual int rawGetc(); virtual void rawClose(); - virtual void rawFlush(); virtual bool rawSkip(size_t length); virtual int rawPercentRead(); private: + int fd; gzFile m_gzFile; double m_endOffset; }; -ZLibFile::ZLibFile(const std::string &filename, - File::Mode mode) - : File(filename, mode), +ZLibFile::ZLibFile(const std::string &filename) + : File(filename), m_gzFile(NULL) { } @@ -84,30 +80,40 @@ ZLibFile::~ZLibFile() close(); } -bool ZLibFile::rawOpen(const std::string &filename, File::Mode mode) +bool ZLibFile::rawOpen(const std::string &filename) { - m_gzFile = gzopen(filename.c_str(), - (mode == File::Write) ? "wb" : "rb"); + int flags = O_RDONLY; +#ifdef O_BINARY + flags |= O_BINARY; +#endif +#ifdef O_LARGEFILE + flags |= O_LARGEFILE; +#endif + +#ifdef _WIN32 + fd = _open(filename.c_str(), flags, 0666); +#else + fd = ::open(filename.c_str(), flags, 0666); +#endif + if (fd < 0) { + return false; + } + + m_gzFile = gzdopen(fd, "rb"); - if (mode == File::Read && m_gzFile) { + if (m_gzFile) { //XXX: unfortunately zlib doesn't support // SEEK_END or we could've done: //m_endOffset = gzseek(m_gzFile, 0, SEEK_END); //gzrewind(m_gzFile); - gz_state *state = (gz_state *)m_gzFile; - off_t loc = lseek(state->fd, 0, SEEK_CUR); - m_endOffset = lseek(state->fd, 0, SEEK_END); - lseek(state->fd, loc, SEEK_SET); + off_t loc = lseek(fd, 0, SEEK_CUR); + m_endOffset = lseek(fd, 0, SEEK_END); + lseek(fd, loc, SEEK_SET); } return m_gzFile != NULL; } -bool ZLibFile::rawWrite(const void *buffer, size_t length) -{ - return gzwrite(m_gzFile, buffer, unsigned(length)) != -1; -} - size_t ZLibFile::rawRead(void *buffer, size_t length) { int ret = gzread(m_gzFile, buffer, unsigned(length)); @@ -127,11 +133,6 @@ void ZLibFile::rawClose() } } -void ZLibFile::rawFlush() -{ - gzflush(m_gzFile, Z_SYNC_FLUSH); -} - File::Offset ZLibFile::currentOffset() { return File::Offset(gztell(m_gzFile)); @@ -149,8 +150,7 @@ bool ZLibFile::rawSkip(size_t) int ZLibFile::rawPercentRead() { - gz_state *state = (gz_state *)m_gzFile; - return int(100 * (lseek(state->fd, 0, SEEK_CUR) / m_endOffset)); + return int(100 * (lseek(fd, 0, SEEK_CUR) / m_endOffset)); } diff --git a/common/trace_format.hpp b/common/trace_format.hpp index 9f2a3ea6..4c6d821e 100644 --- a/common/trace_format.hpp +++ b/common/trace_format.hpp @@ -29,8 +29,7 @@ * See FORMAT.markdown for details. */ -#ifndef _TRACE_FORMAT_HPP_ -#define _TRACE_FORMAT_HPP_ +#pragma once namespace trace { @@ -67,6 +66,7 @@ enum Type { TYPE_STRUCT, TYPE_OPAQUE, TYPE_REPR, + TYPE_WSTRING, }; enum BacktraceDetail { @@ -81,4 +81,3 @@ enum BacktraceDetail { } /* namespace trace */ -#endif /* _TRACE_FORMAT_HPP_ */ diff --git a/common/trace_loader.cpp b/common/trace_loader.cpp deleted file mode 100644 index 6a3d7de0..00000000 --- a/common/trace_loader.cpp +++ /dev/null @@ -1,137 +0,0 @@ -#include "trace_loader.hpp" - - -using namespace trace; - -Loader::Loader() - : m_frameMarker(FrameMarker_SwapBuffers) -{ -} - -Loader::~Loader() -{ - close(); -} - -Loader::FrameMarker Loader::frameMarker() const -{ - return m_frameMarker; -} - -void Loader::setFrameMarker(Loader::FrameMarker marker) -{ - m_frameMarker = marker; -} - -unsigned Loader::numberOfFrames() const -{ - return unsigned(m_frameBookmarks.size()); -} - -unsigned Loader::numberOfCallsInFrame(unsigned frameIdx) const -{ - if (frameIdx > m_frameBookmarks.size()) { - return 0; - } - FrameBookmarks::const_iterator itr = - m_frameBookmarks.find(frameIdx); - return itr->second.numberOfCalls; -} - -bool Loader::open(const char *filename) -{ - if (!m_parser.open(filename)) { - std::cerr << "error: failed to open " << filename << "\n"; - return false; - } - if (!m_parser.supportsOffsets()) { - std::cerr << "error: " <<filename<< " doesn't support seeking " - << "\n"; - return false; - } - - trace::Call *call; - ParseBookmark startBookmark; - unsigned numOfFrames = 0; - unsigned numOfCalls = 0; - int lastPercentReport = 0; - - m_parser.getBookmark(startBookmark); - - while ((call = m_parser.scan_call())) { - ++numOfCalls; - - if (isCallAFrameMarker(call)) { - FrameBookmark frameBookmark(startBookmark); - frameBookmark.numberOfCalls = numOfCalls; - - m_frameBookmarks[numOfFrames] = frameBookmark; - ++numOfFrames; - - if (m_parser.percentRead() - lastPercentReport >= 5) { - std::cerr << "\tPercent scanned = " - << m_parser.percentRead() - << "..."<<std::endl; - lastPercentReport = m_parser.percentRead(); - } - - m_parser.getBookmark(startBookmark); - numOfCalls = 0; - } - //call->dump(std::cout, color); - delete call; - } - return true; -} - -void Loader::close() -{ - m_parser.close(); -} - -bool Loader::isCallAFrameMarker(const trace::Call *call) const -{ - std::string name = call->name(); - - switch (m_frameMarker) { - case FrameMarker_SwapBuffers: - return call->flags & trace::CALL_FLAG_END_FRAME; - break; - case FrameMarker_Flush: - return name == "glFlush"; - break; - case FrameMarker_Finish: - return name == "glFinish"; - break; - case FrameMarker_Clear: - return name == "glClear"; - break; - } - return false; -} - -std::vector<trace::Call *> Loader::frame(unsigned idx) -{ - unsigned numOfCalls = numberOfCallsInFrame(idx); - if (numOfCalls) { - const FrameBookmark &frameBookmark = m_frameBookmarks[idx]; - std::vector<trace::Call*> calls(numOfCalls); - m_parser.setBookmark(frameBookmark.start); - - trace::Call *call; - unsigned parsedCalls = 0; - while ((call = m_parser.parse_call())) { - - calls[parsedCalls] = call; - ++parsedCalls; - - if (isCallAFrameMarker(call)) { - break; - } - - } - assert(parsedCalls == numOfCalls); - return calls; - } - return std::vector<trace::Call*>(); -} diff --git a/common/trace_loader.hpp b/common/trace_loader.hpp deleted file mode 100644 index 6873c964..00000000 --- a/common/trace_loader.hpp +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef TRACE_LOADER_HPP -#define TRACE_LOADER_HPP - -#include "trace_file.hpp" -#include "trace_parser.hpp" - -#include <string> -#include <map> -#include <queue> -#include <vector> - -namespace trace { - -class Frame; - -class Loader -{ -public: - enum FrameMarker { - FrameMarker_SwapBuffers, - FrameMarker_Flush, - FrameMarker_Finish, - FrameMarker_Clear - }; -public: - Loader(); - ~Loader(); - - Loader::FrameMarker frameMarker() const; - void setFrameMarker(Loader::FrameMarker marker); - - unsigned numberOfFrames() const; - unsigned numberOfCallsInFrame(unsigned frameIdx) const; - - bool open(const char *filename); - void close(); - - std::vector<trace::Call*> frame(unsigned idx); - -private: - struct FrameBookmark { - FrameBookmark() - : numberOfCalls(0) - {} - FrameBookmark(const ParseBookmark &s) - : start(s), - numberOfCalls(0) - {} - - ParseBookmark start; - unsigned numberOfCalls; - }; - bool isCallAFrameMarker(const trace::Call *call) const; - -private: - trace::Parser m_parser; - FrameMarker m_frameMarker; - - typedef std::map<int, FrameBookmark> FrameBookmarks; - FrameBookmarks m_frameBookmarks; -}; - -} - -#endif // TRACE_LOADER_HPP diff --git a/common/trace_lookup.hpp b/common/trace_lookup.hpp index 7134778d..55655027 100644 --- a/common/trace_lookup.hpp +++ b/common/trace_lookup.hpp @@ -27,8 +27,7 @@ * Helper code for function name indexed lookup tables. */ -#ifndef _TRACE_LOOKUP_HPP_ -#define _TRACE_LOOKUP_HPP_ +#pragma once #include <assert.h> @@ -108,4 +107,3 @@ entryLookup(const char *name, const Entry<T> (& entries)[n], const T & default_) } /* namespace trace */ -#endif /* _TRACE_LOOKUP_HPP_ */ diff --git a/common/trace_model.cpp b/common/trace_model.cpp index baebc18f..c91a9943 100644 --- a/common/trace_model.cpp +++ b/common/trace_model.cpp @@ -25,6 +25,7 @@ #include <string.h> +#include <deque> #include "trace_model.hpp" @@ -61,6 +62,11 @@ String::~String() { } +WString::~WString() { + delete [] value; +} + + Struct::~Struct() { for (std::vector<Value *>::iterator it = members.begin(); it != members.end(); ++it) { delete *it; @@ -74,17 +80,75 @@ Array::~Array() { } } + +#define BLOB_MAX_BOUND_SIZE (1*1024*1024*1024) + +class BoundBlob { +public: + static size_t totalSize; + +private: + size_t size; + char *buf; + +public: + inline + BoundBlob(size_t _size, char *_buf) : + size(_size), + buf(_buf) + { + assert(totalSize + size >= totalSize); + totalSize += size; + } + + inline + ~BoundBlob() { + assert(totalSize >= size); + totalSize -= size; + delete [] buf; + } + + // Fake move constructor + // std::deque:push_back with move semantics was added only from c++11. + BoundBlob(const BoundBlob & other) + { + size = other.size; + buf = other.buf; + const_cast<BoundBlob &>(other).size = 0; + const_cast<BoundBlob &>(other).buf = 0; + } + + // Disallow assignment operator + BoundBlob& operator = (const BoundBlob &); +}; + +size_t BoundBlob::totalSize = 0; + +typedef std::deque<BoundBlob> BoundBlobQueue; +static BoundBlobQueue boundBlobQueue; + + Blob::~Blob() { // Blobs are often bound and referred during many calls, so we can't delete // them here in that case. // // Once bound there is no way to know when they were unbound, which - // effectively means we have to leak them. A better solution would be to - // keep a list of bound pointers, and defer the destruction to when the - // trace in question has been fully processed. + // effectively means we have to leak them. But some applications + // (particularly OpenGL applications that use vertex arrays in user memory) + // we can easily exhaust all memory. So instead we maintain a queue of + // bound blobs and keep the total size bounded. + if (!bound) { delete [] buf; + return; } + + while (!boundBlobQueue.empty() && + BoundBlob::totalSize + size > BLOB_MAX_BOUND_SIZE) { + boundBlobQueue.pop_front(); + } + + boundBlobQueue.push_back(BoundBlob(size, buf)); } StackFrame::~StackFrame() { @@ -108,6 +172,7 @@ bool UInt ::toBool(void) const { return value != 0; } bool Float ::toBool(void) const { return value != 0; } bool Double ::toBool(void) const { return value != 0; } bool String ::toBool(void) const { return true; } +bool WString::toBool(void) const { return true; } bool Struct ::toBool(void) const { return true; } bool Array ::toBool(void) const { return true; } bool Blob ::toBool(void) const { return true; } @@ -195,6 +260,7 @@ void UInt ::visit(Visitor &visitor) { visitor.visit(this); } void Float ::visit(Visitor &visitor) { visitor.visit(this); } void Double ::visit(Visitor &visitor) { visitor.visit(this); } void String ::visit(Visitor &visitor) { visitor.visit(this); } +void WString::visit(Visitor &visitor) { visitor.visit(this); } void Enum ::visit(Visitor &visitor) { visitor.visit(this); } void Bitmask::visit(Visitor &visitor) { visitor.visit(this); } void Struct ::visit(Visitor &visitor) { visitor.visit(this); } @@ -211,6 +277,7 @@ void Visitor::visit(UInt *) { assert(0); } void Visitor::visit(Float *) { assert(0); } void Visitor::visit(Double *) { assert(0); } void Visitor::visit(String *) { assert(0); } +void Visitor::visit(WString *) { assert(0); } void Visitor::visit(Enum *node) { assert(0); } void Visitor::visit(Bitmask *node) { visit(static_cast<UInt *>(node)); } void Visitor::visit(Struct *) { assert(0); } diff --git a/common/trace_model.hpp b/common/trace_model.hpp index 164b1ab4..821adf65 100644 --- a/common/trace_model.hpp +++ b/common/trace_model.hpp @@ -27,8 +27,7 @@ * Object hierarchy for describing the traces in memory. */ -#ifndef _TRACE_MODEL_HPP_ -#define _TRACE_MODEL_HPP_ +#pragma once #include <assert.h> @@ -240,6 +239,19 @@ public: }; +class WString : public Value +{ +public: + WString(const wchar_t * _value) : value(_value) {} + ~WString(); + + bool toBool(void) const; + void visit(Visitor &visitor); + + const wchar_t * value; +}; + + class Enum : public SInt { public: @@ -424,6 +436,7 @@ public: virtual void visit(Float *); virtual void visit(Double *); virtual void visit(String *); + virtual void visit(WString *); virtual void visit(Enum *); virtual void visit(Bitmask *); virtual void visit(Struct *); @@ -570,4 +583,3 @@ public: } /* namespace trace */ -#endif /* _TRACE_MODEL_HPP_ */ diff --git a/common/trace_option.cpp b/common/trace_option.cpp index 5c4563fe..feae1496 100644 --- a/common/trace_option.cpp +++ b/common/trace_option.cpp @@ -28,6 +28,7 @@ #include <string.h> #include <iostream> +#include <stdlib.h> namespace trace { @@ -50,4 +51,12 @@ boolOption(const char *option, bool default_) { return default_; } +int +intOption(const char *option, int default_) { + if (!option) { + return default_; + } + return atoi(option); +} + } /* namespace trace */ diff --git a/common/trace_option.hpp b/common/trace_option.hpp index e22a422c..f11d4658 100644 --- a/common/trace_option.hpp +++ b/common/trace_option.hpp @@ -24,14 +24,15 @@ * **************************************************************************/ -#ifndef _TRACE_OPTION_HPP_ -#define _TRACE_OPTION_HPP_ +#pragma once namespace trace { bool boolOption(const char *option, bool default_ = true); +int +intOption(const char *option, int default_ = 0); + } /* namespace trace */ -#endif /* _TRACE_CALLSET_HPP_ */ diff --git a/common/trace_ostream.hpp b/common/trace_ostream.hpp new file mode 100644 index 00000000..502905b4 --- /dev/null +++ b/common/trace_ostream.hpp @@ -0,0 +1,52 @@ +/************************************************************************** + * + * Copyright 2015 VMware, Inc. + * Copyright 2011 Zack Rusin + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + +#pragma once + +#include <stdlib.h> + + +namespace trace { + + +class OutStream { +public: + virtual ~OutStream() {} + + virtual bool write(const void *buffer, size_t length) = 0; + virtual void flush(void) = 0; +}; + + +OutStream * +createSnappyStream(const char *filename); + +OutStream * +createZLibStream(const char *filename); + + +} /* namespace trace */ diff --git a/common/trace_ostream_snappy.cpp b/common/trace_ostream_snappy.cpp new file mode 100644 index 00000000..a1a28673 --- /dev/null +++ b/common/trace_ostream_snappy.cpp @@ -0,0 +1,206 @@ +/************************************************************************** + * + * Copyright 2015 VMware, Inc + * Copyright 2011 Zack Rusin + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + +#include "trace_ostream.hpp" + +#include <fstream> + +#include <assert.h> +#include <string.h> + +#include <snappy.h> + +#include "os.hpp" +#include "trace_snappy.hpp" + + +#define SNAPPY_CHUNK_SIZE (1 * 1024 * 1024) + + +using namespace trace; + + +class SnappyOutStream : public OutStream { +public: + SnappyOutStream(const char *filename); + ~SnappyOutStream(); + + SnappyOutStream(void); + bool write(const void *buffer, size_t length); + void flush(void); + bool isOpen(void) { + return m_stream.is_open(); + } + + +private: + void close(); + + inline size_t usedCacheSize() const + { + assert(m_cachePtr >= m_cache); + return m_cachePtr - m_cache; + } + inline size_t freeCacheSize() const + { + assert(m_cacheSize >= usedCacheSize()); + if (m_cacheSize > 0) { + return m_cacheSize - usedCacheSize(); + } else { + return 0; + } + } + inline bool endOfData() const + { + return m_stream.eof() && freeCacheSize() == 0; + } + void flushWriteCache(); + void createCache(size_t size); + void writeCompressedLength(size_t length); +private: + std::ofstream m_stream; + size_t m_cacheMaxSize; + size_t m_cacheSize; + char *m_cache; + char *m_cachePtr; + + char *m_compressedCache; +}; + +SnappyOutStream::SnappyOutStream(const char *filename) + : m_cacheMaxSize(SNAPPY_CHUNK_SIZE), + m_cacheSize(m_cacheMaxSize), + m_cache(new char [m_cacheMaxSize]), + m_cachePtr(m_cache) +{ + size_t maxCompressedLength = + snappy::MaxCompressedLength(SNAPPY_CHUNK_SIZE); + m_compressedCache = new char[maxCompressedLength]; + + std::ios_base::openmode fmode = std::fstream::binary + | std::fstream::out + | std::fstream::trunc; + m_stream.open(filename, fmode); + if (m_stream.is_open()) { + m_stream << SNAPPY_BYTE1; + m_stream << SNAPPY_BYTE2; + } +} + +SnappyOutStream::~SnappyOutStream() +{ + close(); + delete [] m_compressedCache; + delete [] m_cache; +} + +bool SnappyOutStream::write(const void *buffer, size_t length) +{ + if (freeCacheSize() > length) { + memcpy(m_cachePtr, buffer, length); + m_cachePtr += length; + } else if (freeCacheSize() == length) { + memcpy(m_cachePtr, buffer, length); + m_cachePtr += length; + flushWriteCache(); + } else { + size_t sizeToWrite = length; + + while (sizeToWrite >= freeCacheSize()) { + size_t endSize = freeCacheSize(); + size_t offset = length - sizeToWrite; + memcpy(m_cachePtr, (const char*)buffer + offset, endSize); + sizeToWrite -= endSize; + m_cachePtr += endSize; + flushWriteCache(); + } + if (sizeToWrite) { + size_t offset = length - sizeToWrite; + memcpy(m_cachePtr, (const char*)buffer + offset, sizeToWrite); + m_cachePtr += sizeToWrite; + } + } + + return true; +} + +void SnappyOutStream::close() +{ + flushWriteCache(); + m_stream.close(); + delete [] m_cache; + m_cache = NULL; + m_cachePtr = NULL; +} + +void SnappyOutStream::flush(void) +{ + flushWriteCache(); + m_stream.flush(); +} + +void SnappyOutStream::flushWriteCache(void) +{ + size_t inputLength = usedCacheSize(); + + if (inputLength) { + size_t compressedLength; + + ::snappy::RawCompress(m_cache, inputLength, + m_compressedCache, &compressedLength); + + writeCompressedLength(compressedLength); + m_stream.write(m_compressedCache, compressedLength); + m_cachePtr = m_cache; + } + assert(m_cachePtr == m_cache); +} + +void SnappyOutStream::writeCompressedLength(size_t length) +{ + unsigned char buf[4]; + buf[0] = length & 0xff; length >>= 8; + buf[1] = length & 0xff; length >>= 8; + buf[2] = length & 0xff; length >>= 8; + buf[3] = length & 0xff; length >>= 8; + assert(length == 0); + m_stream.write((const char *)buf, sizeof buf); +} + + +OutStream * +trace::createSnappyStream(const char *filename) +{ + SnappyOutStream *outStream = new SnappyOutStream(filename); + if (!outStream->isOpen()) { + os::log("error: could not open %s for writing\n", filename); + delete outStream; + outStream = nullptr; + } + + return outStream; +} diff --git a/common/trace_ostream_zlib.cpp b/common/trace_ostream_zlib.cpp new file mode 100644 index 00000000..54893870 --- /dev/null +++ b/common/trace_ostream_zlib.cpp @@ -0,0 +1,99 @@ +/************************************************************************** + * + * Copyright 2015 VMware, Inc. + * Copyright 2011 Zack Rusin + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + +#include "trace_ostream.hpp" + + +#include <assert.h> +#include <string.h> + +#include <zlib.h> + +#include "os.hpp" + +#include <iostream> + + +using namespace trace; + + +class ZLibOutStream : public OutStream { +public: + ZLibOutStream(gzFile file); + virtual ~ZLibOutStream(); + +protected: + virtual bool write(const void *buffer, size_t length); + virtual void close(); + virtual void flush(); +private: + gzFile m_gzFile; +}; + +ZLibOutStream::ZLibOutStream(gzFile file) + : m_gzFile(file) +{ +} + +ZLibOutStream::~ZLibOutStream() +{ + close(); +} + +bool ZLibOutStream::write(const void *buffer, size_t length) +{ + return gzwrite(m_gzFile, buffer, unsigned(length)) != -1; +} + +void ZLibOutStream::close() +{ + if (m_gzFile) { + gzclose(m_gzFile); + m_gzFile = nullptr; + } +} + +void ZLibOutStream::flush() +{ + gzflush(m_gzFile, Z_SYNC_FLUSH); +} + + +OutStream * +trace::createZLibStream(const char *filename) +{ + gzFile file = gzopen(filename, "wb"); + if (!file) { + return nullptr; + } + + // Currently we only use gzip for offline compression, so aim for maximum + // compression + gzsetparams(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY); + + return new ZLibOutStream(file); +} diff --git a/common/trace_parser.cpp b/common/trace_parser.cpp index a9cdd0fb..99fa5e83 100644 --- a/common/trace_parser.cpp +++ b/common/trace_parser.cpp @@ -673,6 +673,9 @@ Value *Parser::parse_value(void) { case trace::TYPE_REPR: value = parse_repr(); break; + case trace::TYPE_WSTRING: + value = parse_wstring(); + break; default: std::cerr << "error: unknown type " << c << "\n"; exit(1); @@ -734,6 +737,9 @@ void Parser::scan_value(void) { case trace::TYPE_REPR: scan_repr(); break; + case trace::TYPE_WSTRING: + scan_wstring(); + break; default: std::cerr << "error: unknown type " << c << "\n"; exit(1); @@ -918,6 +924,28 @@ void Parser::scan_repr() { } +Value *Parser::parse_wstring() { + size_t len = read_uint(); + wchar_t * value = new wchar_t[len + 1]; + for (size_t i = 0; i < len; ++i) { + value[i] = read_uint(); + } + value[len] = 0; +#if TRACE_VERBOSE + std::cerr << "\tWSTRING \"" << value << "\"\n"; +#endif + return new WString(value); +} + + +void Parser::scan_wstring() { + size_t len = read_uint(); + for (size_t i = 0; i < len; ++i) { + skip_uint(); + } +} + + const char * Parser::read_string(void) { size_t len = read_uint(); char * value = new char[len + 1]; diff --git a/common/trace_parser.hpp b/common/trace_parser.hpp index 7bf0a7dc..b638aa11 100644 --- a/common/trace_parser.hpp +++ b/common/trace_parser.hpp @@ -23,8 +23,7 @@ * **************************************************************************/ -#ifndef _TRACE_PARSER_HPP_ -#define _TRACE_PARSER_HPP_ +#pragma once #include <iostream> @@ -46,7 +45,21 @@ struct ParseBookmark }; -class Parser +// Parser interface +class AbstractParser +{ +public: + virtual ~AbstractParser() {} + virtual Call *parse_call(void) = 0; + virtual void getBookmark(ParseBookmark &bookmark) = 0; + virtual void setBookmark(const ParseBookmark &bookmark) = 0; + virtual bool open(const char *filename) = 0; + virtual void close(void) = 0; + virtual unsigned long long getVersion(void) const = 0; +}; + + +class Parser: public AbstractParser { protected: File *file; @@ -96,8 +109,8 @@ protected: unsigned next_call_no; -public: unsigned long long version; +public: API api; Parser(); @@ -121,6 +134,10 @@ public: void setBookmark(const ParseBookmark &bookmark); + unsigned long long getVersion(void) const { + return version; + } + int percentRead() { return file->percentRead(); @@ -139,9 +156,11 @@ protected: EnumSig *parse_enum_sig(); BitmaskSig *parse_bitmask_sig(); +public: static CallFlags lookupCallFlags(const char *name); +protected: Call *parse_Call(Mode mode); void parse_enter(Mode mode); @@ -204,6 +223,9 @@ protected: Value *parse_repr(); void scan_repr(); + Value *parse_wstring(); + void scan_wstring(); + const char * read_string(void); void skip_string(void); @@ -218,6 +240,9 @@ protected: }; +AbstractParser * +lastFrameLoopParser(AbstractParser *parser, int loopCount); + + } /* namespace trace */ -#endif /* _TRACE_PARSER_HPP_ */ diff --git a/common/trace_parser_flags.cpp b/common/trace_parser_flags.cpp index 35bac214..d4a07257 100644 --- a/common/trace_parser_flags.cpp +++ b/common/trace_parser_flags.cpp @@ -1,5 +1,7 @@ +/* Generated by re2c 0.13.5 */ /************************************************************************** * + * Copyright 2015 VMware, Inc. * Copyright 2011 Jose Fonseca * All Rights Reserved. * @@ -24,14 +26,23 @@ **************************************************************************/ -/** +/* * Label functions based on their name. + * + * Compile with RE2C as + * + * re2c -is --no-generation-date trace_parser_flags.cpp.re > trace_parser_flags.cpp + * + * TODO: Use std::regex once GCC 4.9 becomes widely available -- https://github.com/apitrace/apitrace/issues/370 */ -#include "trace_lookup.hpp" #include "trace_parser.hpp" +#include <assert.h> + +#include "trace_lookup.hpp" + using namespace trace; @@ -57,43 +68,12 @@ const Entry<CallFlags> callFlagTable[] = { { "CGLFlushDrawable", CALL_FLAG_END_FRAME }, { "CGLGetCurrentContext", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, - { "ID3D10Device1::CheckMultisampleQualityLevels", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, - { "ID3D10Device1::Draw", CALL_FLAG_RENDER }, - { "ID3D10Device1::DrawAuto", CALL_FLAG_RENDER }, - { "ID3D10Device1::DrawIndexed", CALL_FLAG_RENDER }, - { "ID3D10Device1::DrawIndexedInstanced", CALL_FLAG_RENDER }, - { "ID3D10Device1::DrawInstanced", CALL_FLAG_RENDER }, - { "ID3D10Device1::OMSetRenderTargets", CALL_FLAG_SWAP_RENDERTARGET }, - { "ID3D10Device::CheckMultisampleQualityLevels", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, - { "ID3D10Device::Draw", CALL_FLAG_RENDER }, - { "ID3D10Device::DrawAuto", CALL_FLAG_RENDER }, - { "ID3D10Device::DrawIndexed", CALL_FLAG_RENDER }, - { "ID3D10Device::DrawIndexedInstanced", CALL_FLAG_RENDER }, - { "ID3D10Device::DrawInstanced", CALL_FLAG_RENDER }, - { "ID3D10Device::OMSetRenderTargets", CALL_FLAG_SWAP_RENDERTARGET }, - { "ID3D11Device::CheckMultisampleQualityLevels", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, - { "ID3D11DeviceContext1::Draw", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext1::DrawAuto", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext1::DrawIndexed", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext1::DrawIndexedInstanced", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext1::DrawIndexedInstancedIndirect", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext1::DrawInstanced", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext1::DrawInstancedIndirect", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext1::ExecuteCommandList", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext1::OMSetRenderTargets", CALL_FLAG_SWAP_RENDERTARGET }, - { "ID3D11DeviceContext1::OMSetRenderTargetsAndUnorderedAccessViews", CALL_FLAG_SWAP_RENDERTARGET }, - { "ID3D11DeviceContext::Draw", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext::DrawAuto", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext::DrawIndexed", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext::DrawIndexedInstanced", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext::DrawIndexedInstancedIndirect", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext::DrawInstanced", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext::DrawInstancedIndirect", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext::ExecuteCommandList", CALL_FLAG_RENDER }, - { "ID3D11DeviceContext::OMSetRenderTargets", CALL_FLAG_SWAP_RENDERTARGET }, - { "ID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews", CALL_FLAG_SWAP_RENDERTARGET }, - { "IDXGISwapChain::Present", CALL_FLAG_SWAPBUFFERS }, - { "IDXGISwapChainDWM::Present", CALL_FLAG_SWAPBUFFERS }, + { "D3DPERF_BeginEvent", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "D3DPERF_EndEvent", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP }, + { "D3DPERF_SetMarker", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER }, + { "ID3DUserDefinedAnnotation::BeginEvent", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "ID3DUserDefinedAnnotation::EndEvent", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP }, + { "ID3DUserDefinedAnnotation::SetMarker", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER }, { "IDirect3D8::CheckDeviceFormat", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "IDirect3D8::EnumAdapterModes", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "IDirect3D8::GetAdapterModeCount", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, @@ -106,6 +86,21 @@ callFlagTable[] = { { "IDirect3D9Ex::EnumAdapterModes", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "IDirect3D9Ex::GetAdapterModeCount", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "IDirect3D9Ex::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3DDevice2::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice2::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawIndexedPrimitiveStrided", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawIndexedPrimitiveVB", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawPrimitiveStrided", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawPrimitiveVB", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::Clear", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawIndexedPrimitiveStrided", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawIndexedPrimitiveVB", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawPrimitiveStrided", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawPrimitiveVB", CALL_FLAG_RENDER }, { "IDirect3DDevice8::Clear", CALL_FLAG_RENDER }, { "IDirect3DDevice8::DrawIndexedPrimitive", CALL_FLAG_RENDER }, { "IDirect3DDevice8::DrawIndexedPrimitiveUP", CALL_FLAG_RENDER }, @@ -141,6 +136,10 @@ callFlagTable[] = { { "IDirect3DDevice9Ex::SetRenderTarget", CALL_FLAG_SWAP_RENDERTARGET }, { "IDirect3DSwapChain9::Present", CALL_FLAG_SWAPBUFFERS }, { "IDirect3DSwapChain9Ex::Present", CALL_FLAG_SWAPBUFFERS }, + { "IDirect3DViewport2::Clear", CALL_FLAG_RENDER }, + { "IDirect3DViewport3::Clear", CALL_FLAG_RENDER }, + { "IDirect3DViewport3::Clear2", CALL_FLAG_RENDER }, + { "IDirect3DViewport::Clear", CALL_FLAG_RENDER }, { "eglGetConfigAttrib", CALL_FLAG_VERBOSE }, { "eglGetProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "eglQueryString", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, @@ -148,47 +147,14 @@ callFlagTable[] = { { "glAreProgramsResidentNV", CALL_FLAG_NO_SIDE_EFFECTS }, { "glAreTexturesResident", CALL_FLAG_NO_SIDE_EFFECTS }, { "glAreTexturesResidentEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glBindFramebuffer", CALL_FLAG_SWAP_RENDERTARGET }, - { "glBindFramebufferEXT", CALL_FLAG_SWAP_RENDERTARGET }, - { "glBindFramebufferOES", CALL_FLAG_SWAP_RENDERTARGET }, - { "glBlitFramebuffer", CALL_FLAG_RENDER }, - { "glBlitFramebufferEXT", CALL_FLAG_RENDER }, { "glBufferRegionEnabled", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glCallList", CALL_FLAG_RENDER }, - { "glCallLists", CALL_FLAG_RENDER }, - { "glClear", CALL_FLAG_RENDER }, { "glDebugMessageControl", CALL_FLAG_NO_SIDE_EFFECTS }, { "glDebugMessageControlARB", CALL_FLAG_NO_SIDE_EFFECTS }, { "glDebugMessageEnableAMD", CALL_FLAG_NO_SIDE_EFFECTS }, { "glDebugMessageInsert", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, { "glDebugMessageInsertAMD", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, { "glDebugMessageInsertARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, - { "glDrawArrays", CALL_FLAG_RENDER }, - { "glDrawArraysEXT", CALL_FLAG_RENDER }, - { "glDrawArraysIndirect", CALL_FLAG_RENDER }, - { "glDrawArraysInstanced", CALL_FLAG_RENDER }, - { "glDrawArraysInstancedARB", CALL_FLAG_RENDER }, - { "glDrawArraysInstancedBaseInstance", CALL_FLAG_RENDER }, - { "glDrawArraysInstancedEXT", CALL_FLAG_RENDER }, - { "glDrawElementArrayAPPLE", CALL_FLAG_RENDER }, - { "glDrawElementArrayATI", CALL_FLAG_RENDER }, - { "glDrawElements", CALL_FLAG_RENDER }, - { "glDrawElementsBaseVertex", CALL_FLAG_RENDER }, - { "glDrawElementsIndirect", CALL_FLAG_RENDER }, - { "glDrawElementsInstanced", CALL_FLAG_RENDER }, - { "glDrawElementsInstancedARB", CALL_FLAG_RENDER }, - { "glDrawElementsInstancedBaseInstance", CALL_FLAG_RENDER }, - { "glDrawElementsInstancedBaseVertex", CALL_FLAG_RENDER }, - { "glDrawElementsInstancedBaseVertexBaseInstance", CALL_FLAG_RENDER }, - { "glDrawElementsInstancedEXT", CALL_FLAG_RENDER }, - { "glDrawMeshArraysSUN", CALL_FLAG_RENDER }, - { "glDrawPixels", CALL_FLAG_RENDER }, - { "glDrawRangeElementArrayAPPLE", CALL_FLAG_RENDER }, - { "glDrawRangeElementArrayATI", CALL_FLAG_RENDER }, - { "glDrawRangeElements", CALL_FLAG_RENDER }, - { "glDrawRangeElementsBaseVertex", CALL_FLAG_RENDER }, - { "glDrawRangeElementsEXT", CALL_FLAG_RENDER }, - { "glEnd", CALL_FLAG_RENDER }, + { "glDebugMessageInsertKHR", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, { "glFrameTerminatorGREMEDY", CALL_FLAG_END_FRAME }, { "glGetActiveAtomicCounterBufferiv", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetActiveAttrib", CALL_FLAG_NO_SIDE_EFFECTS }, @@ -246,9 +212,6 @@ callFlagTable[] = { { "glGetFenceivNV", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetFinalCombinerInputParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetFinalCombinerInputParameterivNV", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetFloatIndexedvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetFloati_v", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetFloatv", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetFogFuncSGIS", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetFragDataIndex", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetFragmentLightfvSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, @@ -270,13 +233,6 @@ callFlagTable[] = { { "glGetImageTransformParameterivHP", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetInfoLogARB", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetInstrumentsSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetInteger64i_v", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetInteger64v", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetIntegerIndexedvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetIntegeri_v", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetIntegerui64i_vNV", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetIntegerui64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetIntegerv", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetInternalformati64v", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetInternalformativ", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetInvariantBooleanvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, @@ -416,21 +372,6 @@ callFlagTable[] = { { "glGetTexGendv", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetTexGenfv", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetTexGeniv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTexLevelParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTexLevelParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTexParameterIiv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTexParameterIivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTexParameterIuiv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTexParameterIuivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTexParameterPointervAPPLE", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTexParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTexParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTextureLevelParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTextureLevelParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTextureParameterIivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTextureParameterIuivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTextureParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetTextureParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetTrackMatrixivNV", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetTransformFeedbackVarying", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetTransformFeedbackVaryingEXT", CALL_FLAG_NO_SIDE_EFFECTS }, @@ -456,28 +397,6 @@ callFlagTable[] = { { "glGetVertexArrayIntegervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetVertexArrayPointeri_vEXT", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetVertexArrayPointervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribArrayObjectfvATI", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribArrayObjectivATI", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribIiv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribIivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribIuiv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribIuivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribLdv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribLdvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribLi64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribLui64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribPointerv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribPointervARB", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribPointervNV", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribdv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribdvARB", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribdvNV", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribfv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribiv", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribivARB", CALL_FLAG_NO_SIDE_EFFECTS }, - { "glGetVertexAttribivNV", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetVideoCaptureStreamdvNV", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetVideoCaptureStreamfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, { "glGetVideoCaptureStreamivNV", CALL_FLAG_NO_SIDE_EFFECTS }, @@ -530,30 +449,25 @@ callFlagTable[] = { { "glIsVertexArray", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "glIsVertexArrayAPPLE", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "glIsVertexAttribEnabledAPPLE", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, - { "glMultiDrawArrays", CALL_FLAG_RENDER }, - { "glMultiDrawArraysEXT", CALL_FLAG_RENDER }, - { "glMultiDrawArraysIndirect", CALL_FLAG_RENDER }, - { "glMultiDrawArraysIndirectAMD", CALL_FLAG_RENDER }, - { "glMultiDrawElementArrayAPPLE", CALL_FLAG_RENDER }, - { "glMultiDrawElements", CALL_FLAG_RENDER }, - { "glMultiDrawElementsBaseVertex", CALL_FLAG_RENDER }, - { "glMultiDrawElementsEXT", CALL_FLAG_RENDER }, - { "glMultiDrawElementsIndirect", CALL_FLAG_RENDER }, - { "glMultiDrawElementsIndirectAMD", CALL_FLAG_RENDER }, - { "glMultiDrawRangeElementArrayAPPLE", CALL_FLAG_RENDER }, - { "glMultiModeDrawArraysIBM", CALL_FLAG_RENDER }, - { "glMultiModeDrawElementsIBM", CALL_FLAG_RENDER }, { "glObjectLabel", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glObjectLabelKHR", CALL_FLAG_NO_SIDE_EFFECTS }, { "glObjectPtrLabel", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glObjectPtrLabelKHR", CALL_FLAG_NO_SIDE_EFFECTS }, { "glPopDebugGroup", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP}, + { "glPopDebugGroupKHR", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP}, { "glPopGroupMarkerEXT", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP}, { "glPushDebugGroup", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "glPushDebugGroupKHR", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, { "glPushGroupMarkerEXT", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, { "glStringMarkerGREMEDY", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER }, { "glXGetClientString", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetConfig", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "glXGetCurrentContext", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "glXGetCurrentDisplay", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentDisplayEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "glXGetCurrentDrawable", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentReadDrawable", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentReadDrawableSGI", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "glXGetFBConfigAttrib", CALL_FLAG_VERBOSE }, { "glXGetFBConfigAttribSGIX", CALL_FLAG_VERBOSE }, { "glXGetProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, @@ -567,7 +481,11 @@ callFlagTable[] = { { "wglGetCurrentContext", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "wglGetCurrentDC", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "wglGetDefaultProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetExtensionsStringARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetExtensionsStringEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "wglGetPixelFormat", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetPixelFormatAttribivARB", CALL_FLAG_VERBOSE }, + { "wglGetPixelFormatAttribivEXT", CALL_FLAG_VERBOSE }, { "wglGetProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, { "wglSwapBuffers", CALL_FLAG_SWAPBUFFERS }, { "wglSwapLayerBuffers", CALL_FLAG_SWAPBUFFERS }, @@ -580,6 +498,4523 @@ callFlagTable[] = { * Lookup call flags by name. */ CallFlags -Parser::lookupCallFlags(const char *name) { - return entryLookup(name, callFlagTable, defaultCallFlags); +Parser::lookupCallFlags(const char *name) +{ + const char *p = name; + const char *q; + + + { + char yych; + + yych = *p; + if (yych == 'I') goto yy4; + if (yych != 'g') goto yy5; + yych = *(q = ++p); + if (yych == 'l') goto yy150; +yy3: + { return entryLookup(name, callFlagTable, defaultCallFlags); } +yy4: + yych = *(q = ++p); + if (yych == 'D') goto yy6; + goto yy3; +yy5: + yych = *++p; + goto yy3; +yy6: + yych = *++p; + if (yych == '3') goto yy9; + if (yych == 'X') goto yy8; +yy7: + p = q; + goto yy3; +yy8: + yych = *++p; + if (yych == 'G') goto yy120; + goto yy7; +yy9: + yych = *++p; + if (yych != 'D') goto yy7; + yych = *++p; + if (yych != '1') goto yy7; + yych = *++p; + if (yych <= '/') goto yy7; + if (yych <= '0') goto yy12; + if (yych <= '1') goto yy13; + goto yy7; +yy12: + yych = *++p; + if (yych == 'D') goto yy111; + goto yy7; +yy13: + yych = *++p; + if (yych != 'D') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 'v') goto yy7; + yych = *++p; + if (yych != 'i') goto yy7; + yych = *++p; + if (yych != 'c') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 'C') goto yy22; + yych = *++p; + if (yych == 'o') goto yy56; + goto yy7; +yy21: + ++p; + yych = *p; +yy22: + if (yych <= '/') goto yy7; + if (yych <= '9') goto yy21; + if (yych >= ';') goto yy7; + yych = *++p; + if (yych != ':') goto yy7; + yych = *++p; + if (yych != 'C') goto yy7; +yy25: + yych = *++p; + if (yych != 'h') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 'c') goto yy7; + yych = *++p; + if (yych != 'k') goto yy7; + yych = *++p; + if (yych != 'M') goto yy7; + yych = *++p; + if (yych != 'u') goto yy7; + yych = *++p; + if (yych != 'l') goto yy7; + yych = *++p; + if (yych != 't') goto yy7; + yych = *++p; + if (yych != 'i') goto yy7; + yych = *++p; + if (yych != 's') goto yy7; + yych = *++p; + if (yych != 'a') goto yy7; + yych = *++p; + if (yych != 'm') goto yy7; + yych = *++p; + if (yych != 'p') goto yy7; + yych = *++p; + if (yych != 'l') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 'Q') goto yy7; + yych = *++p; + if (yych != 'u') goto yy7; + yych = *++p; + if (yych != 'a') goto yy7; + yych = *++p; + if (yych != 'l') goto yy7; + yych = *++p; + if (yych != 'i') goto yy7; + yych = *++p; + if (yych != 't') goto yy7; + yych = *++p; + if (yych != 'y') goto yy7; + yych = *++p; + if (yych != 'L') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 'v') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 'l') goto yy7; + yych = *++p; + if (yych != 's') goto yy7; + yych = *++p; + if (yych >= 0x01) goto yy7; + ++p; + { + return CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE; + } +yy56: + yych = *++p; + if (yych != 'n') goto yy7; + yych = *++p; + if (yych != 't') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 'x') goto yy7; + yych = *++p; + if (yych != 't') goto yy7; +yy61: + ++p; + yych = *p; + if (yych <= '/') goto yy7; + if (yych <= '9') goto yy61; + if (yych >= ';') goto yy7; + yych = *++p; + if (yych != ':') goto yy7; + yych = *++p; + if (yych <= 'E') { + if (yych <= 'C') goto yy7; + if (yych <= 'D') goto yy66; + goto yy67; + } else { + if (yych != 'O') goto yy7; + } +yy65: + yych = *++p; + if (yych == 'M') goto yy91; + goto yy7; +yy66: + yych = *++p; + if (yych == 'r') goto yy87; + goto yy7; +yy67: + yych = *++p; + if (yych != 'x') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 'c') goto yy7; + yych = *++p; + if (yych != 'u') goto yy7; + yych = *++p; + if (yych != 't') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 'C') goto yy7; + yych = *++p; + if (yych != 'o') goto yy7; + yych = *++p; + if (yych != 'm') goto yy7; + yych = *++p; + if (yych != 'm') goto yy7; + yych = *++p; + if (yych != 'a') goto yy7; + yych = *++p; + if (yych != 'n') goto yy7; + yych = *++p; + if (yych != 'd') goto yy7; + yych = *++p; + if (yych != 'L') goto yy7; + yych = *++p; + if (yych != 'i') goto yy7; + yych = *++p; + if (yych != 's') goto yy7; + yych = *++p; + if (yych != 't') goto yy7; + yych = *++p; + if (yych >= 0x01) goto yy7; +yy85: + ++p; + { + return CALL_FLAG_RENDER; + } +yy87: + yych = *++p; + if (yych != 'a') goto yy7; + yych = *++p; + if (yych != 'w') goto yy7; +yy89: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych <= 0x00) goto yy85; + goto yy7; + } else { + if (yych <= '9') goto yy89; + if (yych <= '@') goto yy7; + goto yy89; + } + } else { + if (yych <= '_') { + if (yych <= '^') goto yy7; + goto yy89; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy89; + goto yy7; + } + } +yy91: + yych = *++p; + if (yych != 'S') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 't') goto yy7; + yych = *++p; + if (yych != 'R') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 'n') goto yy7; + yych = *++p; + if (yych != 'd') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 'r') goto yy7; + yych = *++p; + if (yych != 'T') goto yy7; + yych = *++p; + if (yych != 'a') goto yy7; + yych = *++p; + if (yych != 'r') goto yy7; + yych = *++p; + if (yych != 'g') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 't') goto yy7; + yych = *++p; + if (yych != 's') goto yy7; +yy107: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych >= 0x01) goto yy7; + } else { + if (yych <= '9') goto yy107; + if (yych <= '@') goto yy7; + goto yy107; + } + } else { + if (yych <= '_') { + if (yych <= '^') goto yy7; + goto yy107; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy107; + goto yy7; + } + } + ++p; + { + return CALL_FLAG_SWAP_RENDERTARGET; + } +yy111: + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 'v') goto yy7; + yych = *++p; + if (yych != 'i') goto yy7; + yych = *++p; + if (yych != 'c') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; +yy116: + ++p; + yych = *p; + if (yych <= '/') goto yy7; + if (yych <= '9') goto yy116; + if (yych >= ';') goto yy7; + yych = *++p; + if (yych != ':') goto yy7; + yych = *++p; + if (yych <= 'D') { + if (yych <= 'B') goto yy7; + if (yych <= 'C') goto yy25; + goto yy66; + } else { + if (yych <= 'E') goto yy67; + if (yych == 'O') goto yy65; + goto yy7; + } +yy120: + yych = *++p; + if (yych != 'I') goto yy7; + yych = *++p; + if (yych == 'D') goto yy122; + if (yych == 'S') goto yy123; + goto yy7; +yy122: + yych = *++p; + if (yych == 'e') goto yy145; + goto yy7; +yy123: + yych = *++p; + if (yych != 'w') goto yy7; + yych = *++p; + if (yych != 'a') goto yy7; + yych = *++p; + if (yych != 'p') goto yy7; + yych = *++p; + if (yych != 'C') goto yy7; + yych = *++p; + if (yych != 'h') goto yy7; + yych = *++p; + if (yych != 'a') goto yy7; + yych = *++p; + if (yych != 'i') goto yy7; + yych = *++p; + if (yych != 'n') goto yy7; +yy131: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= '/') goto yy7; + goto yy131; + } else { + if (yych <= ':') goto yy133; + if (yych <= '@') goto yy7; + goto yy131; + } + } else { + if (yych <= '_') { + if (yych <= '^') goto yy7; + goto yy131; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy131; + goto yy7; + } + } +yy133: + yych = *++p; + if (yych != ':') goto yy7; + yych = *++p; + if (yych != 'P') goto yy7; + yych = *++p; + if (yych != 'r') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 's') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych != 'n') goto yy7; + yych = *++p; + if (yych != 't') goto yy7; +yy141: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych >= 0x01) goto yy7; + } else { + if (yych <= '9') goto yy141; + if (yych <= '@') goto yy7; + goto yy141; + } + } else { + if (yych <= '_') { + if (yych <= '^') goto yy7; + goto yy141; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy141; + goto yy7; + } + } + ++p; + { + return CALL_FLAG_END_FRAME; + } +yy145: + yych = *++p; + if (yych != 'c') goto yy7; + yych = *++p; + if (yych != 'o') goto yy7; + yych = *++p; + if (yych != 'd') goto yy7; + yych = *++p; + if (yych != 'e') goto yy7; + yych = *++p; + if (yych == 'S') goto yy123; + goto yy7; +yy150: + yych = *++p; + switch (yych) { + case 'A': + case 'F': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': goto yy151; + case 'B': goto yy152; + case 'C': goto yy153; + case 'D': goto yy154; + case 'E': goto yy155; + case 'G': goto yy156; + case 'R': goto yy157; + default: goto yy7; + } +yy151: + ++p; + yych = *p; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy159; + goto yy7; +yy152: + yych = *++p; + if (yych <= 'i') { + if (yych <= '`') goto yy7; + if (yych <= 'h') goto yy159; + goto yy440; + } else { + if (yych == 'l') goto yy441; + if (yych <= 'z') goto yy159; + goto yy7; + } +yy153: + yych = *++p; + if (yych <= 'k') { + if (yych <= '`') goto yy7; + if (yych <= 'a') goto yy431; + goto yy159; + } else { + if (yych <= 'l') goto yy430; + if (yych <= 'z') goto yy159; + goto yy7; + } +yy154: + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'r') goto yy344; + if (yych <= 'z') goto yy159; + goto yy7; +yy155: + yych = *++p; + if (yych <= 'n') { + if (yych <= '`') goto yy7; + if (yych <= 'm') goto yy159; + goto yy335; + } else { + if (yych == 'v') goto yy334; + if (yych <= 'z') goto yy159; + goto yy7; + } +yy156: + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'e') goto yy228; + if (yych <= 'z') goto yy159; + goto yy7; +yy157: + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'e') goto yy158; + if (yych <= 'z') goto yy159; + goto yy7; +yy158: + yych = *++p; + if (yych == 'c') goto yy218; + goto yy160; +yy159: + ++p; + yych = *p; +yy160: + if (yych <= 'D') { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy151; + } else { + if (yych <= 'Z') goto yy151; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy159; + goto yy7; + } +yy161: + ++p; + yych = *p; + if (yych <= '`') goto yy7; + if (yych == 'r') goto yy162; + if (yych <= 'z') goto yy159; + goto yy7; +yy162: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'a') goto yy163; + if (yych <= 'z') goto yy159; + goto yy7; + } +yy163: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'v') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 'w') goto yy164; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy164: + ++p; + yych = *p; + if (yych <= 'L') { + if (yych <= 'C') { + if (yych <= '@') goto yy7; + if (yych <= 'A') goto yy167; + goto yy151; + } else { + if (yych <= 'D') goto yy161; + if (yych <= 'E') goto yy168; + goto yy151; + } + } else { + if (yych <= 'R') { + if (yych <= 'M') goto yy166; + if (yych <= 'Q') goto yy151; + } else { + if (yych <= 'Z') goto yy151; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy165: + ++p; + yych = *p; + if (yych <= '`') goto yy7; + if (yych <= 'a') goto yy215; + if (yych <= 'z') goto yy159; + goto yy7; +yy166: + ++p; + yych = *p; + if (yych <= '`') goto yy7; + if (yych == 'e') goto yy212; + if (yych <= 'z') goto yy159; + goto yy7; +yy167: + ++p; + yych = *p; + if (yych <= '`') goto yy7; + if (yych == 'r') goto yy208; + if (yych <= 'z') goto yy159; + goto yy7; +yy168: + ++p; + yych = *p; + if (yych <= '`') goto yy7; + if (yych == 'l') goto yy169; + if (yych <= 'z') goto yy159; + goto yy7; +yy169: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'd') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 'e') goto yy170; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy170: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'l') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 'm') goto yy171; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy171: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'd') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 'e') goto yy172; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy172: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'm') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 'n') goto yy173; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy173: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 's') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 't') goto yy174; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy174: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'r') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 's') goto yy175; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy175: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= 0x00) goto yy178; + if (yych <= '@') goto yy7; + if (yych >= 'D') goto yy177; + } else { + if (yych <= 'Z') goto yy176; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy159; + goto yy7; + } +yy176: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= 0x00) goto yy178; + if (yych <= '@') goto yy7; + goto yy183; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy180; + goto yy7; + } +yy177: + ++p; + yych = *p; + if (yych <= '`') { + if (yych <= 0x00) goto yy178; + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy183; + goto yy7; + } else { + if (yych == 'r') goto yy182; + if (yych <= 'z') goto yy180; + goto yy7; + } +yy178: + ++p; +yy179: + { + return CALL_FLAG_RENDER; + } +yy180: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= 0x00) goto yy178; + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy176; + goto yy177; + } else { + if (yych <= 'Z') goto yy176; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy180; + goto yy7; + } +yy182: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= 0x00) goto yy178; + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy176; + goto yy177; + } else { + if (yych <= '`') { + if (yych <= 'Z') goto yy176; + goto yy7; + } else { + if (yych <= 'a') goto yy185; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy183: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= 0x00) goto yy178; + if (yych <= '@') goto yy7; + goto yy183; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy183; + goto yy7; + } +yy185: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'v') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 'w') goto yy186; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy186: + ++p; + yych = *p; + if (yych <= 'L') { + if (yych <= 'A') { + if (yych <= 0x00) goto yy178; + if (yych <= '@') goto yy7; + } else { + if (yych <= 'C') goto yy176; + if (yych <= 'D') goto yy177; + if (yych <= 'E') goto yy188; + goto yy176; + } + } else { + if (yych <= 'R') { + if (yych <= 'M') goto yy189; + if (yych <= 'Q') goto yy176; + goto yy190; + } else { + if (yych <= 'Z') goto yy176; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy187: + ++p; + yych = *p; + if (yych <= '`') { + if (yych <= 0x00) goto yy178; + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy183; + goto yy7; + } else { + if (yych == 'r') goto yy204; + if (yych <= 'z') goto yy180; + goto yy7; + } +yy188: + ++p; + yych = *p; + if (yych <= '`') { + if (yych <= 0x00) goto yy178; + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy183; + goto yy7; + } else { + if (yych == 'l') goto yy197; + if (yych <= 'z') goto yy180; + goto yy7; + } +yy189: + ++p; + yych = *p; + if (yych <= '`') { + if (yych <= 0x00) goto yy178; + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy183; + goto yy7; + } else { + if (yych == 'e') goto yy195; + if (yych <= 'z') goto yy180; + goto yy7; + } +yy190: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= 0x00) goto yy178; + if (yych <= '@') goto yy7; + goto yy183; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'a') goto yy191; + if (yych <= 'z') goto yy180; + goto yy7; + } +yy191: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'm') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 'n') goto yy192; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy192: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'f') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 'g') goto yy193; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy193: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'd') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 'e') goto yy194; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy194: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych <= 'A') goto yy187; + if (yych <= 'C') goto yy176; + goto yy177; + } + } else { + if (yych <= 'Z') { + if (yych <= 'E') goto yy188; + goto yy176; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy195: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'r') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 's') goto yy196; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy196: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'g') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 'h') goto yy194; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy197: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'd') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 'e') goto yy198; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy198: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'l') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 'm') goto yy199; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy199: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'd') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 'e') goto yy200; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy200: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'm') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 'n') goto yy201; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy201: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 's') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 't') goto yy202; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy202: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'r') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 's') goto yy203; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy203: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= 0x00) goto yy178; + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy176; + goto yy177; + } else { + if (yych <= 'Z') goto yy176; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy180; + goto yy7; + } +yy204: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'q') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 'r') goto yy205; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy205: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= 0x00) goto yy178; + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy176; + goto yy177; + } else { + if (yych <= '`') { + if (yych <= 'Z') goto yy176; + goto yy7; + } else { + if (yych <= 'a') goto yy206; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy206: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'x') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 'y') goto yy207; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy207: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') { + if (yych <= 0x00) goto yy178; + goto yy7; + } else { + if (yych == 'D') goto yy177; + goto yy176; + } + } else { + if (yych <= 'r') { + if (yych <= '`') goto yy7; + goto yy180; + } else { + if (yych <= 's') goto yy203; + if (yych <= 'z') goto yy180; + goto yy7; + } + } +yy208: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'q') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 'r') goto yy209; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy209: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'a') goto yy210; + if (yych <= 'z') goto yy159; + goto yy7; + } +yy210: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'x') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 'y') goto yy211; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy211: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'r') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 's') goto yy175; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy212: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'r') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 's') goto yy213; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy213: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'g') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 'h') goto yy214; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy214: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '@') goto yy7; + if (yych <= 'A') goto yy167; + if (yych <= 'C') goto yy151; + goto yy161; + } else { + if (yych <= 'Z') { + if (yych <= 'E') goto yy168; + goto yy151; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy215: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'm') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 'n') goto yy216; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy216: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'f') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 'g') goto yy217; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy217: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy161; + goto yy151; + } else { + if (yych <= 'd') { + if (yych <= '`') goto yy7; + goto yy159; + } else { + if (yych <= 'e') goto yy214; + if (yych <= 'z') goto yy159; + goto yy7; + } + } +yy218: + yych = *++p; + if (yych != 't') goto yy160; + yych = *++p; + switch (yych) { + case 'd': + case 'f': + case 'i': + case 's': goto yy220; + default: goto yy160; + } +yy220: + yych = *++p; + if (yych <= 'Z') { + if (yych <= '@') goto yy223; + if (yych == 'D') goto yy225; + goto yy224; + } else { + if (yych <= 'u') { + if (yych <= '`') goto yy223; + goto yy159; + } else { + if (yych <= 'v') goto yy221; + if (yych <= 'z') goto yy159; + goto yy223; + } + } +yy221: + yych = *++p; + if (yych <= 'D') { + if (yych <= '@') goto yy223; + if (yych <= 'C') goto yy224; + goto yy225; + } else { + if (yych <= 'Z') goto yy224; + if (yych <= '`') goto yy223; + if (yych <= 'z') goto yy159; + goto yy223; + } +yy222: + ++p; + yych = *p; +yy223: + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy222; + goto yy7; + } +yy224: + yych = *++p; + if (yych <= '`') goto yy223; + if (yych <= 'z') goto yy159; + goto yy223; +yy225: + yych = *++p; + if (yych <= '`') goto yy223; + if (yych == 'r') goto yy162; + if (yych <= 'z') goto yy159; + goto yy223; +yy226: + ++p; + { + return CALL_FLAG_RENDER; + } +yy228: + yych = *++p; + if (yych != 't') goto yy160; + yych = *++p; + switch (yych) { + case 'F': goto yy233; + case 'I': goto yy232; + case 'T': goto yy230; + case 'V': goto yy231; + default: goto yy160; + } +yy230: + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'e') goto yy315; + if (yych <= 'z') goto yy159; + goto yy7; +yy231: + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'e') goto yy305; + if (yych <= 'z') goto yy159; + goto yy7; +yy232: + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'n') goto yy300; + if (yych <= 'z') goto yy159; + goto yy7; +yy233: + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'l') goto yy234; + if (yych <= 'z') goto yy159; + goto yy7; +yy234: + yych = *++p; + if (yych != 'o') goto yy160; + yych = *++p; + if (yych != 'a') goto yy160; + yych = *++p; + if (yych != 't') goto yy160; +yy237: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy240; + } + } else { + if (yych <= '_') { + if (yych <= 'Z') goto yy240; + if (yych <= '^') goto yy7; + goto yy241; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy239: + ++p; + yych = *p; + if (yych <= '^') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy241; + goto yy7; + } + } else { + if (yych <= 'q') { + if (yych <= '_') goto yy241; + if (yych <= '`') goto yy7; + goto yy237; + } else { + if (yych <= 'r') goto yy245; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy240: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych <= 0x00) goto yy243; + goto yy7; + } else { + if (yych <= '9') goto yy241; + if (yych <= '@') goto yy7; + } + } else { + if (yych <= '_') { + if (yych <= '^') goto yy7; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy241: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych >= 0x01) goto yy7; + } else { + if (yych <= '9') goto yy241; + if (yych <= '@') goto yy7; + goto yy241; + } + } else { + if (yych <= '_') { + if (yych <= '^') goto yy7; + goto yy241; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy241; + goto yy7; + } + } +yy243: + ++p; + { + return CALL_FLAG_NO_SIDE_EFFECTS; + } +yy245: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy240; + goto yy239; + } + } else { + if (yych <= '_') { + if (yych <= 'Z') goto yy240; + if (yych <= '^') goto yy7; + goto yy241; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'a') goto yy246; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy246: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'w') goto yy247; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy247: + ++p; + yych = *p; + if (yych <= 'L') { + if (yych <= '@') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + if (yych <= '9') goto yy241; + goto yy7; + } else { + if (yych <= 'C') { + if (yych <= 'A') goto yy250; + goto yy240; + } else { + if (yych <= 'D') goto yy239; + if (yych <= 'E') goto yy251; + goto yy240; + } + } + } else { + if (yych <= 'Z') { + if (yych <= 'M') goto yy249; + if (yych != 'R') goto yy240; + } else { + if (yych <= '_') { + if (yych <= '^') goto yy7; + goto yy241; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy237; + goto yy7; + } + } + } + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych <= 0x00) goto yy243; + goto yy7; + } else { + if (yych <= '9') goto yy241; + if (yych <= '@') goto yy7; + goto yy241; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych <= 'a') goto yy297; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy249: + ++p; + yych = *p; + if (yych <= '^') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy241; + goto yy7; + } + } else { + if (yych <= 'd') { + if (yych <= '_') goto yy241; + if (yych <= '`') goto yy7; + goto yy237; + } else { + if (yych <= 'e') goto yy294; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy250: + ++p; + yych = *p; + if (yych <= '^') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy241; + goto yy7; + } + } else { + if (yych <= 'q') { + if (yych <= '_') goto yy241; + if (yych <= '`') goto yy7; + goto yy237; + } else { + if (yych <= 'r') goto yy290; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy251: + ++p; + yych = *p; + if (yych <= '^') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy241; + goto yy7; + } + } else { + if (yych <= 'k') { + if (yych <= '_') goto yy241; + if (yych <= '`') goto yy7; + goto yy237; + } else { + if (yych <= 'l') goto yy252; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy252: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'e') goto yy253; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy253: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'm') goto yy254; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy254: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'e') goto yy255; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy255: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'n') goto yy256; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy256: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 't') goto yy257; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy257: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 's') goto yy258; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy258: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych >= 'D') goto yy260; + } + } else { + if (yych <= '_') { + if (yych <= 'Z') goto yy259; + if (yych <= '^') goto yy7; + goto yy241; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy259: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych <= 0x00) goto yy261; + goto yy7; + } else { + if (yych <= '9') goto yy241; + if (yych <= '@') goto yy7; + goto yy262; + } + } else { + if (yych <= '_') { + if (yych <= '^') goto yy7; + goto yy241; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy260: + ++p; + yych = *p; + if (yych <= '^') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy262; + goto yy7; + } + } else { + if (yych <= 'q') { + if (yych <= '_') goto yy241; + if (yych <= '`') goto yy7; + goto yy264; + } else { + if (yych <= 'r') goto yy266; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy261: + yych = *++p; + goto yy179; +yy262: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych <= 0x00) goto yy261; + goto yy7; + } else { + if (yych <= '9') goto yy241; + if (yych <= '@') goto yy7; + goto yy262; + } + } else { + if (yych <= '_') { + if (yych <= '^') goto yy7; + goto yy241; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy262; + goto yy7; + } + } +yy264: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy259; + goto yy260; + } + } else { + if (yych <= '_') { + if (yych <= 'Z') goto yy259; + if (yych <= '^') goto yy7; + goto yy241; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy266: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy259; + goto yy260; + } + } else { + if (yych <= '_') { + if (yych <= 'Z') goto yy259; + if (yych <= '^') goto yy7; + goto yy241; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'a') goto yy267; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy267: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'w') goto yy268; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy268: + ++p; + yych = *p; + if (yych <= 'L') { + if (yych <= '@') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + if (yych <= '9') goto yy241; + goto yy7; + } else { + if (yych <= 'C') { + if (yych >= 'B') goto yy259; + } else { + if (yych <= 'D') goto yy260; + if (yych <= 'E') goto yy270; + goto yy259; + } + } + } else { + if (yych <= 'Z') { + if (yych <= 'M') goto yy271; + if (yych == 'R') goto yy272; + goto yy259; + } else { + if (yych <= '_') { + if (yych <= '^') goto yy7; + goto yy241; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy264; + goto yy7; + } + } + } +yy269: + ++p; + yych = *p; + if (yych <= '^') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy262; + goto yy7; + } + } else { + if (yych <= 'q') { + if (yych <= '_') goto yy241; + if (yych <= '`') goto yy7; + goto yy264; + } else { + if (yych <= 'r') goto yy286; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy270: + ++p; + yych = *p; + if (yych <= '^') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy262; + goto yy7; + } + } else { + if (yych <= 'k') { + if (yych <= '_') goto yy241; + if (yych <= '`') goto yy7; + goto yy264; + } else { + if (yych <= 'l') goto yy279; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy271: + ++p; + yych = *p; + if (yych <= '^') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy262; + goto yy7; + } + } else { + if (yych <= 'd') { + if (yych <= '_') goto yy241; + if (yych <= '`') goto yy7; + goto yy264; + } else { + if (yych <= 'e') goto yy277; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy272: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych <= 0x00) goto yy261; + goto yy7; + } else { + if (yych <= '9') goto yy241; + if (yych <= '@') goto yy7; + goto yy262; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych <= 'a') goto yy273; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy273: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'n') goto yy274; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy274: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'g') goto yy275; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy275: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'e') goto yy276; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy276: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'A') goto yy269; + if (yych <= 'C') goto yy259; + goto yy260; + } + } else { + if (yych <= '^') { + if (yych <= 'E') goto yy270; + if (yych <= 'Z') goto yy259; + goto yy7; + } else { + if (yych <= '_') goto yy241; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy277: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 's') goto yy278; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy278: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'h') goto yy276; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy279: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'e') goto yy280; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy280: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'm') goto yy281; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy281: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'e') goto yy282; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy282: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'n') goto yy283; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy283: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 't') goto yy284; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy284: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 's') goto yy285; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy285: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy259; + goto yy260; + } + } else { + if (yych <= '_') { + if (yych <= 'Z') goto yy259; + if (yych <= '^') goto yy7; + goto yy241; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy286: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'r') goto yy287; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy287: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy259; + goto yy260; + } + } else { + if (yych <= '_') { + if (yych <= 'Z') goto yy259; + if (yych <= '^') goto yy7; + goto yy241; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'a') goto yy288; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy288: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'y') goto yy289; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy289: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy261; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy260; + goto yy259; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 's') goto yy285; + if (yych <= 'z') goto yy264; + goto yy7; + } + } +yy290: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'r') goto yy291; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy291: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy240; + goto yy239; + } + } else { + if (yych <= '_') { + if (yych <= 'Z') goto yy240; + if (yych <= '^') goto yy7; + goto yy241; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'a') goto yy292; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy292: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'y') goto yy293; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy293: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 's') goto yy258; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy294: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 's') goto yy295; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy295: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'h') goto yy296; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy296: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'A') goto yy250; + if (yych <= 'C') goto yy240; + goto yy239; + } + } else { + if (yych <= '^') { + if (yych <= 'E') goto yy251; + if (yych <= 'Z') goto yy240; + goto yy7; + } else { + if (yych <= '_') goto yy241; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy297: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'n') goto yy298; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy298: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'g') goto yy299; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy299: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= 0x00) goto yy243; + if (yych <= '/') goto yy7; + goto yy241; + } else { + if (yych <= '@') goto yy7; + if (yych == 'D') goto yy239; + goto yy240; + } + } else { + if (yych <= '`') { + if (yych == '_') goto yy241; + goto yy7; + } else { + if (yych == 'e') goto yy296; + if (yych <= 'z') goto yy237; + goto yy7; + } + } +yy300: + yych = *++p; + if (yych != 't') goto yy160; + yych = *++p; + if (yych != 'e') goto yy160; + yych = *++p; + if (yych != 'g') goto yy160; + yych = *++p; + if (yych != 'e') goto yy160; + yych = *++p; + if (yych == 'r') goto yy237; + goto yy160; +yy305: + yych = *++p; + if (yych != 'r') goto yy160; + yych = *++p; + if (yych != 't') goto yy160; + yych = *++p; + if (yych != 'e') goto yy160; + yych = *++p; + if (yych != 'x') goto yy160; + yych = *++p; + if (yych != 'A') goto yy160; + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 't') goto yy311; + if (yych <= 'z') goto yy159; + goto yy7; +yy311: + yych = *++p; + if (yych != 't') goto yy160; + yych = *++p; + if (yych != 'r') goto yy160; + yych = *++p; + if (yych != 'i') goto yy160; + yych = *++p; + if (yych == 'b') goto yy237; + goto yy160; +yy315: + yych = *++p; + if (yych != 'x') goto yy160; + yych = *++p; + if (yych <= 'O') { + if (yych != 'L') goto yy160; + } else { + if (yych <= 'P') goto yy318; + if (yych == 't') goto yy319; + goto yy160; + } +yy317: + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'e') goto yy330; + if (yych <= 'z') goto yy159; + goto yy7; +yy318: + yych = *++p; + if (yych <= '`') goto yy7; + if (yych <= 'a') goto yy323; + if (yych <= 'z') goto yy159; + goto yy7; +yy319: + yych = *++p; + if (yych != 'u') goto yy160; + yych = *++p; + if (yych != 'r') goto yy160; + yych = *++p; + if (yych != 'e') goto yy160; + yych = *++p; + if (yych == 'L') goto yy317; + if (yych == 'P') goto yy318; + goto yy160; +yy323: + yych = *++p; + if (yych != 'r') goto yy160; + yych = *++p; + if (yych != 'a') goto yy160; + yych = *++p; + if (yych != 'm') goto yy160; + yych = *++p; + if (yych != 'e') goto yy160; + yych = *++p; + if (yych != 't') goto yy160; + yych = *++p; + if (yych != 'e') goto yy160; + yych = *++p; + if (yych == 'r') goto yy237; + goto yy160; +yy330: + yych = *++p; + if (yych != 'v') goto yy160; + yych = *++p; + if (yych != 'e') goto yy160; + yych = *++p; + if (yych != 'l') goto yy160; + yych = *++p; + if (yych == 'P') goto yy318; + goto yy160; +yy334: + yych = *++p; + if (yych == 'a') goto yy336; + goto yy160; +yy335: + yych = *++p; + if (yych == 'd') goto yy221; + goto yy160; +yy336: + yych = *++p; + if (yych != 'l') goto yy160; + yych = *++p; + if (yych != 'M') goto yy160; + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'e') goto yy339; + if (yych <= 'z') goto yy159; + goto yy7; +yy339: + yych = *++p; + if (yych != 's') goto yy160; + yych = *++p; + if (yych != 'h') goto yy160; + yych = *++p; + if (yych <= 'D') { + if (yych <= 0x00) goto yy7; + if (yych <= '@') goto yy343; + if (yych <= 'C') goto yy151; + goto yy161; + } else { + if (yych <= 'Z') goto yy151; + if (yych <= '`') goto yy343; + if (yych <= 'z') goto yy159; + goto yy343; + } +yy342: + ++p; + yych = *p; +yy343: + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy342; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy222; + goto yy7; + } +yy344: + yych = *++p; + if (yych != 'a') goto yy160; + yych = *++p; + if (yych != 'w') goto yy160; + yych = *++p; + switch (yych) { + case 'A': goto yy167; + case 'E': goto yy168; + case 'M': goto yy166; + case 'P': goto yy347; + case 'R': goto yy165; + case 'T': goto yy348; + default: goto yy160; + } +yy347: + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'i') goto yy426; + if (yych <= 'z') goto yy159; + goto yy7; +yy348: + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'r') goto yy349; + if (yych <= 'z') goto yy159; + goto yy7; +yy349: + yych = *++p; + if (yych != 'a') goto yy160; + yych = *++p; + if (yych != 'n') goto yy160; + yych = *++p; + if (yych != 's') goto yy160; + yych = *++p; + if (yych != 'f') goto yy160; + yych = *++p; + if (yych != 'o') goto yy160; + yych = *++p; + if (yych != 'r') goto yy160; + yych = *++p; + if (yych != 'm') goto yy160; + yych = *++p; + if (yych != 'F') goto yy160; + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'e') goto yy358; + if (yych <= 'z') goto yy159; + goto yy7; +yy358: + yych = *++p; + if (yych != 'e') goto yy160; + yych = *++p; + if (yych != 'd') goto yy160; + yych = *++p; + if (yych != 'b') goto yy160; + yych = *++p; + if (yych != 'a') goto yy160; + yych = *++p; + if (yych != 'c') goto yy160; + yych = *++p; + if (yych != 'k') goto yy160; + yych = *++p; + if (yych <= 'D') { + if (yych <= '@') goto yy223; + if (yych >= 'D') goto yy366; + } else { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy223; + if (yych <= 'z') goto yy159; + goto yy223; + } +yy365: + ++p; + yych = *p; + if (yych <= '@') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + if (yych <= '9') goto yy222; + goto yy7; + } else { + if (yych <= 'Z') goto yy370; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy367; + goto yy7; + } +yy366: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych <= 0x00) goto yy226; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy370; + } + } else { + if (yych <= 'q') { + if (yych <= '`') goto yy7; + } else { + if (yych <= 'r') goto yy369; + if (yych >= '{') goto yy7; + } + } +yy367: + ++p; + yych = *p; + if (yych <= 'C') { + if (yych <= '/') { + if (yych <= 0x00) goto yy226; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy365; + } + } else { + if (yych <= 'Z') { + if (yych <= 'D') goto yy366; + goto yy365; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy369: + ++p; + yych = *p; + if (yych <= 'C') { + if (yych <= '/') { + if (yych <= 0x00) goto yy226; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy365; + } + } else { + if (yych <= '`') { + if (yych <= 'D') goto yy366; + if (yych <= 'Z') goto yy365; + goto yy7; + } else { + if (yych <= 'a') goto yy372; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy370: + ++p; + yych = *p; + if (yych <= '@') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + if (yych <= '9') goto yy222; + goto yy7; + } else { + if (yych <= 'Z') goto yy370; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy370; + goto yy7; + } +yy372: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'v') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'w') goto yy373; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy373: + ++p; + yych = *p; + if (yych <= 'E') { + if (yych <= '@') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + if (yych <= '9') goto yy222; + goto yy7; + } else { + if (yych <= 'A') goto yy374; + if (yych <= 'C') goto yy365; + if (yych <= 'D') goto yy366; + goto yy375; + } + } else { + if (yych <= 'R') { + if (yych == 'M') goto yy376; + if (yych <= 'Q') goto yy365; + goto yy377; + } else { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy374: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych <= 0x00) goto yy226; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy370; + } + } else { + if (yych <= 'q') { + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'r') goto yy422; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy375: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych <= 0x00) goto yy226; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy370; + } + } else { + if (yych <= 'k') { + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'l') goto yy384; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy376: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych <= 0x00) goto yy226; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy370; + } + } else { + if (yych <= 'd') { + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'e') goto yy382; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy377: + ++p; + yych = *p; + if (yych <= '@') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + if (yych <= '9') goto yy222; + goto yy7; + } else { + if (yych <= '`') { + if (yych <= 'Z') goto yy370; + goto yy7; + } else { + if (yych <= 'a') goto yy378; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy378: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'm') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'n') goto yy379; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy379: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'f') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'g') goto yy380; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy380: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'd') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'e') goto yy381; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy381: + ++p; + yych = *p; + if (yych <= 'C') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'A') goto yy374; + goto yy365; + } + } else { + if (yych <= 'Z') { + if (yych <= 'D') goto yy366; + if (yych <= 'E') goto yy375; + goto yy365; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy382: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'r') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 's') goto yy383; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy383: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'g') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'h') goto yy381; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy384: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'd') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'e') goto yy385; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy385: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'l') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'm') goto yy386; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy386: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'd') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'e') goto yy387; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy387: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'm') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'n') goto yy388; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy388: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 's') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 't') goto yy389; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy389: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'r') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 's') goto yy390; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy390: + ++p; + yych = *p; + if (yych <= 'C') { + if (yych <= '/') { + if (yych <= 0x00) goto yy393; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + } + } else { + if (yych <= 'Z') { + if (yych <= 'D') goto yy392; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy391: + ++p; + yych = *p; + if (yych <= '@') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + if (yych <= '9') goto yy222; + goto yy7; + } else { + if (yych <= 'Z') goto yy397; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy394; + goto yy7; + } +yy392: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych >= 0x01) goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy397; + } + } else { + if (yych <= 'q') { + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'r') goto yy396; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy393: + yych = *++p; + goto yy179; +yy394: + ++p; + yych = *p; + if (yych <= 'C') { + if (yych <= '/') { + if (yych <= 0x00) goto yy393; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy391; + } + } else { + if (yych <= 'Z') { + if (yych <= 'D') goto yy392; + goto yy391; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy396: + ++p; + yych = *p; + if (yych <= 'C') { + if (yych <= '/') { + if (yych <= 0x00) goto yy393; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy391; + } + } else { + if (yych <= '`') { + if (yych <= 'D') goto yy392; + if (yych <= 'Z') goto yy391; + goto yy7; + } else { + if (yych <= 'a') goto yy399; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy397: + ++p; + yych = *p; + if (yych <= '@') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + if (yych <= '9') goto yy222; + goto yy7; + } else { + if (yych <= 'Z') goto yy397; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy397; + goto yy7; + } +yy399: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'v') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'w') goto yy400; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy400: + ++p; + yych = *p; + if (yych <= 'E') { + if (yych <= '@') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + if (yych <= '9') goto yy222; + goto yy7; + } else { + if (yych <= 'A') goto yy401; + if (yych <= 'C') goto yy391; + if (yych <= 'D') goto yy392; + goto yy402; + } + } else { + if (yych <= 'R') { + if (yych == 'M') goto yy403; + if (yych <= 'Q') goto yy391; + goto yy404; + } else { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy401: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych <= 0x00) goto yy393; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy397; + } + } else { + if (yych <= 'q') { + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'r') goto yy418; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy402: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych <= 0x00) goto yy393; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy397; + } + } else { + if (yych <= 'k') { + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'l') goto yy411; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy403: + ++p; + yych = *p; + if (yych <= 'Z') { + if (yych <= '/') { + if (yych <= 0x00) goto yy393; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy397; + } + } else { + if (yych <= 'd') { + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'e') goto yy409; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy404: + ++p; + yych = *p; + if (yych <= '@') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + if (yych <= '9') goto yy222; + goto yy7; + } else { + if (yych <= '`') { + if (yych <= 'Z') goto yy397; + goto yy7; + } else { + if (yych <= 'a') goto yy405; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy405: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'm') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'n') goto yy406; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy406: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'f') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'g') goto yy407; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy407: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'd') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'e') goto yy408; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy408: + ++p; + yych = *p; + if (yych <= 'C') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'A') goto yy401; + goto yy391; + } + } else { + if (yych <= 'Z') { + if (yych <= 'D') goto yy392; + if (yych <= 'E') goto yy402; + goto yy391; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy409: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'r') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 's') goto yy410; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy410: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'g') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'h') goto yy408; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy411: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'd') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'e') goto yy412; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy412: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'l') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'm') goto yy413; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy413: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'd') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'e') goto yy414; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy414: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'm') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'n') goto yy415; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy415: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 's') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 't') goto yy416; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy416: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'r') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 's') goto yy417; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy417: + ++p; + yych = *p; + if (yych <= 'C') { + if (yych <= '/') { + if (yych <= 0x00) goto yy393; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy391; + } + } else { + if (yych <= 'Z') { + if (yych <= 'D') goto yy392; + goto yy391; + } else { + if (yych <= '`') goto yy7; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy418: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'q') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'r') goto yy419; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy419: + ++p; + yych = *p; + if (yych <= 'C') { + if (yych <= '/') { + if (yych <= 0x00) goto yy393; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy391; + } + } else { + if (yych <= '`') { + if (yych <= 'D') goto yy392; + if (yych <= 'Z') goto yy391; + goto yy7; + } else { + if (yych <= 'a') goto yy420; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy420: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'x') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 'y') goto yy421; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy421: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy393; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy391; + goto yy392; + } + } else { + if (yych <= 'r') { + if (yych <= 'Z') goto yy391; + if (yych <= '`') goto yy7; + goto yy394; + } else { + if (yych <= 's') goto yy417; + if (yych <= 'z') goto yy394; + goto yy7; + } + } +yy422: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'q') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'r') goto yy423; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy423: + ++p; + yych = *p; + if (yych <= 'C') { + if (yych <= '/') { + if (yych <= 0x00) goto yy226; + goto yy7; + } else { + if (yych <= '9') goto yy222; + if (yych <= '@') goto yy7; + goto yy365; + } + } else { + if (yych <= '`') { + if (yych <= 'D') goto yy366; + if (yych <= 'Z') goto yy365; + goto yy7; + } else { + if (yych <= 'a') goto yy424; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy424: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'x') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 'y') goto yy425; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy425: + ++p; + yych = *p; + if (yych <= 'D') { + if (yych <= '9') { + if (yych <= 0x00) goto yy226; + if (yych <= '/') goto yy7; + goto yy222; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'C') goto yy365; + goto yy366; + } + } else { + if (yych <= 'r') { + if (yych <= 'Z') goto yy365; + if (yych <= '`') goto yy7; + goto yy367; + } else { + if (yych <= 's') goto yy390; + if (yych <= 'z') goto yy367; + goto yy7; + } + } +yy426: + yych = *++p; + if (yych != 'x') goto yy160; + yych = *++p; + if (yych != 'e') goto yy160; + yych = *++p; + if (yych != 'l') goto yy160; + yych = *++p; + if (yych == 's') goto yy221; + goto yy160; +yy430: + yych = *++p; + if (yych == 'e') goto yy438; + goto yy160; +yy431: + yych = *++p; + if (yych != 'l') goto yy160; + yych = *++p; + if (yych != 'l') goto yy160; + yych = *++p; + if (yych != 'L') goto yy160; + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'i') goto yy435; + if (yych <= 'z') goto yy159; + goto yy7; +yy435: + yych = *++p; + if (yych != 's') goto yy160; + yych = *++p; + if (yych != 't') goto yy160; + yych = *++p; + if (yych <= 'Z') { + if (yych <= '@') goto yy223; + if (yych == 'D') goto yy225; + goto yy224; + } else { + if (yych <= 'r') { + if (yych <= '`') goto yy223; + goto yy159; + } else { + if (yych <= 's') goto yy221; + if (yych <= 'z') goto yy159; + goto yy223; + } + } +yy438: + yych = *++p; + if (yych != 'a') goto yy160; + yych = *++p; + if (yych == 'r') goto yy221; + goto yy160; +yy440: + yych = *++p; + if (yych == 'n') goto yy454; + goto yy160; +yy441: + yych = *++p; + if (yych != 'i') goto yy160; + yych = *++p; + if (yych != 't') goto yy160; + yych = *++p; + if (yych != 'F') goto yy160; + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'r') goto yy445; + if (yych <= 'z') goto yy159; + goto yy7; +yy445: + yych = *++p; + if (yych != 'a') goto yy160; + yych = *++p; + if (yych != 'm') goto yy160; + yych = *++p; + if (yych != 'e') goto yy160; + yych = *++p; + if (yych != 'b') goto yy160; + yych = *++p; + if (yych != 'u') goto yy160; + yych = *++p; + if (yych != 'f') goto yy160; + yych = *++p; + if (yych != 'f') goto yy160; + yych = *++p; + if (yych != 'e') goto yy160; + yych = *++p; + if (yych == 'r') goto yy221; + goto yy160; +yy454: + yych = *++p; + if (yych != 'd') goto yy160; + yych = *++p; + if (yych != 'F') goto yy160; + yych = *++p; + if (yych <= '`') goto yy7; + if (yych == 'r') goto yy457; + if (yych <= 'z') goto yy159; + goto yy7; +yy457: + yych = *++p; + if (yych != 'a') goto yy160; + yych = *++p; + if (yych != 'm') goto yy160; + yych = *++p; + if (yych != 'e') goto yy160; + yych = *++p; + if (yych != 'b') goto yy160; + yych = *++p; + if (yych != 'u') goto yy160; + yych = *++p; + if (yych != 'f') goto yy160; + yych = *++p; + if (yych != 'f') goto yy160; + yych = *++p; + if (yych != 'e') goto yy160; + yych = *++p; + if (yych != 'r') goto yy160; + yych = *++p; + if (yych <= 'D') { + if (yych <= '@') goto yy468; + if (yych <= 'C') goto yy469; + goto yy470; + } else { + if (yych <= 'Z') goto yy469; + if (yych <= '`') goto yy468; + if (yych <= 'z') goto yy159; + goto yy468; + } +yy467: + ++p; + yych = *p; +yy468: + if (yych <= '9') { + if (yych <= 0x00) goto yy471; + if (yych <= '/') goto yy7; + goto yy467; + } else { + if (yych <= '@') goto yy7; + if (yych <= 'Z') goto yy467; + goto yy7; + } +yy469: + yych = *++p; + if (yych <= '`') goto yy468; + if (yych <= 'z') goto yy159; + goto yy468; +yy470: + yych = *++p; + if (yych <= '`') goto yy468; + if (yych == 'r') goto yy162; + if (yych <= 'z') goto yy159; + goto yy468; +yy471: + ++p; + { + return CALL_FLAG_SWAP_RENDERTARGET; + } + } + } diff --git a/common/trace_parser_flags.cpp.re b/common/trace_parser_flags.cpp.re new file mode 100644 index 00000000..b3536c0c --- /dev/null +++ b/common/trace_parser_flags.cpp.re @@ -0,0 +1,565 @@ +/************************************************************************** + * + * Copyright 2015 VMware, Inc. + * Copyright 2011 Jose Fonseca + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + +/* + * Label functions based on their name. + * + * Compile with RE2C as + * + * re2c -is --no-generation-date trace_parser_flags.cpp.re > trace_parser_flags.cpp + * + * TODO: Use std::regex once GCC 4.9 becomes widely available -- https://github.com/apitrace/apitrace/issues/370 + */ + + +#include "trace_parser.hpp" + +#include <assert.h> + +#include "trace_lookup.hpp" + + +using namespace trace; + + +/** + * Shortcut for SwapBuffers, which terminate and swap bound render buffer. + */ +#define CALL_FLAG_SWAPBUFFERS (CALL_FLAG_END_FRAME | CALL_FLAG_SWAP_RENDERTARGET) + + + +/** + * Default call flags. + */ +const CallFlags +defaultCallFlags = 0; + + +/** + * Call flags lookup table. + */ +const Entry<CallFlags> +callFlagTable[] = { + { "CGLFlushDrawable", CALL_FLAG_END_FRAME }, + { "CGLGetCurrentContext", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "D3DPERF_BeginEvent", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "D3DPERF_EndEvent", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP }, + { "D3DPERF_SetMarker", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER }, + { "ID3DUserDefinedAnnotation::BeginEvent", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "ID3DUserDefinedAnnotation::EndEvent", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP }, + { "ID3DUserDefinedAnnotation::SetMarker", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER }, + { "IDirect3D8::CheckDeviceFormat", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D8::EnumAdapterModes", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D8::GetAdapterModeCount", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D8::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9::CheckDeviceFormat", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9::EnumAdapterModes", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9::GetAdapterModeCount", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9Ex::CheckDeviceFormat", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9Ex::EnumAdapterModes", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9Ex::GetAdapterModeCount", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9Ex::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3DDevice2::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice2::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawIndexedPrimitiveStrided", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawIndexedPrimitiveVB", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawPrimitiveStrided", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawPrimitiveVB", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::Clear", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawIndexedPrimitiveStrided", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawIndexedPrimitiveVB", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawPrimitiveStrided", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawPrimitiveVB", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::Clear", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::DrawIndexedPrimitiveUP", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::DrawPrimitiveUP", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::DrawRectPatch", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::DrawTriPatch", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3DDevice8::Present", CALL_FLAG_SWAPBUFFERS }, + { "IDirect3DDevice8::SetRenderTarget", CALL_FLAG_SWAP_RENDERTARGET }, + { "IDirect3DDevice9::Clear", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::DrawIndexedPrimitiveUP", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::DrawPrimitiveUP", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::DrawRectPatch", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::DrawTriPatch", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3DDevice9::GetRenderTargetData", CALL_FLAG_END_FRAME }, + { "IDirect3DDevice9::Present", CALL_FLAG_SWAPBUFFERS }, + { "IDirect3DDevice9::SetRenderTarget", CALL_FLAG_SWAP_RENDERTARGET }, + { "IDirect3DDevice9Ex::Clear", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::DrawIndexedPrimitiveUP", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::DrawPrimitiveUP", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::DrawRectPatch", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::DrawTriPatch", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3DDevice9Ex::GetRenderTargetData", CALL_FLAG_END_FRAME }, + { "IDirect3DDevice9Ex::Present", CALL_FLAG_SWAPBUFFERS }, + { "IDirect3DDevice9Ex::PresentEx", CALL_FLAG_SWAPBUFFERS }, + { "IDirect3DDevice9Ex::SetRenderTarget", CALL_FLAG_SWAP_RENDERTARGET }, + { "IDirect3DSwapChain9::Present", CALL_FLAG_SWAPBUFFERS }, + { "IDirect3DSwapChain9Ex::Present", CALL_FLAG_SWAPBUFFERS }, + { "IDirect3DViewport2::Clear", CALL_FLAG_RENDER }, + { "IDirect3DViewport3::Clear", CALL_FLAG_RENDER }, + { "IDirect3DViewport3::Clear2", CALL_FLAG_RENDER }, + { "IDirect3DViewport::Clear", CALL_FLAG_RENDER }, + { "eglGetConfigAttrib", CALL_FLAG_VERBOSE }, + { "eglGetProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "eglQueryString", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "eglSwapBuffers", CALL_FLAG_SWAPBUFFERS }, + { "glAreProgramsResidentNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glAreTexturesResident", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glAreTexturesResidentEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glBufferRegionEnabled", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glDebugMessageControl", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glDebugMessageControlARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glDebugMessageEnableAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glDebugMessageInsert", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, + { "glDebugMessageInsertAMD", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, + { "glDebugMessageInsertARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, + { "glDebugMessageInsertKHR", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, + { "glFrameTerminatorGREMEDY", CALL_FLAG_END_FRAME }, + { "glGetActiveAtomicCounterBufferiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveAttrib", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveAttribARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveSubroutineName", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveSubroutineUniformName", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveSubroutineUniformiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveUniform", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveUniformARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveUniformBlockName", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveUniformBlockiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveUniformName", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveUniformsiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveVaryingNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetArrayObjectfvATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetArrayObjectivATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetAttachedObjectsARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetAttachedShaders", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBooleanIndexedvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBooleani_v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBooleanv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferParameteri64v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferParameterivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferParameterui64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferPointerv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferPointervARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferSubData", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferSubDataARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetClipPlane", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTable", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableParameterfvSGI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableParameterivSGI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableSGI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetCombinerInputParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetCombinerInputParameterivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetCombinerOutputParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetCombinerOutputParameterivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetCombinerStageParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetConvolutionFilterEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetConvolutionParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetConvolutionParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetConvolutionParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetConvolutionParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetDetailTexFuncSGIS", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetDoubleIndexedvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetDoublei_v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetDoublev", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetError", CALL_FLAG_NO_SIDE_EFFECTS }, // verbose will be set later for GL_NO_ERROR + { "glGetFenceivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFinalCombinerInputParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFinalCombinerInputParameterivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFogFuncSGIS", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFragDataIndex", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFragmentLightfvSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFragmentLightivSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFragmentMaterialfvSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFragmentMaterialivSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFramebufferAttachmentParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFramebufferAttachmentParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFramebufferParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFramebufferParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetGraphicsResetStatusARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetHandleARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetHistogramEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetHistogramParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetHistogramParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetHistogramParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetHistogramParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetImageTransformParameterfvHP", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetImageTransformParameterivHP", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInfoLogARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInstrumentsSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInternalformati64v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInternalformativ", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInvariantBooleanvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInvariantFloatvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInvariantIntegervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetLightfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetLightiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetListParameterfvSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetListParameterivSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetLocalConstantBooleanvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetLocalConstantFloatvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetLocalConstantIntegervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapAttribParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapAttribParameterivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapControlPointsNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapParameterivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapdv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMaterialfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMaterialiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMinmaxEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMinmaxParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMinmaxParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMinmaxParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMinmaxParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexEnvfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexEnvivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexGendvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexGenfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexGenivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexLevelParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexLevelParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexParameterIivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexParameterIuivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultisamplefv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultisamplefvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedBufferParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedBufferParameterui64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedBufferPointervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedBufferSubDataEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedFramebufferAttachmentParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedFramebufferParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedProgramLocalParameterIivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedProgramLocalParameterIuivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedProgramLocalParameterdvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedProgramLocalParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedProgramStringEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedProgramivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedRenderbufferParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedStringARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedStringivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectBufferfvATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectBufferivATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectLabel", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectParameterfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectParameterivAPPLE", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectParameterivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectPtrLabel", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetOcclusionQueryivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetOcclusionQueryuivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPerfMonitorCounterDataAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPerfMonitorCounterInfoAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPerfMonitorCounterStringAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPerfMonitorCountersAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPerfMonitorGroupStringAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPerfMonitorGroupsAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPixelTexGenParameterfvSGIS", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPixelTexGenParameterivSGIS", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPointerIndexedvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPointerv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPointervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramBinary", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramEnvParameterIivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramEnvParameterIuivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramEnvParameterdvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramEnvParameterfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramInfoLog", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramInterfaceiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramLocalParameterIivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramLocalParameterIuivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramLocalParameterdvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramLocalParameterfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramNamedParameterdvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramNamedParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramParameterdvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramPipelineInfoLog", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramPipelineiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramResourceIndex", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramResourceLocation", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramResourceLocationIndex", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramResourceName", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramResourceiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramStageiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramStringARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramStringNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramSubroutineParameteruivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryIndexediv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjecti64v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjecti64vEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjectiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjectivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjectui64v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjectui64vEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjectuiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjectuivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetRenderbufferParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetRenderbufferParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetSamplerParameterIiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetSamplerParameterIuiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetSamplerParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetSamplerParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetSeparableFilterEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetShaderInfoLog", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetShaderPrecisionFormat", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetShaderSource", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetShaderSourceARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetShaderiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetSharpenTexFuncSGIS", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetString", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glGetStringi", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glGetSynciv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexBumpParameterfvATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexBumpParameterivATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexEnvfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexEnviv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexFilterFuncSGIS", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexGendv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexGenfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexGeniv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTrackMatrixivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTransformFeedbackVarying", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTransformFeedbackVaryingEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTransformFeedbackVaryingNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformIndices", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformSubroutineuiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformdv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformi64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformui64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformuiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformuivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVariantArrayObjectfvATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVariantArrayObjectivATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVariantBooleanvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVariantFloatvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVariantIntegervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVariantPointervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexArrayIntegeri_vEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexArrayIntegervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexArrayPointeri_vEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexArrayPointervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoCaptureStreamdvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoCaptureStreamfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoCaptureStreamivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoCaptureivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoi64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoui64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideouivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnMapdvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnMapfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnMapivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnUniformdvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnUniformfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnUniformivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnUniformuivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glInsertEventMarkerEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, + { "glIsAsyncMarkerSGIX", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsBuffer", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsBufferARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsBufferResidentNV", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsEnabled", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsEnabledIndexedEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsEnabledi", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsFenceAPPLE", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsFenceNV", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsFramebuffer", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsFramebufferEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsList", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsNameAMD", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsNamedBufferResidentNV", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsNamedStringARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsObjectBufferATI", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsOcclusionQueryNV", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsProgram", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsProgramARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsProgramNV", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsProgramPipeline", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsQuery", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsQueryARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsRenderbuffer", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsRenderbufferEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsSampler", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsShader", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsSync", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsTexture", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsTextureEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsTransformFeedback", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsTransformFeedbackNV", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsVariantEnabledEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsVertexArray", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsVertexArrayAPPLE", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsVertexAttribEnabledAPPLE", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glObjectLabel", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glObjectLabelKHR", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glObjectPtrLabel", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glObjectPtrLabelKHR", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glPopDebugGroup", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP}, + { "glPopDebugGroupKHR", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP}, + { "glPopGroupMarkerEXT", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP}, + { "glPushDebugGroup", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "glPushDebugGroupKHR", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "glPushGroupMarkerEXT", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "glStringMarkerGREMEDY", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER }, + { "glXGetClientString", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetConfig", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentContext", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentDisplay", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentDisplayEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentDrawable", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentReadDrawable", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentReadDrawableSGI", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetFBConfigAttrib", CALL_FLAG_VERBOSE }, + { "glXGetFBConfigAttribSGIX", CALL_FLAG_VERBOSE }, + { "glXGetProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetProcAddressARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXIsDirect", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXQueryExtension", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXQueryExtensionsString", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXQueryVersion", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXSwapBuffers", CALL_FLAG_SWAPBUFFERS }, + { "wglDescribePixelFormat", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetCurrentContext", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetCurrentDC", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetDefaultProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetExtensionsStringARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetExtensionsStringEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetPixelFormat", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetPixelFormatAttribivARB", CALL_FLAG_VERBOSE }, + { "wglGetPixelFormatAttribivEXT", CALL_FLAG_VERBOSE }, + { "wglGetProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglSwapBuffers", CALL_FLAG_SWAPBUFFERS }, + { "wglSwapLayerBuffers", CALL_FLAG_SWAPBUFFERS }, + { "wglSwapMultipleBuffers", CALL_FLAG_SWAPBUFFERS }, + // NOTE: New entries must be sorted alphabetically +}; + + +/** + * Lookup call flags by name. + */ +CallFlags +Parser::lookupCallFlags(const char *name) +{ + const char *p = name; + const char *q; + + /*!re2c + re2c:define:YYCTYPE = "char"; + re2c:define:YYCURSOR = p; + re2c:define:YYMARKER = q; + re2c:yyfill:enable = 0; + re2c:indent:string = " "; + re2c:indent:top = 1; + + D = [0-9]; + W = [_A-Z0-9a-z]; + END = "\000"; + + "gl"([A-Z][a-z]+)*"Draw"("Range"|"Mesh")?("Arrays"|"Elements")([A-Z][a-zA-Z]*)? END { + return CALL_FLAG_RENDER; + } + + "gl" ( + "CallList" "s"? | + "Clear" | + "End" | + "DrawPixels" | + "DrawTransformFeedback" ([A-Z][a-zA-Z]*)? | + "BlitFramebuffer" | + "Rect" [dfis] "v"? | + "EvalMesh" [0-9]+ + ) [0-9A-Z]* END { + return CALL_FLAG_RENDER; + } + + "glBindFramebuffer" [0-9A-Z]* END { + return CALL_FLAG_SWAP_RENDERTARGET; + } + + "gl" ( + "GetFloat" | + "GetInteger" | + "GetVertexAttrib" | + "GetTex"("ture")?("Level")?"Parameter" + ) W* END { + return CALL_FLAG_NO_SIDE_EFFECTS; + } + + "IDXGI" ("Decode")? "SwapChain" W* "::Present" W* END { + return CALL_FLAG_END_FRAME; + } + + "ID3D1" ("0Device"|"1DeviceContext") D* "::" ("Draw" W* | "ExecuteCommandList") END { + return CALL_FLAG_RENDER; + } + + "ID3D1" ("0Device"|"1DeviceContext") D* "::" "OMSetRenderTargets" W* END { + return CALL_FLAG_SWAP_RENDERTARGET; + } + + "ID3D1" [01] "Device" D* "::CheckMultisampleQualityLevels" END { + return CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE; + } + + [^] { return entryLookup(name, callFlagTable, defaultCallFlags); } + */ +} diff --git a/common/trace_parser_flags_test.cpp b/common/trace_parser_flags_test.cpp new file mode 100644 index 00000000..43135737 --- /dev/null +++ b/common/trace_parser_flags_test.cpp @@ -0,0 +1,652 @@ +/************************************************************************** + * + * Copyright 2015 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + +#include "trace_parser.hpp" + +#include "gtest/gtest.h" + +#include "trace_lookup.hpp" + +using namespace trace; + + +/** + * Shortcut for SwapBuffers, which terminate and swap bound render buffer. + */ +#define CALL_FLAG_SWAPBUFFERS (CALL_FLAG_END_FRAME | CALL_FLAG_SWAP_RENDERTARGET) + + + +/** + * Call flags lookup table. + */ +static const Entry<CallFlags> +entries[] = { + { "CGLFlushDrawable", CALL_FLAG_END_FRAME }, + { "CGLGetCurrentContext", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "D3DPERF_BeginEvent", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "D3DPERF_EndEvent", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP }, + { "D3DPERF_SetMarker", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER }, + { "ID3D10Device1::CheckMultisampleQualityLevels", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "ID3D10Device1::Draw", CALL_FLAG_RENDER }, + { "ID3D10Device1::DrawAuto", CALL_FLAG_RENDER }, + { "ID3D10Device1::DrawIndexed", CALL_FLAG_RENDER }, + { "ID3D10Device1::DrawIndexedInstanced", CALL_FLAG_RENDER }, + { "ID3D10Device1::DrawInstanced", CALL_FLAG_RENDER }, + { "ID3D10Device1::OMSetRenderTargets", CALL_FLAG_SWAP_RENDERTARGET }, + { "ID3D10Device::CheckMultisampleQualityLevels", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "ID3D10Device::Draw", CALL_FLAG_RENDER }, + { "ID3D10Device::DrawAuto", CALL_FLAG_RENDER }, + { "ID3D10Device::DrawIndexed", CALL_FLAG_RENDER }, + { "ID3D10Device::DrawIndexedInstanced", CALL_FLAG_RENDER }, + { "ID3D10Device::DrawInstanced", CALL_FLAG_RENDER }, + { "ID3D10Device::OMSetRenderTargets", CALL_FLAG_SWAP_RENDERTARGET }, + { "ID3D11Device::CheckMultisampleQualityLevels", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "ID3D11DeviceContext1::Draw", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext1::DrawAuto", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext1::DrawIndexed", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext1::DrawIndexedInstanced", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext1::DrawIndexedInstancedIndirect", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext1::DrawInstanced", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext1::DrawInstancedIndirect", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext1::ExecuteCommandList", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext1::OMSetRenderTargets", CALL_FLAG_SWAP_RENDERTARGET }, + { "ID3D11DeviceContext1::OMSetRenderTargetsAndUnorderedAccessViews", CALL_FLAG_SWAP_RENDERTARGET }, + { "ID3D11DeviceContext::Draw", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext::DrawAuto", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext::DrawIndexed", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext::DrawIndexedInstanced", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext::DrawIndexedInstancedIndirect", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext::DrawInstanced", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext::DrawInstancedIndirect", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext::ExecuteCommandList", CALL_FLAG_RENDER }, + { "ID3D11DeviceContext::OMSetRenderTargets", CALL_FLAG_SWAP_RENDERTARGET }, + { "ID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews", CALL_FLAG_SWAP_RENDERTARGET }, + { "ID3DUserDefinedAnnotation::BeginEvent", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "ID3DUserDefinedAnnotation::EndEvent", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP }, + { "ID3DUserDefinedAnnotation::SetMarker", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER }, + { "IDXGIDecodeSwapChain::PresentBuffer", CALL_FLAG_END_FRAME /* CALL_FLAG_SWAPBUFFERS */ }, + { "IDXGISwapChain1::Present", CALL_FLAG_END_FRAME /* CALL_FLAG_SWAPBUFFERS */ }, + { "IDXGISwapChain1::Present1", CALL_FLAG_END_FRAME /* CALL_FLAG_SWAPBUFFERS */ }, + { "IDXGISwapChain2::Present", CALL_FLAG_END_FRAME /* CALL_FLAG_SWAPBUFFERS */ }, + { "IDXGISwapChain2::Present1", CALL_FLAG_END_FRAME /* CALL_FLAG_SWAPBUFFERS */ }, + { "IDXGISwapChain::Present", CALL_FLAG_END_FRAME /* CALL_FLAG_SWAPBUFFERS */ }, + { "IDXGISwapChainDWM::Present", CALL_FLAG_END_FRAME /* CALL_FLAG_SWAPBUFFERS */ }, + { "IDirect3D8::CheckDeviceFormat", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D8::EnumAdapterModes", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D8::GetAdapterModeCount", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D8::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9::CheckDeviceFormat", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9::EnumAdapterModes", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9::GetAdapterModeCount", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9Ex::CheckDeviceFormat", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9Ex::EnumAdapterModes", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9Ex::GetAdapterModeCount", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3D9Ex::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3DDevice2::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice2::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawIndexedPrimitiveStrided", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawIndexedPrimitiveVB", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawPrimitiveStrided", CALL_FLAG_RENDER }, + { "IDirect3DDevice3::DrawPrimitiveVB", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::Clear", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawIndexedPrimitiveStrided", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawIndexedPrimitiveVB", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawPrimitiveStrided", CALL_FLAG_RENDER }, + { "IDirect3DDevice7::DrawPrimitiveVB", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::Clear", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::DrawIndexedPrimitiveUP", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::DrawPrimitiveUP", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::DrawRectPatch", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::DrawTriPatch", CALL_FLAG_RENDER }, + { "IDirect3DDevice8::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3DDevice8::Present", CALL_FLAG_SWAPBUFFERS }, + { "IDirect3DDevice8::SetRenderTarget", CALL_FLAG_SWAP_RENDERTARGET }, + { "IDirect3DDevice9::Clear", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::DrawIndexedPrimitiveUP", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::DrawPrimitiveUP", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::DrawRectPatch", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::DrawTriPatch", CALL_FLAG_RENDER }, + { "IDirect3DDevice9::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3DDevice9::GetRenderTargetData", CALL_FLAG_END_FRAME }, + { "IDirect3DDevice9::Present", CALL_FLAG_SWAPBUFFERS }, + { "IDirect3DDevice9::SetRenderTarget", CALL_FLAG_SWAP_RENDERTARGET }, + { "IDirect3DDevice9Ex::Clear", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::DrawIndexedPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::DrawIndexedPrimitiveUP", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::DrawPrimitive", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::DrawPrimitiveUP", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::DrawRectPatch", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::DrawTriPatch", CALL_FLAG_RENDER }, + { "IDirect3DDevice9Ex::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "IDirect3DDevice9Ex::GetRenderTargetData", CALL_FLAG_END_FRAME }, + { "IDirect3DDevice9Ex::Present", CALL_FLAG_SWAPBUFFERS }, + { "IDirect3DDevice9Ex::PresentEx", CALL_FLAG_SWAPBUFFERS }, + { "IDirect3DDevice9Ex::SetRenderTarget", CALL_FLAG_SWAP_RENDERTARGET }, + { "IDirect3DSwapChain9::Present", CALL_FLAG_SWAPBUFFERS }, + { "IDirect3DSwapChain9Ex::Present", CALL_FLAG_SWAPBUFFERS }, + { "IDirect3DViewport2::Clear", CALL_FLAG_RENDER }, + { "IDirect3DViewport3::Clear", CALL_FLAG_RENDER }, + { "IDirect3DViewport3::Clear2", CALL_FLAG_RENDER }, + { "IDirect3DViewport::Clear", CALL_FLAG_RENDER }, + { "eglGetConfigAttrib", CALL_FLAG_VERBOSE }, + { "eglGetProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "eglQueryString", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "eglSwapBuffers", CALL_FLAG_SWAPBUFFERS }, + { "glAreProgramsResidentNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glAreTexturesResident", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glAreTexturesResidentEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glBindFramebuffer", CALL_FLAG_SWAP_RENDERTARGET }, + { "glBindFramebufferEXT", CALL_FLAG_SWAP_RENDERTARGET }, + { "glBindFramebufferOES", CALL_FLAG_SWAP_RENDERTARGET }, + { "glBlitFramebuffer", CALL_FLAG_RENDER }, + { "glBlitFramebufferANGLE", CALL_FLAG_RENDER }, + { "glBlitFramebufferEXT", CALL_FLAG_RENDER }, + { "glBlitFramebufferNV", CALL_FLAG_RENDER }, + { "glBufferRegionEnabled", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glCallList", CALL_FLAG_RENDER }, + { "glCallLists", CALL_FLAG_RENDER }, + { "glClear", CALL_FLAG_RENDER }, + { "glDebugMessageControl", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glDebugMessageControlARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glDebugMessageEnableAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glDebugMessageInsert", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, + { "glDebugMessageInsertAMD", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, + { "glDebugMessageInsertARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, + { "glDebugMessageInsertKHR", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, + { "glDrawArrays", CALL_FLAG_RENDER }, + { "glDrawArraysEXT", CALL_FLAG_RENDER }, + { "glDrawArraysIndirect", CALL_FLAG_RENDER }, + { "glDrawArraysInstanced", CALL_FLAG_RENDER }, + { "glDrawArraysInstancedANGLE", CALL_FLAG_RENDER }, + { "glDrawArraysInstancedARB", CALL_FLAG_RENDER }, + { "glDrawArraysInstancedBaseInstance", CALL_FLAG_RENDER }, + { "glDrawArraysInstancedEXT", CALL_FLAG_RENDER }, + { "glDrawElements", CALL_FLAG_RENDER }, + { "glDrawElementsBaseVertex", CALL_FLAG_RENDER }, + { "glDrawElementsIndirect", CALL_FLAG_RENDER }, + { "glDrawElementsInstanced", CALL_FLAG_RENDER }, + { "glDrawElementsInstancedANGLE", CALL_FLAG_RENDER }, + { "glDrawElementsInstancedARB", CALL_FLAG_RENDER }, + { "glDrawElementsInstancedBaseInstance", CALL_FLAG_RENDER }, + { "glDrawElementsInstancedBaseVertex", CALL_FLAG_RENDER }, + { "glDrawElementsInstancedBaseVertexBaseInstance", CALL_FLAG_RENDER }, + { "glDrawElementsInstancedEXT", CALL_FLAG_RENDER }, + { "glDrawMeshArraysSUN", CALL_FLAG_RENDER }, + { "glDrawPixels", CALL_FLAG_RENDER }, + { "glDrawRangeElementArrayAPPLE", 0 }, + { "glDrawRangeElementArrayATI", 0 }, + { "glDrawRangeElements", CALL_FLAG_RENDER }, + { "glDrawRangeElementsBaseVertex", CALL_FLAG_RENDER }, + { "glDrawRangeElementsEXT", CALL_FLAG_RENDER }, + { "glDrawTransformFeedback", CALL_FLAG_RENDER }, + { "glDrawTransformFeedbackInstanced", CALL_FLAG_RENDER }, + { "glDrawTransformFeedbackNV", CALL_FLAG_RENDER }, + { "glDrawTransformFeedbackStream", CALL_FLAG_RENDER }, + { "glDrawTransformFeedbackStreamInstanced", CALL_FLAG_RENDER }, + { "glEnd", CALL_FLAG_RENDER }, + { "glEvalMesh1", CALL_FLAG_RENDER }, + { "glEvalMesh2", CALL_FLAG_RENDER }, + { "glFrameTerminatorGREMEDY", CALL_FLAG_END_FRAME }, + { "glGetActiveAtomicCounterBufferiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveAttrib", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveAttribARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveSubroutineName", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveSubroutineUniformName", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveSubroutineUniformiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveUniform", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveUniformARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveUniformBlockName", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveUniformBlockiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveUniformName", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveUniformsiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetActiveVaryingNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetArrayObjectfvATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetArrayObjectivATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetAttachedObjectsARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetAttachedShaders", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBooleanIndexedvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBooleani_v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBooleanv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferParameteri64v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferParameterivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferParameterui64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferPointerv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferPointervARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferSubData", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetBufferSubDataARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetClipPlane", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTable", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableParameterfvSGI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableParameterivSGI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetColorTableSGI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetCombinerInputParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetCombinerInputParameterivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetCombinerOutputParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetCombinerOutputParameterivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetCombinerStageParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetConvolutionFilterEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetConvolutionParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetConvolutionParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetConvolutionParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetConvolutionParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetDetailTexFuncSGIS", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetDoubleIndexedvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetDoublei_v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetDoublev", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetError", CALL_FLAG_NO_SIDE_EFFECTS }, // verbose will be set later for GL_NO_ERROR + { "glGetFenceivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFinalCombinerInputParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFinalCombinerInputParameterivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFloatIndexedvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFloati_v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFloatv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFogFuncSGIS", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFragDataIndex", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFragmentLightfvSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFragmentLightivSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFragmentMaterialfvSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFragmentMaterialivSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFramebufferAttachmentParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFramebufferAttachmentParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFramebufferParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetFramebufferParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetGraphicsResetStatusARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetHandleARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetHistogramEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetHistogramParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetHistogramParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetHistogramParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetHistogramParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetImageTransformParameterfvHP", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetImageTransformParameterivHP", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInfoLogARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInstrumentsSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInteger64i_v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInteger64v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetIntegerIndexedvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetIntegeri_v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetIntegerui64i_vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetIntegerui64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetIntegerv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInternalformati64v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInternalformativ", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInvariantBooleanvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInvariantFloatvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetInvariantIntegervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetLightfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetLightiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetListParameterfvSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetListParameterivSGIX", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetLocalConstantBooleanvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetLocalConstantFloatvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetLocalConstantIntegervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapAttribParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapAttribParameterivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapControlPointsNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapParameterivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapdv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMapiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMaterialfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMaterialiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMinmaxEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMinmaxParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMinmaxParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMinmaxParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMinmaxParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexEnvfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexEnvivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexGendvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexGenfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexGenivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexLevelParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexLevelParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexParameterIivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexParameterIuivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultiTexParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultisamplefv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetMultisamplefvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedBufferParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedBufferParameterui64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedBufferPointervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedBufferSubDataEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedFramebufferAttachmentParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedFramebufferParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedProgramLocalParameterIivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedProgramLocalParameterIuivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedProgramLocalParameterdvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedProgramLocalParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedProgramStringEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedProgramivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedRenderbufferParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedStringARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetNamedStringivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectBufferfvATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectBufferivATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectLabel", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectParameterfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectParameterivAPPLE", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectParameterivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetObjectPtrLabel", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetOcclusionQueryivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetOcclusionQueryuivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPerfMonitorCounterDataAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPerfMonitorCounterInfoAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPerfMonitorCounterStringAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPerfMonitorCountersAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPerfMonitorGroupStringAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPerfMonitorGroupsAMD", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPixelTexGenParameterfvSGIS", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPixelTexGenParameterivSGIS", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPointerIndexedvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPointerv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetPointervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramBinary", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramEnvParameterIivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramEnvParameterIuivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramEnvParameterdvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramEnvParameterfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramInfoLog", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramInterfaceiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramLocalParameterIivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramLocalParameterIuivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramLocalParameterdvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramLocalParameterfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramNamedParameterdvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramNamedParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramParameterdvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramParameterfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramPipelineInfoLog", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramPipelineiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramResourceIndex", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramResourceLocation", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramResourceLocationIndex", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramResourceName", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramResourceiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramStageiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramStringARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramStringNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramSubroutineParameteruivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetProgramivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryIndexediv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjecti64v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjecti64vEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjectiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjectivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjectui64v", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjectui64vEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjectuiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryObjectuivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetQueryivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetRenderbufferParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetRenderbufferParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetSamplerParameterIiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetSamplerParameterIuiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetSamplerParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetSamplerParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetSeparableFilterEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetShaderInfoLog", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetShaderPrecisionFormat", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetShaderSource", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetShaderSourceARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetShaderiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetSharpenTexFuncSGIS", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetString", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glGetStringi", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glGetSynciv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexBumpParameterfvATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexBumpParameterivATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexEnvfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexEnviv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexFilterFuncSGIS", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexGendv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexGenfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexGeniv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexLevelParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexLevelParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexParameterIiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexParameterIivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexParameterIuiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexParameterIuivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexParameterPointervAPPLE", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexParameterfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTexParameteriv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTextureLevelParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTextureLevelParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTextureParameterIivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTextureParameterIuivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTextureParameterfvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTextureParameterivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTrackMatrixivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTransformFeedbackVarying", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTransformFeedbackVaryingEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetTransformFeedbackVaryingNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformIndices", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformSubroutineuiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformdv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformi64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformui64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformuiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetUniformuivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVariantArrayObjectfvATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVariantArrayObjectivATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVariantBooleanvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVariantFloatvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVariantIntegervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVariantPointervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexArrayIntegeri_vEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexArrayIntegervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexArrayPointeri_vEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexArrayPointervEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribArrayObjectfvATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribArrayObjectivATI", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribIiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribIivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribIuiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribIuivEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribLdv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribLdvEXT", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribLi64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribLui64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribPointerv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribPointervARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribPointervNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribdv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribdvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribdvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribfv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribiv", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVertexAttribivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoCaptureStreamdvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoCaptureStreamfvNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoCaptureStreamivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoCaptureivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoi64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideoui64vNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetVideouivNV", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnMapdvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnMapfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnMapivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnUniformdvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnUniformfvARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnUniformivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glGetnUniformuivARB", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glInsertEventMarkerEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_MARKER }, + { "glIsAsyncMarkerSGIX", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsBuffer", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsBufferARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsBufferResidentNV", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsEnabled", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsEnabledIndexedEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsEnabledi", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsFenceAPPLE", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsFenceNV", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsFramebuffer", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsFramebufferEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsList", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsNameAMD", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsNamedBufferResidentNV", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsNamedStringARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsObjectBufferATI", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsOcclusionQueryNV", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsProgram", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsProgramARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsProgramNV", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsProgramPipeline", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsQuery", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsQueryARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsRenderbuffer", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsRenderbufferEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsSampler", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsShader", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsSync", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsTexture", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsTextureEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsTransformFeedback", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsTransformFeedbackNV", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsVariantEnabledEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsVertexArray", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsVertexArrayAPPLE", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glIsVertexAttribEnabledAPPLE", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glMultiDrawArrays", CALL_FLAG_RENDER }, + { "glMultiDrawArraysEXT", CALL_FLAG_RENDER }, + { "glMultiDrawArraysIndirect", CALL_FLAG_RENDER }, + { "glMultiDrawArraysIndirectAMD", CALL_FLAG_RENDER }, + { "glMultiDrawArraysIndirectBindlessNV", CALL_FLAG_RENDER }, + { "glMultiDrawArraysIndirectCountARB", CALL_FLAG_RENDER }, + { "glMultiDrawElementArrayAPPLE", 0 }, + { "glMultiDrawElements", CALL_FLAG_RENDER }, + { "glMultiDrawElementsBaseVertex", CALL_FLAG_RENDER }, + { "glMultiDrawElementsEXT", CALL_FLAG_RENDER }, + { "glMultiDrawElementsIndirect", CALL_FLAG_RENDER }, + { "glMultiDrawElementsIndirectAMD", CALL_FLAG_RENDER }, + { "glMultiDrawElementsIndirectBindlessNV", CALL_FLAG_RENDER }, + { "glMultiDrawElementsIndirectCountARB", CALL_FLAG_RENDER }, + { "glMultiDrawRangeElementArrayAPPLE", 0 }, + { "glMultiModeDrawArraysIBM", CALL_FLAG_RENDER }, + { "glMultiModeDrawElementsIBM", CALL_FLAG_RENDER }, + { "glObjectLabel", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glObjectLabelKHR", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glObjectPtrLabel", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glObjectPtrLabelKHR", CALL_FLAG_NO_SIDE_EFFECTS }, + { "glPopDebugGroup", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP}, + { "glPopDebugGroupKHR", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP}, + { "glPopGroupMarkerEXT", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_POP}, + { "glPushDebugGroup", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "glPushDebugGroupKHR", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "glPushGroupMarkerEXT", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER | CALL_FLAG_MARKER_PUSH }, + { "glRectd", CALL_FLAG_RENDER }, + { "glRectdv", CALL_FLAG_RENDER }, + { "glRectf", CALL_FLAG_RENDER }, + { "glRectfv", CALL_FLAG_RENDER }, + { "glRecti", CALL_FLAG_RENDER }, + { "glRectiv", CALL_FLAG_RENDER }, + { "glRects", CALL_FLAG_RENDER }, + { "glRectsv", CALL_FLAG_RENDER }, + { "glStringMarkerGREMEDY", /* CALL_FLAG_NO_SIDE_EFFECTS | */ CALL_FLAG_MARKER }, + { "glXGetClientString", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetConfig", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentContext", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentDisplay", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentDisplayEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentDrawable", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentReadDrawable", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetCurrentReadDrawableSGI", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetFBConfigAttrib", CALL_FLAG_VERBOSE }, + { "glXGetFBConfigAttribSGIX", CALL_FLAG_VERBOSE }, + { "glXGetProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXGetProcAddressARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXIsDirect", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXQueryExtension", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXQueryExtensionsString", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXQueryVersion", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "glXSwapBuffers", CALL_FLAG_SWAPBUFFERS }, + { "wglDescribePixelFormat", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetCurrentContext", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetCurrentDC", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetDefaultProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetExtensionsStringARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetExtensionsStringEXT", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetPixelFormat", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglGetPixelFormatAttribivARB", CALL_FLAG_VERBOSE }, + { "wglGetPixelFormatAttribivEXT", CALL_FLAG_VERBOSE }, + { "wglGetProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE }, + { "wglSwapBuffers", CALL_FLAG_SWAPBUFFERS }, + { "wglSwapLayerBuffers", CALL_FLAG_SWAPBUFFERS }, + { "wglSwapMultipleBuffers", CALL_FLAG_SWAPBUFFERS }, +}; + + +TEST(common_parser, lookupCallFlags) +{ + typedef const Entry<CallFlags> * ConstIterator; + + ConstIterator first = &entries[0]; + ConstIterator last = &entries[sizeof entries / sizeof entries[0]]; + + for (ConstIterator it = first; it != last; ++it) { + CallFlags flags = Parser::lookupCallFlags(it->name); + + EXPECT_EQ(flags, it->value) << "flags differ for " << it->name; + } +} + + +int +main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/common/trace_parser_loop.cpp b/common/trace_parser_loop.cpp new file mode 100644 index 00000000..45772210 --- /dev/null +++ b/common/trace_parser_loop.cpp @@ -0,0 +1,111 @@ +/************************************************************************** + * + * Copyright 2014 LunarG, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + +#include "trace_parser.hpp" + + +namespace trace { + + +// Decorator for parser which loops +class LastFrameLoopParser : public AbstractParser { +public: + LastFrameLoopParser(AbstractParser *p, int c) { + parser = p; + loopCount = c; + } + + ~LastFrameLoopParser() { + delete parser; + } + + Call *parse_call(void); + + // Delegate to Parser + void getBookmark(ParseBookmark &bookmark) { parser->getBookmark(bookmark); } + void setBookmark(const ParseBookmark &bookmark) { parser->setBookmark(bookmark); } + bool open(const char *filename); + void close(void) { parser->close(); } + unsigned long long getVersion(void) const { return parser->getVersion(); } +private: + int loopCount; + AbstractParser *parser; + ParseBookmark frameStart; + ParseBookmark lastFrameStart; +}; + + +bool +LastFrameLoopParser::open(const char *filename) +{ + bool ret = parser->open(filename); + if (ret) { + /* If the user wants to loop we need to get a bookmark target. We + * usually get this after replaying a call that ends a frame, but + * for a trace that has only one frame we need to get it at the + * beginning. */ + parser->getBookmark(frameStart); + lastFrameStart = frameStart; + } + return ret; +} + +Call * +LastFrameLoopParser::parse_call(void) +{ + trace::Call *call; + + call = parser->parse_call(); + + /* Restart last frame when looping is requested. */ + if (call) { + lastFrameStart = frameStart; + if (call->flags & trace::CALL_FLAG_END_FRAME) { + parser->getBookmark(frameStart); + } + } else { + if (loopCount) { + frameStart = lastFrameStart; + parser->setBookmark(frameStart); + call = parser->parse_call(); + if (loopCount > 0) { + --loopCount; + } + } + } + + return call; +} + + +AbstractParser * +lastFrameLoopParser(AbstractParser *parser, int loopCount) +{ + return new LastFrameLoopParser(parser, loopCount); +} + + +} /* namespace trace */ diff --git a/common/trace_profiler.cpp b/common/trace_profiler.cpp index b7653409..65c91aad 100644 --- a/common/trace_profiler.cpp +++ b/common/trace_profiler.cpp @@ -116,7 +116,6 @@ void Profiler::addCall(unsigned no, gpuStart -= baseGpuTime; } else { gpuStart = 0; - gpuDuration = 0; } if (cpuTimes && cpuStart) { diff --git a/common/trace_profiler.hpp b/common/trace_profiler.hpp index e3ae016b..ebe28b46 100644 --- a/common/trace_profiler.hpp +++ b/common/trace_profiler.hpp @@ -24,8 +24,7 @@ * **************************************************************************/ -#ifndef TRACE_PROFILER_H -#define TRACE_PROFILER_H +#pragma once #include <string> #include <vector> @@ -142,4 +141,3 @@ private: }; } -#endif // TRACE_PROFILER_H diff --git a/common/trace_snappy.hpp b/common/trace_snappy.hpp new file mode 100644 index 00000000..57d47a8d --- /dev/null +++ b/common/trace_snappy.hpp @@ -0,0 +1,61 @@ +/************************************************************************** + * + * Copyright 2015 VMware, Inc + * Copyright 2011 Zack Rusin + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + +/* + * Snappy file format. + * ------------------- + * + * Snappy at its core is just a compressoin algorithm so we're + * creating a new file format which uses snappy compression + * to hold the trace data. + * + * The file is composed of a number of chunks, they are: + * chunk { + * uint32 - specifying the length of the compressed data + * compressed data, in little endian + * } + * File can contain any number of such chunks. + * The default size of an uncompressed chunk is specified in + * SNAPPY_CHUNK_SIZE. + * + * Note: + * Currently the default size for a a to-be-compressed data is + * 1mb, meaning that the compressed data will be <= 1mb. + * The reason it's 1mb is because it seems + * to offer a pretty good compression/disk io speed ratio + * but that might change. + * + */ + + +#pragma once + + +#define SNAPPY_BYTE1 'a' +#define SNAPPY_BYTE2 't' + + diff --git a/common/trace_writer.cpp b/common/trace_writer.cpp index e7e3df21..3ad06e4f 100644 --- a/common/trace_writer.cpp +++ b/common/trace_writer.cpp @@ -29,10 +29,11 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <wchar.h> #include <vector> #include "os.hpp" -#include "trace_file.hpp" +#include "trace_ostream.hpp" #include "trace_writer.hpp" #include "trace_format.hpp" @@ -42,27 +43,26 @@ namespace trace { Writer::Writer() : call_no(0) { - m_file = File::createSnappy(); - close(); + m_file = nullptr; } Writer::~Writer() { close(); - delete m_file; - m_file = NULL; } void Writer::close(void) { - m_file->close(); + delete m_file; + m_file = nullptr; } bool Writer::open(const char *filename) { close(); - if (!m_file->open(filename, File::Write)) { + m_file = createSnappyStream(filename); + if (!m_file) { return false; } @@ -109,13 +109,13 @@ Writer::_writeUInt(unsigned long long value) { void inline Writer::_writeFloat(float value) { - assert(sizeof value == 4); + static_assert(sizeof value == 4, "float is not 4 bytes"); _write((const char *)&value, sizeof value); } void inline Writer::_writeDouble(double value) { - assert(sizeof value == 8); + static_assert(sizeof value == 8, "double is not 8 bytes"); _write((const char *)&value, sizeof value); } @@ -278,13 +278,37 @@ void Writer::writeString(const char *str, size_t len) { _write(str, len); } -void Writer::writeWString(const wchar_t *str) { +void Writer::writeWString(const wchar_t *str, size_t len) { if (!str) { Writer::writeNull(); return; } + /* XXX: Encode wide-strings as ASCII for now, to avoid introducing a trace format version bump. */ +#if 0 + _writeByte(trace::TYPE_WSTRING); + size_t len = wcslen(str); + _writeUInt(len); + for (size_t i = 0; i < len; ++i) { + _writeUInt(str[i]); + } +#else _writeByte(trace::TYPE_STRING); - _writeString("<wide-string>"); + _writeUInt(len); + for (size_t i = 0; i < len; ++i) { + wchar_t wc = str[i]; + char c = wc >= 0 && wc < 0x80 ? (char)wc : '?'; + _writeByte(c); + } +#endif +} + +void Writer::writeWString(const wchar_t *str) { + if (!str) { + Writer::writeNull(); + return; + } + size_t len = wcslen(str); + writeWString(str, len); } void Writer::writeBlob(const void *data, size_t size) { diff --git a/common/trace_writer.hpp b/common/trace_writer.hpp index 4c954778..e293a938 100644 --- a/common/trace_writer.hpp +++ b/common/trace_writer.hpp @@ -27,8 +27,7 @@ * Trace writing functions. */ -#ifndef _TRACE_WRITER_HPP_ -#define _TRACE_WRITER_HPP_ +#pragma once #include <stddef.h> @@ -38,11 +37,11 @@ #include "trace_model.hpp" namespace trace { - class File; + class OutStream; class Writer { protected: - File *m_file; + OutStream *m_file; unsigned call_no; std::vector<bool> functions; @@ -94,6 +93,7 @@ namespace trace { void writeString(const char *str); void writeString(const char *str, size_t size); void writeWString(const wchar_t *str); + void writeWString(const wchar_t *str, size_t size); void writeBlob(const void *data, size_t size); void writeEnum(const EnumSig *sig, signed long long value); void writeBitmask(const BitmaskSig *sig, unsigned long long value); @@ -114,4 +114,3 @@ namespace trace { } /* namespace trace */ -#endif /* _TRACE_WRITER_HPP_ */ diff --git a/common/trace_writer_local.cpp b/common/trace_writer_local.cpp index 72f636aa..a30c4d74 100644 --- a/common/trace_writer_local.cpp +++ b/common/trace_writer_local.cpp @@ -39,7 +39,8 @@ #include "os_thread.hpp" #include "os_string.hpp" #include "range.hpp" -#include "trace_file.hpp" +#include "os_version.hpp" +#include "trace_ostream.hpp" #include "trace_writer_local.hpp" #include "trace_format.hpp" #include "os_backtrace.hpp" @@ -70,7 +71,8 @@ static void exceptionCallback(void) LocalWriter::LocalWriter() : acquired(0) { - os::log("apitrace: loaded\n"); + os::String process = os::getProcessName(); + os::log("apitrace: loaded into %s\n", process.str()); // Install the signal handlers as early as possible, to prevent // interfering with the application's signal handling. @@ -81,6 +83,9 @@ LocalWriter::~LocalWriter() { os::resetExceptionCallback(); checkProcessId(); + + os::String process = os::getProcessName(); + os::log("apitrace: unloaded from %s\n", process.str()); } void @@ -100,10 +105,22 @@ LocalWriter::open(void) { process.trimDirectory(); #ifdef ANDROID - os::String prefix = "/data/data"; - prefix.join(process); + os::String prefix = "/data/data"; + prefix.join(process); #else - os::String prefix = os::getCurrentDir(); + os::String prefix = os::getCurrentDir(); +#ifdef _WIN32 + // Avoid writing into Windows' system directory as quite often access + // will be denied. + if (IsWindows8OrGreater()) { + char szDirectory[MAX_PATH + 1]; + GetSystemDirectoryA(szDirectory, sizeof szDirectory); + if (stricmp(prefix, szDirectory) == 0) { + GetTempPathA(sizeof szDirectory, szDirectory); + prefix = szDirectory; + } + } +#endif #endif prefix.join(process); @@ -147,13 +164,13 @@ static OS_THREAD_SPECIFIC(uintptr_t) thread_num; void LocalWriter::checkProcessId(void) { - if (m_file->isOpened() && + if (m_file && os::getCurrentProcessId() != pid) { // We are a forked child process that inherited the trace file, so // create a new file. We can't call any method of the current // file, as it may cause it to flush and corrupt the parent's // trace, so we effectively leak the old file object. - m_file = File::createSnappy(); + close(); // Don't want to open the same file again os::unsetEnvironment("TRACE_FILE"); open(); @@ -165,7 +182,7 @@ unsigned LocalWriter::beginEnter(const FunctionSig *sig, bool fake) { ++acquired; checkProcessId(); - if (!m_file->isOpened()) { + if (!m_file) { open(); } @@ -219,7 +236,7 @@ void LocalWriter::flush(void) { os::log("apitrace: ignoring exception while tracing\n"); } else { ++acquired; - if (m_file->isOpened()) { + if (m_file) { if (os::getCurrentProcessId() != pid) { os::log("apitrace: ignoring exception in child process\n"); } else { @@ -422,5 +439,41 @@ void LocalWriter::updateRegion(const void *ptr, size_t size) { LocalWriter localWriter; +void fakeMemcpy(const void *ptr, size_t size) { + assert(ptr); + if (!size) { + return; + } + + unsigned _call = localWriter.beginEnter(&memcpy_sig, true); + +#if defined(_WIN32) && !defined(NDEBUG) + size_t maxSize = 0; + MEMORY_BASIC_INFORMATION mi; + while (VirtualQuery((const uint8_t *)ptr + maxSize, &mi, sizeof mi) == sizeof mi && + mi.Protect & (PAGE_READONLY|PAGE_READWRITE)) { + maxSize = (const uint8_t *)mi.BaseAddress + mi.RegionSize - (const uint8_t *)ptr; + } + if (maxSize < size) { + os::log("apitrace: warning: %u: clamping size from %Iu to %Iu\n", _call, size, maxSize); + size = maxSize; + } +#endif + + localWriter.beginArg(0); + localWriter.writePointer((uintptr_t)ptr); + localWriter.endArg(); + localWriter.beginArg(1); + localWriter.writeBlob(ptr, size); + localWriter.endArg(); + localWriter.beginArg(2); + localWriter.writeUInt(size); + localWriter.endArg(); + localWriter.endEnter(); + localWriter.beginLeave(_call); + localWriter.endLeave(); +} + + } /* namespace trace */ diff --git a/common/trace_writer_local.hpp b/common/trace_writer_local.hpp index e2fbb982..cb4c7437 100644 --- a/common/trace_writer_local.hpp +++ b/common/trace_writer_local.hpp @@ -27,8 +27,7 @@ * Trace writing functions, used to trace calls in the current process. */ -#ifndef _TRACE_WRITER_LOCAL_HPP_ -#define _TRACE_WRITER_LOCAL_HPP_ +#pragma once #include <stdint.h> @@ -118,6 +117,7 @@ namespace trace { */ extern LocalWriter localWriter; + void fakeMemcpy(const void *ptr, size_t size); + } /* namespace trace */ -#endif /* _TRACE_WRITER_LOCAL_HPP_ */ diff --git a/common/trace_writer_model.cpp b/common/trace_writer_model.cpp index 4cf82f65..af5a2b0c 100644 --- a/common/trace_writer_model.cpp +++ b/common/trace_writer_model.cpp @@ -68,6 +68,10 @@ public: writer.writeString(node->value); } + void visit(WString *node) { + writer.writeWString(node->value); + } + void visit(Enum *node) { writer.writeEnum(node->sig, node->value); } diff --git a/common/ubjson.hpp b/common/ubjson.hpp new file mode 100644 index 00000000..04c8b08a --- /dev/null +++ b/common/ubjson.hpp @@ -0,0 +1,111 @@ +/************************************************************************** + * + * Copyright 2015 VMware, Inc + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + + +#pragma once + + +#include <stdint.h> +#include <stdlib.h> + + +namespace ubjson { + + +// http://ubjson.org/type-reference/ +enum Marker { + MARKER_EOF = -1, + MARKER_NULL = 'Z', + MARKER_NOOP = 'N', + MARKER_TRUE = 'T', + MARKER_FALSE = 'F', + MARKER_INT8 = 'i', + MARKER_UINT8 = 'U', + MARKER_INT16 = 'I', + MARKER_INT32 = 'l', + MARKER_INT64 = 'L', + MARKER_FLOAT32 = 'd', + MARKER_FLOAT64 = 'D', + MARKER_HIGH_PRECISION = 'H', + MARKER_CHAR = 'C', + MARKER_STRING = 'S', + MARKER_ARRAY_BEGIN = '[', + MARKER_ARRAY_END = ']', + MARKER_OBJECT_BEGIN = '{', + MARKER_OBJECT_END = '}', + MARKER_TYPE = '$', + MARKER_COUNT = '#', +}; + + +inline uint16_t +bigEndian16(uint16_t x) { +#ifdef HAVE_BIGENDIAN + return x; +#elif defined(_MSC_VER) + return _byteswap_ushort(x); +#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 + return __builtin_bswap16(x); +#else + return (x << 8) | (x >> 8); +#endif +} + +inline uint32_t +bigEndian32(uint32_t x) { +#ifdef HAVE_BIGENDIAN + return x; +#elif defined(_MSC_VER) + return _byteswap_ulong(x); +#else + return __builtin_bswap32(x); +#endif +} + +inline uint64_t +bigEndian64(uint64_t x) { +#ifdef HAVE_BIGENDIAN + return x; +#elif defined(_MSC_VER) + return _byteswap_uint64(x); +#else + return __builtin_bswap64(x); +#endif +} + + +union Float32 { + float f; + uint32_t i; +}; + + +union Float64 { + double f; + uint64_t i; +}; + + +} |