/* Lookup an external function. Return function address if success, NULL otherwise. * package_handle - DLL handle returned by fgn_getpak * entry_name - symbol name to be looked up * msgtype - message severity of the errors reported if any. * Note: If msgtype is SUCCESS, errors are not issued. It is useful if the callers are not * interested in message report and not willing to have condition handler overhead (eg. zro_search). */ fgnfnc fgn_getrtn(void_ptr_t package_handle, mstr *entry_name, int msgtype) { void_ptr_t sym_addr; char_ptr_t dummy_err_str; void *short_sym_addr; char err_str[MAX_ERRSTR_LEN]; /* needed as util_out_print doesn't handle 64bit pointers */ error_def(ERR_DLLNORTN); error_def(ERR_TEXT); if (!(sym_addr = dlsym(package_handle, entry_name->addr))) { if (SUCCESS != msgtype) { assert(!(msgtype & ~SEV_MSK)); COPY_DLLERR_MSG; rts_error(VARLSTCNT(8) MAKE_MSG_TYPE(ERR_DLLNORTN, msgtype), 2, LEN_AND_STR(entry_name->addr), ERR_TEXT, 2, LEN_AND_STR(err_str)); } } else { /* Tru64 - dlsym() is bound to return short pointer because of ld -taso flag used for GT.M */ #ifdef __osf__ short_sym_addr = sym_addr; if (short_sym_addr != sym_addr) { sym_addr = NULL; /* always report an error irrespective of msgtype - since this code should never * have executed and/or the DLL might need to be rebuilt with 32-bit options */ rts_error(VARLSTCNT(8) ERR_DLLNORTN, 2, LEN_AND_STR(entry_name->addr), ERR_TEXT, 2, LEN_AND_LIT("Symbol is loaded above the lower 31-bit address space")); } #endif } return (fgnfnc)sym_addr; }
void fgn_closepak(void_ptr_t package_handle, int msgtype) { char_ptr_t dummy_err_str; int status; char err_str[MAX_ERRSTR_LEN]; error_def(ERR_TEXT); error_def(ERR_DLLNOCLOSE); status = dlclose(package_handle); if (0 != status && SUCCESS != msgtype) { assert(!(msgtype & ~SEV_MSK)); COPY_DLLERR_MSG; rts_error(VARLSTCNT(6) MAKE_MSG_TYPE(ERR_DLLNOCLOSE, msgtype), 0, ERR_TEXT, 2, LEN_AND_STR(err_str)); } }
/* Lookup package. Return package handle if success, NULL otherwise. * package_name - DLL name * msgtype - message severity of the errors reported if any. * Note - Errors are not issued if msgtype is SUCCESS, which is to be used if the callers are not * interested in message report and not willing to have condition handler overhead. */ void_ptr_t fgn_getpak(char *package_name, int msgtype) { void_ptr_t ret_handle; char_ptr_t dummy_err_str; char err_str[MAX_ERRSTR_LEN]; /* needed as util_out_print doesn't handle 64bit pointers */ error_def(ERR_TEXT); error_def(ERR_DLLNOOPEN); if (!(ret_handle = dlopen(package_name, RTLD_LAZY))) { if (SUCCESS != msgtype) { assert(!(msgtype & ~SEV_MSK)); COPY_DLLERR_MSG; rts_error(VARLSTCNT(8) MAKE_MSG_TYPE(ERR_DLLNOOPEN, msgtype), 2, LEN_AND_STR(package_name), ERR_TEXT, 2, LEN_AND_STR(err_str)); } } return ret_handle; }
/* This function issues a BADCHAR error and prints the sequences of bytes that comprise the bad multi-byte character. * If "len" is 0, the function determines how many bytes this multi-byte character is comprised of and prints all of it. * If "len" is non-zero, the function prints "len" number of bytes from "str" in the error message. * This is the work-horse routine for the 3 above variants of utf8_badchar*(). The differences are in how the error * is delivered and what happens afterwards. For the 3 options: * * err_rts - uses rts_error() to raise the error * err_stx - uses stx_error to raise the error * err_dec - uses dec_err to raise the error */ STATICFNDEF void utf8_badchar_real(utf8_err_type err_type, int len, unsigned char *str, unsigned char *strtop, int chset_len, unsigned char *chset) { unsigned char *strptr, *strend, *outstr; unsigned char errtxt[OUT_BUFF_SIZE]; int tmplen; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; assert(gtm_utf8_mode); if (0 == len) { /* Determine the maximal length (upto 4 bytes) of the invalid byte sequence */ for (strend = str; len <= 4 && strend < strtop; ++strend, ++len) { if (UTF8_VALID(strend, strtop, tmplen)) break; } } else strend = str + len; strptr = str; outstr = &errtxt[0]; for (; strptr < strend; ++strptr, ++outstr) { outstr = (unsigned char*)i2asc((uchar_ptr_t)outstr, *strptr); *outstr = ','; } if (0 < len) /* do not include the last comma */ outstr--; if (err_dec == err_type) { assert(NULL != show_source_line_fptr); (*show_source_line_fptr)(TRUE); /* Prints errant source line and pointer to where parsing detected the error */ } if (0 < chset_len) { switch(err_type) { case err_rts: rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0], chset_len, chset); break; /* Never get here but keeps compiler happy */ case err_stx: assert(NULL != stx_error_fptr); (*stx_error_fptr)(ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0], chset_len, chset); break; case err_dec: dec_err(VARLSTCNT(6) (TREF(compile_time) ? MAKE_MSG_TYPE(ERR_BADCHAR, WARNING) : ERR_BADCHAR), 4, (outstr - &errtxt[0]), &errtxt[0], chset_len, chset); break; default: assertpro(FALSE /* Invalid error type */); } } else { switch(err_type) { case err_rts: rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0], LEN_AND_LIT(UTF8_NAME)); break; /* Never get here but keeps compiler happy */ case err_stx: assert(NULL != stx_error_fptr); (*stx_error_fptr)(ERR_BADCHAR, 4, (outstr - &errtxt[0]), &errtxt[0], LEN_AND_LIT(UTF8_NAME)); break; case err_dec: dec_err(VARLSTCNT(6) (TREF(compile_time) ? MAKE_MSG_TYPE(ERR_BADCHAR, WARNING) : ERR_BADCHAR), 4, (outstr - &errtxt[0]), &errtxt[0], LEN_AND_LIT(UTF8_NAME)); break; default: assertpro(FALSE /* Invalid error type */); } } }