summaryrefslogtreecommitdiff
path: root/numlib
diff options
context:
space:
mode:
Diffstat (limited to 'numlib')
-rw-r--r--numlib/Jamfile11
-rw-r--r--numlib/aatree.h2
-rw-r--r--numlib/afiles2
-rw-r--r--numlib/numsup.c14
-rw-r--r--numlib/numsup.h139
-rw-r--r--numlib/ui.c238
-rw-r--r--numlib/ui.h50
7 files changed, 411 insertions, 45 deletions
diff --git a/numlib/Jamfile b/numlib/Jamfile
index dd90e22..87c3c78 100644
--- a/numlib/Jamfile
+++ b/numlib/Jamfile
@@ -10,8 +10,8 @@ PREF_LINKFLAGS = $(LINKDEBUGFLAG) ;
#PREF_LINKFLAGS = $(LINKPROFFLAG) ; # Profile flags
# Products
-Libraries = libnum ;
-Headers = numlib.h ;
+Libraries = libnum libui ;
+Headers = numlib.h libui.h ;
#Install
#InstallFile $(DESTDIR)$(PREFIX)/h : $(Headers) ;
@@ -26,3 +26,10 @@ LINKLIBS = libnum ;
# All test programs are made from a single source file
MainsFromSources dnsqtest.c tpowell.c tdhsx.c LUtest.c svdtest.c zbrenttest.c soboltest.c ;
+# Compile .c as .m
+if $(OS) = MACOSX {
+ ObjectCcFlags ui : -ObjC ;
+}
+
+# UI setup library
+Library libui.lib : ui.c ;
diff --git a/numlib/aatree.h b/numlib/aatree.h
index 2a6df84..4212b09 100644
--- a/numlib/aatree.h
+++ b/numlib/aatree.h
@@ -4,7 +4,7 @@
/*
Andersson binary balanced tree library
- > Created (Julienne Walker): September 10, 2005
+ > Created (Julienne Walker): September 10, 2005
This code is in the public domain. Anyone may
use it or change it in any way that they see
diff --git a/numlib/afiles b/numlib/afiles
index dff62ef..29d6699 100644
--- a/numlib/afiles
+++ b/numlib/afiles
@@ -30,3 +30,5 @@ sobol.h
soboltest.c
aatree.h
aatree.c
+ui.h
+ui.c
diff --git a/numlib/numsup.c b/numlib/numsup.c
index a28dcd2..bfa144b 100644
--- a/numlib/numsup.c
+++ b/numlib/numsup.c
@@ -27,6 +27,7 @@
#include <pthread.h>
#endif
+#define NUMSUP_C
#include "numsup.h"
/*
@@ -239,6 +240,7 @@ void check_if_not_interactive() {
#endif
+
/* Default verbose logging function - print to stdtout */
static void a1_default_v_log(void *cntx, a1log *p, char *fmt, va_list args) {
vfprintf(stdout, fmt, args);
@@ -328,7 +330,7 @@ a1log *new_a1log_d(a1log *log) {
/* Returns NULL */
a1log *del_a1log(a1log *log) {
if (log != NULL) {
- if (--log->refc == 0) {
+ if (--log->refc <= 0) {
#ifdef NT
DeleteCriticalSection(&log->lock);
#endif
@@ -476,7 +478,7 @@ static void g_loge(char *fmt, ...) {
void
verbose(int level, char *fmt, ...) {
- if (level >= g_log->verb) {
+ if (g_log->verb >= level) {
va_list args;
A1LOG_LOCK(g_log);
@@ -1423,7 +1425,7 @@ void matrix_print(char *c, double **a, int nr, int nc) {
/* Platform independent IEE754 conversions */
/*******************************************/
-/* Cast a native double to an IEEE754 encoded single precision value, */
+/* Convert a native double to an IEEE754 encoded single precision value, */
/* in a platform independent fashion. (ie. This works even */
/* on the rare platforms that don't use IEEE 754 floating */
/* point for their C implementation) */
@@ -1462,7 +1464,7 @@ ORD32 doubletoIEEE754(double d) {
return id;
}
-/* Cast a an IEEE754 encoded single precision value to a native double, */
+/* Convert a an IEEE754 encoded single precision value to a native double, */
/* in a platform independent fashion. (ie. This works even */
/* on the rare platforms that don't use IEEE 754 floating */
/* point for their C implementation) */
@@ -1486,7 +1488,7 @@ double IEEE754todouble(ORD32 ip) {
return op;
}
-/* Cast a native double to an IEEE754 encoded double precision value, */
+/* Convert a native double to an IEEE754 encoded double precision value, */
/* in a platform independent fashion. (ie. This works even */
/* on the rare platforms that don't use IEEE 754 floating */
/* point for their C implementation) */
@@ -1525,7 +1527,7 @@ ORD64 doubletoIEEE754_64(double d) {
return id;
}
-/* Cast a an IEEE754 encode double precision value to a native double, */
+/* Convert a an IEEE754 encode double precision value to a native double, */
/* in a platform independent fashion. (ie. This works even */
/* on the rare platforms that don't use IEEE 754 floating */
/* point for their C implementation) */
diff --git a/numlib/numsup.h b/numlib/numsup.h
index b949379..1fb83bc 100644
--- a/numlib/numsup.h
+++ b/numlib/numsup.h
@@ -35,8 +35,6 @@
#endif
/* =========================================================== */
-/* Should this go in spectro/conv.h ?? */
-/* =========================================================== */
/* Platform specific primitive defines. */
/* This really needs checking for each different platform. */
/* Using C99 and MSC covers a lot of cases, */
@@ -45,7 +43,16 @@
/* so long shouldn't really be used in any code.... */
/* (duplicated in icc.h) */
-#if (__STDC_VERSION__ >= 199901L) /* C99 */
+/* Use __LP64__ as cross platform 64 bit pointer #define */
+#if !defined(__LP64__) && defined(_WIN64)
+# define __LP64__ 1
+#endif
+
+#ifndef ORD32
+
+#if (__STDC_VERSION__ >= 199901L) /* C99 */ \
+ || defined(_STDINT_H_) || defined(_STDINT_H) \
+ || defined(_SYS_TYPES_H)
#include <stdint.h>
@@ -60,17 +67,11 @@
#define PNTR intptr_t
-/* printf format precision specifier */
-#define PF64PREC "ll"
-
-/* Constant precision specifier */
-#define CF64PREC "LL"
-
-#ifndef ATTRIBUTE_NORETURN
-# define ATTRIBUTE_NORETURN __declspec(noreturn)
-#endif
+#define PF64PREC "ll" /* printf format precision specifier */
+#define CF64PREC "LL" /* Constant precision specifier */
#else /* !__STDC_VERSION__ */
+
#ifdef _MSC_VER
#define INR8 __int8 /* 8 bit signed */
@@ -86,15 +87,8 @@
#define vsnprintf _vsnprintf
-/* printf format precision specifier */
-#define PF64PREC "I64"
-
-/* Constant precision specifier */
-#define CF64PREC "LL"
-
-#ifndef ATTRIBUTE_NORETURN
-# define ATTRIBUTE_NORETURN __declspec(noreturn)
-#endif
+#define PF64PREC "I64" /* printf format precision specifier */
+#define CF64PREC "LL" /* Constant precision specifier */
#else /* !_MSC_VER */
@@ -109,26 +103,87 @@
#define ORD32 unsigned int /* 32 bit unsigned */
#ifdef __GNUC__
-#define INR64 long long /* 64 bit signed - not used in icclib */
-#define ORD64 unsigned long long /* 64 bit unsigned - not used in icclib */
+# define INR64 long long /* 64 bit signed - not used in icclib */
+# define ORD64 unsigned long long /* 64 bit unsigned - not used in icclib */
+# define PF64PREC "ll" /* printf format precision specifier */
+# define CF64PREC "LL" /* Constant precision specifier */
+#endif /* __GNUC__ */
-/* printf format precision specifier */
-#define PF64PREC "ll"
+#define PNTR unsigned long
+
+#endif /* !_MSC_VER */
+#endif /* !__STDC_VERSION__ */
+#endif /* !ORD32 */
-/* Constant precision specifier */
-#define CF64PREC "LL"
+#ifdef _MSC_VER
+#ifndef ATTRIBUTE_NORETURN
+# define ATTRIBUTE_NORETURN __declspec(noreturn)
+#endif
+#endif
+#ifdef __GNUC__
#ifndef ATTRIBUTE_NORETURN
-#define ATTRIBUTE_NORETURN __attribute__((noreturn))
+# define ATTRIBUTE_NORETURN __attribute__((noreturn))
+#endif
#endif
-#endif /* __GNUC__ */
/* =========================================================== */
+/* System compatibility #defines */
+#if defined (NT)
-#define PNTR unsigned long
+#ifndef sys_stat
+# define sys_stat _stat
+#endif
+#ifndef sys_mkdir
+# define sys_mkdir _mkdir
+#endif
+#ifndef sys_read
+# define sys_read _read
+#endif
+#ifndef sys_utime
+# define sys_utime _utime
+# define sys_utimbuf _utimbuf
+#endif
+#ifndef sys_access
+# define sys_access _access
+#endif
-#endif /* !_MSC_VER */
-#endif /* !__STDC_VERSION__ */
+#ifndef snprintf
+# define snprintf _snprintf
+# define vsnprintf _vsnprintf
+#endif
+#ifndef stricmp
+# define stricmp _stricmp
+#endif
+
+#endif /* NT */
+
+#if defined (UNIX)
+
+#ifndef sys_stat
+# define sys_stat stat
+#endif
+#ifndef sys_mkdir
+# define sys_mkdir mkdir
+#endif
+#ifndef sys_read
+# define sys_read read
+#endif
+#ifndef sys_utime
+# define sys_utime utime
+# define sys_utimbuf utimbuf
+#endif
+#ifndef sys_access
+# define sys_access access
+#endif
+
+#ifndef stricmp
+# define stricmp strcasecmp
+#endif
+
+#endif /* UNIX */
+
+/* =========================================================== */
/* Some default math limits and constants */
#ifndef DBL_EPSILON
#define DBL_EPSILON 2.2204460492503131e-016 /* 1.0+DBL_EPSILON != 1.0 */
@@ -235,7 +290,7 @@ a1log *new_a1log_d(a1log *log);
/* Returns NULL */
a1log *del_a1log(a1log *log);
-/* Set the tag. Note that the tage string is NOT copied, just referenced */
+/* Set the tag. Note that the tag string is NOT copied, just referenced */
void a1log_tag(a1log *log, char *tag);
/* Log a verbose message if level >= verb */
@@ -279,12 +334,15 @@ extern char cr_char;
/* =========================================================== */
+
+/* =========================================================== */
+
/* reallocate and clear new allocation */
void *recalloc( /* Return new address */
-void *ptr, /* Current address */
-size_t cnum, /* Current number and unit size */
+void *ptr, /* Current address */
+size_t cnum, /* Current number and unit size */
size_t csize,
-size_t nnum, /* New number and unit size */
+size_t nnum, /* New number and unit size */
size_t nsize
);
@@ -438,6 +496,15 @@ INR64 read_INR64_le(ORD8 *p);
void write_INR64_be(INR64 d, ORD8 *p);
void write_INR64_le(INR64 d, ORD8 *p);
+/*******************************************/
+/* Numerical diagnostics */
+
+#ifndef isNan
+#define isNan(x) ((x) != (x))
+#define isFinite(x) ((x) == 0.0 || (x) * 1.0000001 != (x))
+#endif
+
+
#ifdef __cplusplus
}
#endif
diff --git a/numlib/ui.c b/numlib/ui.c
new file mode 100644
index 0000000..fefdcc2
--- /dev/null
+++ b/numlib/ui.c
@@ -0,0 +1,238 @@
+
+
+#define __UI_C__
+
+/*
+ * Do OS specific setup for using UI windows.
+ *
+ * Copyright 2014 Graeme W. Gill
+ * All rights reserved.
+ *
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ *
+ * Typically we need to set things up and then call the
+ * "normal" main, called "uimain" in ArgyllCMS utils.
+ */
+
+#ifdef UNIX
+
+#if __APPLE__
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/* OS X */
+
+/*
+
+ OS X is dumb in relying on an event loop that
+ _has_ to be in the main thread to operate.
+ Since we can invoke UI operations from any thread,
+ the way we work around this is to intercept the
+ main thread, spawn a secondary thread to run the
+ application main(), and then do nothing but
+ service the events in the main thread.
+
+ Note though that Cocoa has poor thread safety :-
+ ie. NSRunLoop can't be used to access events - use CFRunLoop
+
+ Should bracket all drawing code between the lockFocusIfCanDraw and
+ unlockFocus methods of NSView ? Or is this only a problem if
+ different threads try and draw to the same window ?
+
+ */
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <pthread.h>
+
+# include <Foundation/Foundation.h>
+# include <AppKit/AppKit.h>
+
+/* This is a mechanism to force libui to link */
+int ui_initialized = 0;
+
+static int g_argc;
+static char **g_argv;
+
+pthread_t ui_thid = 0; /* Thread ID of main thread running io run loop */
+pthread_t ui_main_thid = 0; /* Thread ID of thread running application main() */
+
+static void *callMain(void *p) {
+ int rv;
+
+ ui_main_thid = pthread_self();
+
+ NSAutoreleasePool *tpool = [NSAutoreleasePool new];
+
+ rv = uimain(g_argc, g_argv);
+
+ [tpool release];
+
+ exit(rv);
+}
+
+/* Dumy method for NSThread to start */
+@interface MainClass : NSObject
++(void)dummyfunc:(id)param;
+@end
+
+@implementation MainClass
++(void)dummyfunc:(id)param{
+}
+
+@end
+
+int main(int argc, char ** argv) {
+
+ ui_thid = pthread_self();
+
+ /* Create an NSApp */
+ static NSAutoreleasePool *pool = nil;
+ ProcessSerialNumber psn = { 0, 0 };
+
+ /* Transform the process so that the desktop interacts with it properly. */
+ /* We don't need resources or a bundle if we do this. */
+ if (GetCurrentProcess(&psn) == noErr) {
+ OSStatus stat;
+ if (psn.lowLongOfPSN != 0 && (stat = TransformProcessType(&psn,
+ kProcessTransformToForegroundApplication)) != noErr) {
+// fprintf(stderr,"TransformProcess failed with code %d\n",stat);
+ } else {
+// fprintf(stderr,"TransformProcess suceeded\n");
+ }
+// if ((stat = SetFrontProcess(&psn)) != noErr) {
+// fprintf(stderr,"SetFrontProcess returned error %d\n",stat);
+// }
+ }
+
+ pool = [NSAutoreleasePool new];
+
+ [NSApplication sharedApplication]; /* Creates NSApp */
+ [NSApp finishLaunching];
+
+ /* We seem to need this, because otherwise we don't get focus automatically */
+ [NSApp activateIgnoringOtherApps: YES];
+
+ /* We need to create at least one NSThread to tell Cocoa that we are using */
+ /* threads, and to protect Cococa objects. */
+ [NSThread detachNewThreadSelector:@selector(dummyfunc:) toTarget:[MainClass class] withObject:nil];
+
+ /* Call the real main() in another thread */
+ int rv;
+ pthread_t thid;
+ g_argc = argc;
+ g_argv = argv;
+
+ ui_initialized = 1;
+
+ if ((rv = pthread_create(&thid, NULL, callMain, (void *)NULL)) != 0) {
+ fprintf(stderr,"ui: pthread_create failed with %d\n",rv);
+ return -1;
+ }
+
+ /* Service the run queue */
+ [NSApp run];
+
+ /* Note that we don't actually clean this up on exit - */
+ /* possibly we can't. */
+// [NSApp terminate: nil];
+}
+
+#else /* !APPLE */
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/* UNIX */
+
+/* This is a mechanism to force libui to link */
+int ui_initialized = 1; /* Nothing needs initializing */
+
+#endif /* !APPLE */
+
+#endif /* UNIX */
+
+#ifdef NT
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+/* NT */
+
+#ifdef NEVER
+
+/*
+ This code isn't generally usable for console programs, because
+ Microsoft changed the default behaviour of cmd.exe in Vista to
+ not wait for a gui mode .exe to terminate. A non-gui .exe always
+ pops a new console if run from explorer.
+
+ So this approach is still viable for primarily gui programs
+ to output debug to stdout, but a different shell or "cmd.exe /E:OFF"
+ is needed to interact with it via the shell.
+
+ Alternatives are messy - mark the exe as console and
+ have it shut down the popup console in gui mode (looks
+ ugly), or have a stub app.bat that invokes the
+ real .exe, forcing cmd.exe to operate in the mode where
+ it waits for execution to finish.
+*/
+
+/* This is a mechanism to force libui to link */
+int ui_initialized = 0;
+
+/*
+
+ On MSWin we can rely on WinMain to be called instead of
+ main(), so that we can re-attache the stdio so that the
+ resulting exe works the same when involked either from
+ a shell, or directly from explorer.
+
+ */
+
+/* May have to add link flag -Wl,-subsystem,windows */
+/* since MingW is stupid about noticing WinMain or pragma */
+
+#include <windows.h>
+#include <stdio.h>
+
+# pragma comment( linker, "/subsystem:windows" )
+//# pragma comment( linker, "/subsystem:console /ENTRY:WinMainCRTStartup" )
+//# pragma comment( linker, "/subsystem:windows /ENTRY:mainCRTStartup" )
+//# pragma comment( linker, "/subsystem:windows /ENTRY:WinMainCRTStartup" )
+
+APIENTRY WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow
+) {
+ { /* Only works on >= XP though */
+ BOOL (WINAPI *AttachConsole)(DWORD dwProcessId);
+
+ *(FARPROC *)&AttachConsole =
+ GetProcAddress(LoadLibraryA("kernel32.dll"), "AttachConsole");
+
+ if (AttachConsole != NULL && AttachConsole(((DWORD)-1)))
+ {
+ if (_fileno(stdout) < 0)
+ freopen("CONOUT$","wb",stdout);
+ if (_fileno(stderr) < 0)
+ freopen("CONOUT$","wb",stderr);
+ if (_fileno(stdin) < 0)
+ freopen("CONIN$","rb",stdin);
+#ifdef __cplusplus
+ // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog point to console as well
+ std::ios::sync_with_stdio();
+#endif
+ }
+ }
+
+ ui_initialized = 1;
+
+ return uimain(__argc, __argv);
+}
+
+#else /* !NEVER */
+
+/* This is a mechanism to force libui to link */
+int ui_initialized = 1; /* Nothing needs initializing */
+
+#endif /* !NEVER */
+
+#endif /* NT */
diff --git a/numlib/ui.h b/numlib/ui.h
new file mode 100644
index 0000000..e1d7a58
--- /dev/null
+++ b/numlib/ui.h
@@ -0,0 +1,50 @@
+
+#ifndef __UI_H__
+
+/*
+ * Do OS specific setup for using UI windows.
+ * Include this only in file with main().
+ *
+ * Copyright 2014 Graeme W. Gill
+ * All rights reserved.
+ *
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ *
+ * Typically we need to set things up and then call the
+ * "normal" main, called "uimain" in ArgyllCMS utils.
+ */
+
+/* Because linkers are dumb (they pass over a library containing main() */
+/* and then complain that there is no entry point!), we force linking */
+/* of libui if ui.h gets #included. */
+extern int ui_initialized;
+static int *pui_initialized = &ui_initialized;
+
+#ifdef UNIX
+# ifdef __APPLE__
+
+extern pthread_t ui_thid; /* Thread ID of main thread running io run loop */
+extern pthread_t ui_main_thid; /* Thread ID of thread running application main() */
+
+#ifndef __UI_C__
+# define main uimain
+#endif
+
+#else /* Linux etc. */
+
+#endif /* Linux etc. */
+#endif /* UNIX */
+
+#ifdef NT
+
+#ifdef NEVER /* Not practical - see ui.c for full explanation */
+#ifndef __UI_C__
+# define main uimain
+#endif
+#endif
+
+#endif
+
+#define __UI_H__
+#endif /* __UI_H__ */