michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef gdb_gdb_tests_h michael@0: #define gdb_gdb_tests_h michael@0: michael@0: // Support for C++ fragments to be used by Python unit tests for SpiderMonkey's michael@0: // GDB support. michael@0: // michael@0: // That is: michael@0: // - js/src/gdb/mozilla holds the actual GDB SpiderMonkey support code. michael@0: // - Each '.py' file in js/src/gdb/tests is a unit test for the above. michael@0: // - Each '.cpp' file in js/src/gdb/tests is C++ code for one of the unit tests michael@0: // to run. michael@0: // michael@0: // (So the .cpp files are two steps removed from being anything one would michael@0: // actually run.) michael@0: michael@0: #include "NamespaceImports.h" michael@0: michael@0: void breakpoint(); michael@0: michael@0: struct GDBFragment { michael@0: GDBFragment() { michael@0: next = allFragments; michael@0: allFragments = this; michael@0: } michael@0: michael@0: // The name of this fragment. gdb-tests.cpp runs the fragments whose names michael@0: // are passed to it on the command line. michael@0: virtual const char *name() = 0; michael@0: michael@0: // Run the fragment code. |argv| is a reference to the pointer into the michael@0: // command-line argument vector, referring to the argument immediately michael@0: // following this fragment's name. The fragment can consume arguments and michael@0: // advance argv if it wishes. michael@0: virtual void run(JSContext *cx, const char **&argv) = 0; michael@0: michael@0: // We declare one instance of this type for each fragment to run. The michael@0: // constructor adds each instance to a linked list, of which this is michael@0: // the head. michael@0: static GDBFragment *allFragments; michael@0: michael@0: // The link in the list of all instances. michael@0: GDBFragment *next; michael@0: }; michael@0: michael@0: // Macro for declaring a C++ fragment for some Python unit test to call. Usage: michael@0: // michael@0: // FRAGMENT(, ) { } michael@0: // michael@0: // where and are identifiers. The gdb-tests executable michael@0: // takes a series of fragment names as command-line arguments and runs them in michael@0: // turn; each fragment is named . on the command line. michael@0: // michael@0: // The body runs in a scope where 'cx' is a usable JSContext *. michael@0: michael@0: #define FRAGMENT(category, subname) \ michael@0: class FRAGMENT_CLASS_NAME(category, subname): public GDBFragment { \ michael@0: void run(JSContext *cx, const char **&argv); \ michael@0: const char *name() { return FRAGMENT_STRING_NAME(category, subname); } \ michael@0: static FRAGMENT_CLASS_NAME(category, subname) singleton; \ michael@0: }; \ michael@0: FRAGMENT_CLASS_NAME(category, subname) FRAGMENT_CLASS_NAME(category, subname)::singleton; \ michael@0: void FRAGMENT_CLASS_NAME(category, subname)::run(JSContext *cx, const char **&argv) michael@0: michael@0: #define FRAGMENT_STRING_NAME(category, subname) (#category "." #subname) michael@0: #define FRAGMENT_CLASS_NAME(category, subname) Fragment_ ## category ## _ ## subname michael@0: michael@0: #endif /* gdb_gdb_tests_h */