diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2015-05-01 16:24:15 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2015-05-01 16:24:15 +0200 |
commit | a30ba67504ffd12c4db499adbb5ce47a7d1f6036 (patch) | |
tree | 9ae1a7e3849dda6bbb5c578232f6f2fa5b2e7e7e /numlib | |
parent | 89e99e8a827859729729dfc92d74be4a8f96f1a4 (diff) | |
parent | 094535c010320967639e8e86f974d878e80baa72 (diff) |
New release 1.7.0
Diffstat (limited to 'numlib')
-rw-r--r-- | numlib/Jamfile | 11 | ||||
-rw-r--r-- | numlib/aatree.h | 2 | ||||
-rw-r--r-- | numlib/afiles | 2 | ||||
-rw-r--r-- | numlib/numsup.c | 14 | ||||
-rw-r--r-- | numlib/numsup.h | 139 | ||||
-rw-r--r-- | numlib/ui.c | 238 | ||||
-rw-r--r-- | numlib/ui.h | 50 |
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__ */ |