emscripten/tests/nbody-java/xmlvm-hy.c

256 строки
7.1 KiB
C

/*
* Copyright (c) 2002-2011 by XMLVM.org
*
* Project Info: http://www.xmlvm.org
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
#include "xmlvm.h"
#include "xmlvm-hy.h"
const char* errorMessage (I_32 errorCode)
{
PortlibPTBuffers_t ptBuffers;
ptBuffers = hyport_tls_peek ();
if (0 == ptBuffers->errorMessageBufferSize)
{
ptBuffers->errorMessageBuffer = XMLVM_ATOMIC_MALLOC(HYERROR_DEFAULT_BUFFER_SIZE);
if (NULL == ptBuffers->errorMessageBuffer)
{
return "";
}
ptBuffers->errorMessageBufferSize = HYERROR_DEFAULT_BUFFER_SIZE;
}
/* Copy from OS to ptBuffers */
#if !defined(ZOS)
strerror_r(errorCode,
ptBuffers->errorMessageBuffer, ptBuffers->errorMessageBufferSize);
#else
/* Do not have strerror_r on z/OS so use port library function instead */
portLibrary->str_printf(portLibrary, ptBuffers->errorMessageBuffer, ptBuffers->errorMessageBufferSize, strerror(errorCode));
#endif /* ZOS */
ptBuffers->errorMessageBuffer[ptBuffers->errorMessageBufferSize - 1] = '\0';
return ptBuffers->errorMessageBuffer;
}
static const char* swapMessageBuffer (PortlibPTBuffers_t ptBuffers, const char *message)
{
char *tempBuffer = ptBuffers->reportedMessageBuffer;
U_32 tempBufferSize = ptBuffers->reportedMessageBufferSize;
if (message == NULL)
{
return "";
}
/* Can't swap unknown message buffer */
if (message != ptBuffers->errorMessageBuffer)
{
return message;
}
/* Save reported information */
ptBuffers->reportedErrorCode = ptBuffers->portableErrorCode;
ptBuffers->reportedMessageBuffer = ptBuffers->errorMessageBuffer;
ptBuffers->reportedMessageBufferSize = ptBuffers->errorMessageBufferSize;
if (tempBufferSize > 0)
{
tempBuffer[0] = '\0';
}
/* Clear pending fields ready for next error */
ptBuffers->portableErrorCode = 0;
ptBuffers->errorMessageBuffer = tempBuffer;
ptBuffers->errorMessageBufferSize = tempBufferSize;
return ptBuffers->reportedMessageBuffer;
}
void* hyport_tls_get ()
{
java_lang_Thread* curThread = (java_lang_Thread*) java_lang_Thread_currentThread__();
if (curThread->fields.java_lang_Thread.ptBuffers_ == JAVA_NULL) {
curThread->fields.java_lang_Thread.ptBuffers_ = XMLVM_MALLOC(sizeof(PortlibPTBuffers_struct));
XMLVM_BZERO(curThread->fields.java_lang_Thread.ptBuffers_, sizeof(PortlibPTBuffers_struct));
}
return curThread->fields.java_lang_Thread.ptBuffers_;
}
void* hyport_tls_peek ()
{
java_lang_Thread* curThread = (java_lang_Thread*) java_lang_Thread_currentThread__();
return curThread->fields.java_lang_Thread.ptBuffers_;
}
const char* hyerror_last_error_message ()
{
PortlibPTBuffers_t ptBuffers;
/* Was an error saved ? */
ptBuffers = hyport_tls_peek ();
if (NULL == ptBuffers)
{
return "";
}
/* New error ? */
if (ptBuffers->portableErrorCode != 0)
{
const char *message = NULL;
/* Customized message stored ? */
if (ptBuffers->errorMessageBufferSize > 0)
{
if ('\0' != ptBuffers->errorMessageBuffer[0])
{
message = ptBuffers->errorMessageBuffer;
}
}
/* Call a helper to get the last message from the OS. */
if (message == NULL)
{
message = errorMessage (ptBuffers->platformErrorCode);
}
/* Avoid overwrite by internal portlib errors */
return swapMessageBuffer (ptBuffers, message);
}
/* Previous message stored ? */
if (ptBuffers->reportedMessageBufferSize > 0)
{
if ('\0' != ptBuffers->reportedMessageBuffer[0])
{
return ptBuffers->reportedMessageBuffer;
}
}
/* No error. */
return "";
}
I_32 hyerror_last_error_number ()
{
PortlibPTBuffers_t ptBuffers;
/* get the buffers, return failure if not present */
ptBuffers = hyport_tls_peek ();
if (NULL == ptBuffers)
{
return 0;
}
/* New error ? */
if (ptBuffers->portableErrorCode != 0)
{
return ptBuffers->portableErrorCode;
}
else
{
return ptBuffers->reportedErrorCode;
}
}
I_32 hyerror_set_last_error (I_32 platformCode, I_32 portableCode)
{
PortlibPTBuffers_t ptBuffers;
/* get the buffers, allocate if necessary.
* Silently return if not present, what else would the caller do anyway?
*/
ptBuffers = hyport_tls_get ();
if (NULL == ptBuffers)
{
return portableCode;
}
/* Save the last error */
ptBuffers->platformErrorCode = platformCode;
ptBuffers->portableErrorCode = portableCode;
/* Overwrite any customized messages stored */
if (ptBuffers->errorMessageBufferSize > 0)
{
ptBuffers->errorMessageBuffer[0] = '\0';
}
return portableCode;
}
I_32 hyerror_set_last_error_with_message (I_32 portableCode, const char *errorMessage)
{
PortlibPTBuffers_t ptBuffers;
U_32 requiredSize;
/* get the buffers, allocate if necessary.
* Silently return if not present, what else would the caller do anyway?
*/
ptBuffers = hyport_tls_get ();
if (NULL == ptBuffers)
{
return portableCode;
}
/* Save the last error */
ptBuffers->platformErrorCode = -1;
ptBuffers->portableErrorCode = portableCode;
/* Store the message, allocate a bigger buffer if required. Keep the old buffer around
* just in case memory can not be allocated
*/
requiredSize = strlen (errorMessage) + 1;
requiredSize =
requiredSize <
HYERROR_DEFAULT_BUFFER_SIZE ? HYERROR_DEFAULT_BUFFER_SIZE : requiredSize;
if (requiredSize > ptBuffers->errorMessageBufferSize)
{
char *newBuffer = XMLVM_ATOMIC_MALLOC(requiredSize);
if (NULL != newBuffer)
{
if (ptBuffers->errorMessageBuffer != NULL)
{
XMLVM_FREE(ptBuffers->errorMessageBuffer);
}
ptBuffers->errorMessageBuffer = newBuffer;
ptBuffers->errorMessageBufferSize = requiredSize;
}
}
/* Save the message */
if (ptBuffers->errorMessageBufferSize > 0)
{
sprintf(ptBuffers->errorMessageBuffer, "%s", errorMessage);
ptBuffers->errorMessageBuffer[ptBuffers->errorMessageBufferSize - 1] = '\0';
}
return portableCode;
}