Example #1
0
// gsl_error_handler_t * gsl_set_error_handler_off ()
func SetErrorHandlerOff() *GslErrorHandler {
	oldHandler := uintptr(unsafe.Pointer(C.gsl_set_error_handler_off()))
	prevPtr := uintptr(C.get_go_gsl_error_handler_ptr())
	C.set_go_gsl_error_handler_ptr(unsafe.Pointer(nil))
	if oldHandler == 0 {
		// No previous handler installed.
		return nil
	}
	if prevPtr != 0 {
		// The previous handler was a Go handler, reuse the returned structure.
		return (*GslErrorHandler)(unsafe.Pointer(prevPtr))
	} else {
		// The previous handler was a C handler, create a new Go structure for it via closure.
		return &GslErrorHandler{
			cptr:         oldHandler,
			cSideHandler: true,
			Handler: func(reason string, file string, line int, gslError GslError) {
				cReason := C.CString(reason)
				cFile := C.CString(file)
				C.call_gsl_error_handler((*C.gsl_error_handler_t)(unsafe.Pointer(oldHandler)),
					cReason, cFile, C.int(line), C.int(gslError))
				C.free(unsafe.Pointer(cReason))
				C.free(unsafe.Pointer(cFile))
			},
		}
	}
}
Example #2
0
// gsl_error_handler_t * gsl_set_error_handler (gsl_error_handler_t * new_handler)
func SetErrorHandler(handler *GslErrorHandler) *GslErrorHandler {
	var prevPtr uintptr
	var oldHandler uintptr
	if handler.cptr == 0 {
		if handler.cSideHandler {
			panic("nil gsl_error_handler_t pointer in reused native handler record")
		}
		handler.cptr = uintptr(C.go_gsl_error_handler_proxy)
		prevPtr = uintptr(C.get_go_gsl_error_handler_ptr())
		C.set_go_gsl_error_handler_ptr(unsafe.Pointer(handler))
	}
	if handler.cSideHandler {
		// Install the original handler and clear the Go handler structure global.
		prevPtr = uintptr(C.get_go_gsl_error_handler_ptr())
		C.set_go_gsl_error_handler_ptr(unsafe.Pointer(nil))
	} else {
		// Install the original handler and set the Go handler global to the given
		// go side structure - we also hold a reference to keep the Go GC from deallocating it.
		global_GSL_HANDLER_HELD_REFERENCE = handler
		prevPtr = uintptr(C.get_go_gsl_error_handler_ptr())
		C.set_go_gsl_error_handler_ptr(unsafe.Pointer(handler))
	}
	// Set the new handler active.
	oldHandler = uintptr(unsafe.Pointer(C.gsl_set_error_handler((*C.gsl_error_handler_t)(C.get_go_gsl_error_handler_proxy_addr()))))
	if oldHandler == 0 {
		// No previous handler installed.
		return nil
	}
	if prevPtr != 0 {
		// The previous handler was a Go handler, reuse the returned structure.
		return (*GslErrorHandler)(unsafe.Pointer(prevPtr))
	} else {
		// The previous handler was a C handler, create a new Go structure for it via closure.
		return &GslErrorHandler{
			cptr:         oldHandler,
			cSideHandler: true,
			Handler: func(reason string, file string, line int, gslError GslError) {
				cReason := C.CString(reason)
				cFile := C.CString(file)
				C.call_gsl_error_handler((*C.gsl_error_handler_t)(unsafe.Pointer(oldHandler)),
					cReason, cFile, C.int(line), C.int(gslError))
				C.free(unsafe.Pointer(cReason))
				C.free(unsafe.Pointer(cFile))
			},
		}
	}
}