also a nice change in tree, to support the 40,000 deep symbol tree test that was barfing.
this was totally due to having a recursive destructor with a crazy deep tree; we blew out the stack on windows,
which we never even noticed on linux. replacement algorithm does an iterative spider instead of beautiful
recursion, but it also handles arbitrarily large trees with no additional stack frames.
\*****************************************************************************/
#include "windoze_helper.h"
-///#include "array.h"
-///#include "build_configuration.h"
-///#include "convert_utf.h"
-///#include "function.h"
-///#include "mutex.h"
-///#include "portable.h"
-///#include "set.h"
-///#include "version_record.h"
#include <configuration/application_configuration.h>
+#include <loggers/program_wide_logger.h>
///#include <errno.h>
///#include <stdlib.h>
*/
using namespace basis;
+using namespace loggers;
using namespace structures;
using namespace configuration;
#undef static_class_name
#define static_class_name() "windoze_helper"
+#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
+
/*
//#define DEBUG_PORTABLE
// uncomment for noisy debugging.
case WIN_XP: return "WIN_XP";
case WIN_SRV2K3: return "WIN_SRV2K3";
case WIN_VISTA: return "WIN_VISTA";
- case WIN_SRV2K8: return "WIN_SRV2K8";
+ case WIN_7: return "WIN_7";
+ case WIN_8: return "WIN_8";
+ case WIN_10: return "WIN_10";
default: return "UNKNOWN_OS";
}
}
known_operating_systems determine_OS()
{
+ FUNCDEF("determine_OS");
version osver = application_configuration::get_OS_version();
if ( (osver.v_major() == 4) && (osver.v_minor() == 0) ) {
if (osver.v_revision() == VER_PLATFORM_WIN32_WINDOWS) return WIN_95;
return WIN_SRV2K3;
} else if ( (osver.v_major() == 6) && (osver.v_minor() == 0) ) {
return WIN_VISTA;
+// } else if ( (osver.v_major() == 6) && (osver.v_minor() == 1) ) {
+// return WIN_SRV2K8;
} else if ( (osver.v_major() == 6) && (osver.v_minor() == 1) ) {
- return WIN_SRV2K8;
+ return WIN_7;
+ } else if ( (osver.v_major() == 6) && (osver.v_minor() == 2) ) {
+ return WIN_8;
+ } else if ( (osver.v_major() == 10) && (osver.v_minor() == 0) ) {
+ return WIN_10;
}
+
+//temp
+LOG(a_sprintf("got a major OS of %d and minor OS of %d", osver.v_major(), osver.v_minor()));
+
return UNKNOWN_OS;
}
#define BROADCAST_HANDLE HWND_BROADCAST
enum known_operating_systems {
- WIN_95, WIN_NT, WIN_2K, WIN_XP, WIN_SRV2K3, WIN_VISTA, WIN_SRV2K8,
+ WIN_95, WIN_NT, WIN_2K, WIN_XP, WIN_SRV2K3, WIN_VISTA,
+///WIN_SRV2K8,
+ WIN_7, WIN_8, WIN_10,
UNKNOWN_OS
};
const char *opsystem_name(known_operating_systems which);
#include <stdlib.h>
#include <string.h>
-//#ifdef __WIN32__
-// #undef strcasecmp
-// #undef strncasecmp
-// #define strcasecmp strcmpi
-// #define strncasecmp strnicmp
-//#endif
+#ifdef _MSC_VER
+ #undef strcasecmp
+ #undef strncasecmp
+ #define strcasecmp strcmpi
+ #define strncasecmp strnicmp
+#endif
//#define DEBUG_STRING
// uncomment for debugging version.
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
-#if defined(__UNIX__) || defined(__GNU_WINDOWS__)
+#if defined(__UNIX__)
#include <unistd.h>
#else
#include <io.h>
// on windows, we want to translate away from any cygwin or msys format into a more palatable
// version that the rest of windows understands.
// first, cygwin...
- const astring CYGDRIVE_PATH = astring(astring(DEFAULT_SEPARATOR, 1) + "cygdrive"
- + astring(DEFAULT_SEPARATOR, 1));
+//hmmm: make these into statics!
+ const astring CYGDRIVE_SENTINEL = "cygdrive";
+ const astring CYGDRIVE_PATH = astring(astring(DEFAULT_SEPARATOR, 1)
+ + CYGDRIVE_SENTINEL + astring(DEFAULT_SEPARATOR, 1));
+
// must be at least as long as the string we're looking for, plus a drive letter afterwards.
- if ( (length() > CYGDRIVE_PATH.length() + 1) && begins(CYGDRIVE_PATH) ) {
+ if ( (length() >= CYGDRIVE_PATH.length() + 1)
+ && separator(get(0))
+ && separator(get(CYGDRIVE_PATH.length() - 1))
+ && compare(CYGDRIVE_SENTINEL, 1,
+ 0, CYGDRIVE_SENTINEL.length(), true) ) {
zap(0, CYGDRIVE_PATH.length() - 1); // whack the cygdrive portion plus two slashes.
insert(1, ":"); // add a colon after the imputed drive letter.
-//LOG(astring("turned cygdrive string into: ") + *this);
+//LOG(astring("turned cygdrive path string into: ") + *this);
+ } else {
+//LOG(astring("path didn't match so left as: ") + *this);
}
// now we convert msys...
if ( (length() >= 2) && (get(0) == DEFAULT_SEPARATOR)
#include <timely/time_stamp.h>
#include <stdio.h>
-#ifdef __UNIX__
+#ifndef _MSC_VER
#include <errno.h>
#endif
basis::un_int critical_events::system_error()
{
-#if defined(__UNIX__)
+#if defined(__UNIX__) || defined(__GNU_WINDOWS__)
return errno;
-#elif defined(__WIN32__)
+#elif defined(_MSC_VER)
return GetLastError();
#else
#pragma error("hmmm: no code for error number for this operating system")
astring critical_events::system_error_text(basis::un_int to_name)
{
-#if defined(__UNIX__)
+#if defined(__UNIX__) || defined(__GNU_WINDOWS__)
return strerror(to_name);
-#elif defined(__WIN32__)
+#elif defined(_MSC_VER)
char error_text[1000];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NIL, to_name,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)error_text,
namespace loggers {
//! This macro wraps the notion of stopping in the debugger.
-#ifdef __UNIX__
+#ifndef _MSC_VER
#define CAUSE_BREAKPOINT
//hmmm: need a unix equivalent for this. supporting gcc might be enough.
-#elif defined(__WIN32__)
+#else
#ifdef __MINGW32__
extern "C" {
// #include <ddk/winddi.h>
using namespace basis;
using namespace structures;
-#define DEBUG_PACKABLE_TREE
+//#define DEBUG_PACKABLE_TREE
// uncomment for noisy debugging.
#undef LOG
void packable_tree::calcit(int &size_accumulator, const packable_tree *current_node)
{
-LOG(a_sprintf("calcing node %x", current_node));
FUNCDEF("calcit");
+#ifdef DEBUG_PACKABLE_TREE
+ LOG(a_sprintf("calcing node %x", current_node));
+#endif
if (!current_node) throw_error(static_class_name(), func, "current node is nil");
tree_command_unit temp;
size_accumulator += current_node->packed_size() + temp.packed_size();
-LOG(a_sprintf("len A %d", size_accumulator));
+#ifdef DEBUG_PACKABLE_TREE
+ LOG(a_sprintf("len A %d", size_accumulator));
+#endif
}
void packable_tree::packit(byte_array &packed_form, const packable_tree *current_node)
//#define DEBUG_SYMBOL_TREE
// uncomment for totally noisy version.
+#include <loggers/program_wide_logger.h>
#undef LOG
#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
+using namespace loggers;
using namespace basis;
using namespace structures;
public:
symbol_tree_associations(int estimated_elements)
: symbol_table<symbol_tree *>(estimated_elements) {}
+ virtual ~symbol_tree_associations() {
+// for (int i = 0; i < symbols(); i++) {
+// WHACK(use(i));
+// }
+ }
};
//////////////
symbol_tree::~symbol_tree()
{
- WHACK(_name);
+ FUNCDEF("destructor");
+LOG("prior to whacks");
WHACK(_associations);
+ WHACK(_name);
+LOG("after whacks");
}
int symbol_tree::children() const { return _associations->symbols(); }
// cousin.
tree *my_parent = parent();
if (my_parent) my_parent->prune(this);
+ my_parent = NIL; // disavow since we are loose now.
+
+#if 0
+
+ //original version suffers from being too recursive on windoze,
+ //which blows out the stack. linux never showed this problem. so, i
+ //guess i'm glad i tested on windows.
+ //anyway, it's a general problem for a degenerate tree like the one
+ //i've constructed. current version has ~40000 direct descendants of
+ //the root in a single line, so the stack has to support 40000 frames
+ //for the delete implementation below to work.
// iterate over the child nodes and whack each individually.
while (branches()) delete branch(0);
// this relies on the child getting out of our branch list.
+#else
+
+ // newer version of delete doesn't recurse; it just iterates instead,
+ // which avoids the massive recursive depth of the original approach.
+ tree *curr_node = this;
+ while (curr_node != NIL) {
+ // make a breadcrumb for getting back to 'here' in the tree.
+ tree *way_back = curr_node;
+ // our main operation here is to go down a node without using any
+ // stack frames. so we just pick the first kid; it's either valid
+ // or there are no kids at all.
+ curr_node = curr_node->branch(0);
+
+ if (curr_node = NIL) {
+ // wayback has no children, so we can take action.
+
+ // if wayback is the same as "this", then we exit from iterations since
+ // we've cleaned all the kids out.
+ if (way_back == this) {
+ break;
+ }
+
+ // we want to whack the wayback node at this point, since it's a parent
+ // with no kids, i.e. a leaf. we've guaranteed we're not going beyond
+ // our remit, since wayback is not the same node as the top level one
+ // in the destructor (as long as there are no cycles in the tree...).
+ curr_node = way_back->parent(); // go up in tree on next iteration.
+ delete way_back; // whack a node, finally.
+
+ } else {
+ // okay, there's a node below here. we will spider down to it.
+ continue;
+ }
+
+
+ }
+
+#endif
+
+
}
tree *tree::parent() const { return (tree *)get_link(BACKWARDS_BRANCH); }
#ifdef __WIN32__
known_operating_systems os = determine_OS();
- if (os == WIN_95)
- printf("This is windows 95.\n");
- else if (os == WIN_NT)
- printf("This is windows NT.\n");
- else if (os == WIN_2K)
- printf("This is windows 2000.\n");
- else if (os == WIN_XP)
- printf("This is windows XP.\n");
- else
- printf("This OS is unknown.\n");
+ astring os_report = "This OS is: ";
+ os_report += opsystem_name(os);
+ os_report += "\n";
+ printf(os_report.s());
#endif
version os_ver = application_configuration::get_OS_version();
test_file_time.exe test_filename.exe test_huge_file.exe
DEFINITIONS += USE_HOOPLE_DLLS
LOCAL_LIBS_USED = unit_test application configuration filesystem loggers \
- mathematics nodes processes structures textual timely structures basis
+ mathematics nodes processes structures textual timely structures basis \
+loggers
RUN_TARGETS = $(ACTUAL_TARGETS)
include cpp/rules.def
//hmmm: plug in real recursive delete here instead.
basis::un_int kid;
-launch_process::run("rm", astring("-rf ") + tmpdir.raw(), launch_process::AWAIT_APP_EXIT, kid);
+launch_process::run("/usr/bin/rm", astring("-rf ") + tmpdir.raw(), launch_process::AWAIT_APP_EXIT, kid);
ASSERT_FALSE(kid, "removing temporary files after test");
}
FUNCDEF("execute");
#ifdef __UNIX__
+ // just open the root directory on unix; always works.
astring toppy("/");
#endif
#ifdef __WIN32__
- astring toppy("c:/ntldr"); // will work for any modern windows OS.
+ // windows cannot fopen a directory. this blows. so we pick a file
+ // that should work for most windowses.
+ astring toppy("c:/Windows/notepad.exe");
#endif
// test storing info via the constructor.
file_time absurdity_time(toppy);
FILE *topdir = fopen(toppy.s(), "r");
+ ASSERT_INEQUAL(topdir, NIL, "opening topdir for testing");
+ if (topdir == NIL) {
+ return 1;
+ }
file_time nutty_time(topdir);
- struct stat sbuffer;
+
int filenum = fileno(topdir);
+ struct stat sbuffer;
int stat_okay = fstat(filenum, &sbuffer);
ASSERT_FALSE(stat_okay, "failure to read filetime");
file_time goofy_time(sbuffer.st_mtime);
{
// eighth test group is only for windows side.
//hmmm: might be nice to get the build machine launching this on a windows vm.
- astring GROUP = "eighth: cygwin and msys paths";
+ astring GROUP = "eighth: cygwin and msys paths ";
filename test1("/cygdrive/q/marbles");
ASSERT_EQUAL(test1, astring("q:\\marbles"), GROUP + "test 1 failed");
filename test2("/cygdrive/r");
filename test14("/r/");
ASSERT_EQUAL(test14, astring("r:\\"), GROUP + "test 14 failed");
filename test15("/r");
- ASSERT_EQUAL(test15, astring("r:"), GROUP + "test 15 failed");
+ ASSERT_EQUAL(test15, astring("r:\\"), GROUP + "test 15 failed");
filename test16("/");
ASSERT_EQUAL(test16, astring("\\"), GROUP + "test 16 failed");
filename test17("r/");
ASSERT_EQUAL(test17, astring("r\\"), GROUP + "test 17 failed");
filename test18("/kr/soop");
- ASSERT_INEQUAL(test18, astring("\\kr\\soop"), GROUP + "test 18 failed");
+ ASSERT_EQUAL(test18, astring("\\kr\\soop"), GROUP + "test 18 failed");
}
#endif
#define DEBUG_SYMBOL_TREE
-class test_symbol_tree : public virtual unit_base, virtual public application_shell
+// how many nodes we add to the tree.
+const int MAX_NODES_TESTED = 40000;
+
+class test_symbol_tree : public unit_base, public application_shell
{
public:
- test_symbol_tree() {}
+ test_symbol_tree() : unit_base() {}
DEFINE_CLASS_NAME("test_symbol_tree");
int execute();
};
int test_symbol_tree::execute()
{
+ FUNCDEF("execute");
LOG("please check memory usage and record it, then hit a key to start testing.");
try {
symbol_tree t("blork");
symbol_tree *curr = &t;
- for (int i = 0; i < 40000; i++) {
+ for (int i = 0; i < MAX_NODES_TESTED; i++) {
// if the current node has any branches, we'll jump on one as the next
// place.
if (curr->branches()) {
return 1;
}
+LOG("got out of the loop");
+
+//one assertion to tickle final report.
+ bool farp = true;
+ ASSERT_TRUE(farp, "tickling reporting for assertions");
+//hmmm: above shouldn't be needed at all.
+
LOG("check memory usage after the run. then hit a key to end "
"the program.");
astring keyword = "FAILURE"; // but be pessimistic about overall result at first..?
+
+BASE_LOG(a_sprintf("total tests %d passed tests %d", c_total_tests, c_passed_tests));
+
// check whether we really did succeed or not.
if (c_total_tests == c_passed_tests) keyword = "SUCCESS"; // success!
else to_return = 12; // a failure return.
#!/bin/bash
-# the basename is the file that needs its manifest stuffed into the file
+# the target is the file that needs its manifest stuffed into the file
# itself. the where parameter tells us what index to use when stuffing it.
-basename=$1
-where=$2
+target=$1; shift
+where=$1; shift
if [ -z "$WIN32_MANIFEST_FILE" ]; then
WIN32_MANIFEST_FILE=$CLAM_DIR/cpp/ms_manifests/security_manifest.txt
fi
-error_val=0
-if [ -f "$basename.manifest" -a -f "$basename" ]; then
- bash $BUILD_SCRIPTS_DIR/wrapdoze.sh mt -manifest $basename.manifest $WIN32_MANIFEST_FILE -outputresource:$basename\;$where >/dev/null
- error_val=$?
-elif [ -f "$basename" ]; then
- bash $BUILD_SCRIPTS_DIR/wrapdoze.sh mt -manifest $WIN32_MANIFEST_FILE -outputresource:$basename\;$where >/dev/null
- error_val=$?
-else
- echo skipping manifest generation for $basename.
- if [ ! -f "$basename.manifest" ]; then echo manifest file was missing.; fi
- if [ ! -f "$basename" ]; then echo main file was missing.; fi
-fi
+for ((count=1 ; count <= 10; count++)); do
+ error_val=0
+ if [ -f "$target.manifest" -a -f "$target" ]; then
+ bash $BUILD_SCRIPTS_DIR/wrapdoze.sh mt -manifest $target.manifest $WIN32_MANIFEST_FILE -outputresource:$target\;$where >/dev/null
+ error_val=$?
+ elif [ -f "$target" ]; then
+ bash $BUILD_SCRIPTS_DIR/wrapdoze.sh mt -manifest $WIN32_MANIFEST_FILE -outputresource:$target\;$where >/dev/null
+ error_val=$?
+ else
+ echo skipping manifest generation for $target.
+ if [ ! -f "$target.manifest" ]; then echo manifest file was missing.; fi
+ if [ ! -f "$target" ]; then echo main file was missing.; fi
+ break
+ fi
+ if [ $error_val -ne 0 ]; then
+ echo "Error attaching manifest to $target at try #$count."
+ else
+ break
+ fi
+done
if [ $error_val -ne 0 ]; then
- echo There was an error attaching manifest to $1.
+ echo There was an error attaching manifest to $target.
exit 12
fi
else
TEMP_OBJ3a = $(TEMP_OBJ2)
endif
- TEMP_OBJ3 = $(TEMP_OBJ3a:%.rc=%.res)
+ ifeq "$(COMPILER)" "VISUAL_CPP"
+ TEMP_OBJ3 = $(TEMP_OBJ3a:%.rc=%.res)
+ else
+ TEMP_OBJ3 = $(TEMP_OBJ3a)
+ endif
else
# replace this when supporting resource files on unix.
TEMP_OBJ3 = $(TEMP_OBJ2:%.rc=)
endif
endif
ifeq "$(OP_SYSTEM)" "WIN32"
- COMPILER := GNU_WINDOWS
-# COMPILER := VISUAL_CPP
+# COMPILER := GNU_WINDOWS
+ COMPILER := VISUAL_CPP
endif
ifeq "$(COMPILER)" ""
# if we get into this case, we have no idea how to set the default
###$(COMPILER_ROOT_DIR)/usr/include/mingw $(COMPILER_ROOT_DIR)/usr/include $(COMPILER_ROOT_DIR)/usr/include/w32api $(COMPILER_ROOT_DIR)/usr/include/extras
COMPILER_LIBRARY_DIR = $(COMPILER_ROOT_DIR)/lib
- DEFINITIONS += __GNU_WINDOWS__ _Windows _WINDOWS WIN32 __WIN32__ __FLAT__ VC_EXTRALEAN WIN32_LEAN_AND_MEAN ATL_NO_LEAN_AND_MEAN _WIN32 __cplusplus __USE_W32_SOCKETS
+ DEFINITIONS += __GNU_WINDOWS__ _Windows _WINDOWS WIN32 __WIN32__ __FLAT__ VC_EXTRALEAN WIN32_LEAN_AND_MEAN ATL_NO_LEAN_AND_MEAN _WIN32 __USE_W32_SOCKETS
+#__cplusplus
#__USE_GNU
LIBRARY_TOOL = ar
MIDL_DEFS = -no_robust
# some lovely definitions used by some of the mfc and other ms code.
DEPENDENCY_DEFINITIONS += __cplusplus __MINGW32__ _WIN32 _CHAR_UNSIGNED M_I86 _M_I86 _M_IX86=500 _WIN32_WINNT=0x501 __RPC_WIN32__ __RPCNDR_H_VERSION__ __RPCPROXY_H_VERSION__ TARGET_IS_NT40_OR_LATER PGM_SETCHILD _MFC_VER=0x0600
+
endif
ifeq "$(COMPILER)" "VISUAL_CPP"