void show_source_line(char* buf, boolean_t warn) { char *b, *c, *c_top; int chlen, chwidth; unsigned int ch; error_def(ERR_SRCLIN); error_def(ERR_SRCLOC); for (c = (char *)source_buffer, b = buf, c_top = c + last_source_column - 1; c < c_top; ) { if (*c == '\t') *b++ = *c++; else if (!gtm_utf8_mode || *(uchar_ptr_t)c <= ASCII_MAX) { *b++ = ' '; c++; } #ifdef UNICODE_SUPPORTED else { chlen = (int)(UTF8_MBTOWC(c, c_top, ch) - (uchar_ptr_t)c); if (WEOF != ch && 0 < (chwidth = UTF8_WCWIDTH(ch))) { memset(b, ' ', chwidth); b += chwidth; } c += chlen; } #endif } memcpy(b, ARROW, STR_LIT_LEN(ARROW)); b += STR_LIT_LEN(ARROW); *b = '\0'; if (warn) { dec_nofac = TRUE; dec_err(VARLSTCNT (6) ERR_SRCLIN, 4, LEN_AND_STR((char *)source_buffer), b - buf, buf); if (!run_time) dec_err(VARLSTCNT(6) ERR_SRCLOC, 4, last_source_column, source_line, source_name_len, source_file_name); dec_nofac = FALSE; } }
/* Returns the total display column width of a UTF-8 string given its address and byte length. * The third parameter (strict) is used to specify how both illegal characters should be handled. * The fourth parameter (nonprintwidth) is to specify what width to give for unprintable characters. * It is currently 0 if coming through $ZWIDTH and 1 if coming through util_output (for historical reasons). * If strict is TRUE, this routine * - triggers BADCHAR error if it encounters any illegal characters irrespective of VIEW BADCHAR setting. * If strict is FALSE, this routine * - does NOT do BADCHAR check. * - treats illegal characters as unprintable characters (for width). */ int gtm_wcswidth(unsigned char* ptr, int len, boolean_t strict, int nonprintwidth) { int strwidth, cwidth; uint4 ch; unsigned char *ptrtop, *ptrnext; assert(gtm_utf8_mode); ptrtop = ptr + len; for (strwidth = 0; ptr < ptrtop; ptr = ptrnext) { ptrnext = UTF8_MBTOWC(ptr, ptrtop, ch); if (WEOF != ch && -1 != (cwidth = UTF8_WCWIDTH(ch))) strwidth += cwidth; else if (strict && (WEOF == ch)) UTF8_BADCHAR(0, ptr, ptrtop, 0, NULL); else strwidth += nonprintwidth; } assert(ptr == ptrtop); return strwidth; }
void show_source_line(boolean_t warn) { char *b, *b_top, *c, *c_top, *buf; char source_line_buff[MAX_SRCLINE + SIZEOF(ARROW)]; ssize_t buflen; int chlen, chwidth; unsigned int ch, line_chwidth = 0; boolean_t unable_to_complete_arrow = FALSE; mstr msgstr; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; buf = source_line_buff; buflen = SIZEOF(source_line_buff); b_top = buf + buflen - STR_LIT_LEN(ARROW) - 1; /* allow room for arrow and string terminator */ for (c = (char *)source_buffer, b = buf, c_top = c + TREF(last_source_column) - 1; c < c_top;) { if ('\t' == *c) { if ((b + 1) > b_top) { unable_to_complete_arrow = TRUE; break; } *b++ = *c++; } else if (!gtm_utf8_mode || (ASCII_MAX >= *(uchar_ptr_t)c)) { if ((b + 1) > b_top) { unable_to_complete_arrow = TRUE; break; } *b++ = ' '; c++; } # ifdef UNICODE_SUPPORTED else { chlen = (int)(UTF8_MBTOWC(c, c_top, ch) - (uchar_ptr_t)c); if (WEOF != ch && (0 < (chwidth = UTF8_WCWIDTH(ch)))) /* assignment */ { if ((b + chwidth) > b_top) { unable_to_complete_arrow = TRUE; break; } memset(b, ' ', chwidth); b += chwidth; } c += chlen; } # endif } if (unable_to_complete_arrow) { msgstr.addr = buf; msgstr.len = buflen; dec_nofac = TRUE; gtm_getmsg(ERR_ARROWNTDSP, &msgstr); dec_nofac = FALSE; } else { memcpy(b, ARROW, STR_LIT_LEN(ARROW)); b += STR_LIT_LEN(ARROW); *b = '\0'; } if (warn) { for (c = (char *)source_buffer; c < (char *)source_buffer + STRLEN((char *)source_buffer) - 1; ) { if ('\t' == *c) { line_chwidth++; c++; } else if (!gtm_utf8_mode || (ASCII_MAX >= *(uchar_ptr_t)c)) { line_chwidth++; c++; } else { # ifdef UNICODE_SUPPORTED /* funky positioning makes VMS compiler happy */ chlen = (int)(UTF8_MBTOWC(c, (char *)source_buffer + STRLEN((char *)source_buffer) - 1, ch) - (uchar_ptr_t)c); if ((WEOF != ch) && 0 < (chwidth = UTF8_WCWIDTH(ch))) line_chwidth += chwidth; c += chlen; # endif } } dec_nofac = TRUE; if (MAXLINESIZEFORDISPLAY > line_chwidth) if (unable_to_complete_arrow) dec_err(VARLSTCNT(6) ERR_SRCLIN, 4, LEN_AND_STR((char *)source_buffer), msgstr.len, msgstr.addr); else dec_err(VARLSTCNT(6) ERR_SRCLIN, 4, LEN_AND_STR((char *)source_buffer), b - buf, buf); else dec_err(VARLSTCNT(2) ERR_SRCLNNTDSP, 1, MAXLINESIZEFORDISPLAY); if (!run_time) dec_err(VARLSTCNT(6) ERR_SRCLOC, 4, TREF(last_source_column), source_line, source_name_len, source_file_name); dec_nofac = FALSE; } }
sm_uc_ptr_t dump_record(sm_uc_ptr_t rp, block_id blk, sm_uc_ptr_t bp, sm_uc_ptr_t b_top) { sm_uc_ptr_t r_top, key_top, cptr0, cptr1, cptr_top, cptr_base = NULL, cptr_next = NULL; char key_buf[MAX_KEY_SZ + 1], *temp_ptr, *temp_key, util_buff[MAX_UTIL_LEN]; char *prefix_str, *space_str, *dot_str, *format_str; unsigned char cc; short int size; int4 util_len, head; uint4 ch; int buf_len, field_width,fastate, chwidth = 0; ssize_t chlen; block_id blk_id; boolean_t rechdr_displayed = FALSE; sgmnt_addrs *csa; if (rp >= b_top) return NULL; head = cli_present("HEADER"); GET_SHORT(size, &((rec_hdr_ptr_t)rp)->rsiz); cc = ((rec_hdr_ptr_t)rp)->cmpc; if ((CLI_NEGATED != head) && !patch_is_fdmp) { MEMCPY_LIT(util_buff, "Rec:"); util_len = SIZEOF("Rec:") - 1; util_len += i2hex_nofill(patch_rec_counter, (uchar_ptr_t)&util_buff[util_len], 4); MEMCPY_LIT(&util_buff[util_len], " Blk "); util_len += SIZEOF(" Blk ") - 1; util_len += i2hex_nofill(blk, (uchar_ptr_t)&util_buff[util_len], 8); MEMCPY_LIT(&util_buff[util_len], " Off "); util_len += SIZEOF(" Off ") - 1; util_len += i2hex_nofill((int)(rp - bp), (uchar_ptr_t)&util_buff[util_len], 4); MEMCPY_LIT(&util_buff[util_len], " Size "); util_len += SIZEOF(" Size ") - 1; util_len += i2hex_nofill(size, (uchar_ptr_t)&util_buff[util_len], 4); MEMCPY_LIT(&util_buff[util_len], " Cmpc "); util_len += SIZEOF(" Cmpc ") - 1; util_len += i2hex_nofill(cc, (uchar_ptr_t)&util_buff[util_len], 2); MEMCPY_LIT(&util_buff[util_len], " "); util_len += SIZEOF(" ") - 1; util_buff[util_len] = 0; util_out_print(util_buff, FALSE); } r_top = rp + size; if (r_top > b_top) r_top = b_top; else if (r_top < rp + SIZEOF(rec_hdr)) r_top = rp + SIZEOF(rec_hdr); if (cc > patch_comp_count) cc = patch_comp_count; if (((blk_hdr_ptr_t)bp)->levl) key_top = r_top - SIZEOF(block_id); else { for (key_top = rp + SIZEOF(rec_hdr); key_top < r_top;) if (!*key_top++ && !*key_top++) break; } size = key_top - rp - SIZEOF(rec_hdr); if (size > SIZEOF(patch_comp_key) - 2 - cc) size = SIZEOF(patch_comp_key) - 2 - cc; if (size < 0) size = 0; memcpy(&patch_comp_key[cc], rp + SIZEOF(rec_hdr), size); patch_comp_count = cc + size; patch_comp_key[patch_comp_count] = patch_comp_key[patch_comp_count + 1] = 0; if (patch_is_fdmp) { if (dse_fdmp(key_top, (int)(r_top - key_top))) patch_fdmp_recs++; } else { if (r_top - SIZEOF(block_id) >= key_top) { GET_LONG(blk_id, key_top); if ((((blk_hdr_ptr_t)bp)->levl) || (blk_id <= cs_addrs->ti->total_blks)) { MEMCPY_LIT(util_buff, "Ptr "); util_len = SIZEOF("Ptr ") - 1; util_len += i2hex_nofill(blk_id, (uchar_ptr_t)&util_buff[util_len], SIZEOF(blk_id) * 2); MEMCPY_LIT(&util_buff[util_len], " "); util_len += SIZEOF(" ") - 1; util_buff[util_len] = 0; util_out_print(util_buff, FALSE); } } util_out_print("Key ", FALSE); if (r_top == b_top && ((blk_hdr_ptr_t)bp)->levl && !((rec_hdr_ptr_t)rp)->cmpc && r_top - rp == SIZEOF(rec_hdr) + SIZEOF(block_id)) util_out_print("*", FALSE); else if (patch_comp_key[0]) { util_out_print("^", FALSE); csa = cs_addrs; RETRIEVE_ROOT_VAL(patch_comp_key, key_buf, temp_ptr, temp_key, buf_len); INIT_ROOT_GVT(key_buf, buf_len, curr_gbl_root); } print_target((uchar_ptr_t)patch_comp_key); util_out_print(0, TRUE); if (CLI_PRESENT != head) { prefix_str = " |"; if (wide_out) { format_str = " !AD"; dot_str = " ."; space_str = " "; field_width = 4; } else { format_str = " !AD"; dot_str = " ."; space_str = " "; field_width = 3; } fastate = 0; for (cptr0 = rp; cptr0 < r_top; cptr0 += NUM_BYTES_PER_LINE) { if (util_interrupt) { /* return, rather than signal ERR_CTRLC so that the calling routine can deal with that signal and do the appropriate cleanup */ return NULL; } util_len = 8; i2hex_blkfill((int)(cptr0 - bp), (uchar_ptr_t)util_buff, 8); MEMCPY_LIT(&util_buff[util_len], " : |"); util_len += SIZEOF(" : |") - 1; util_buff[util_len] = 0; util_out_print(util_buff, FALSE); /* Dump hexadecimal byte values */ for (cptr1 = cptr0; cptr1 < (cptr0 + NUM_BYTES_PER_LINE); cptr1++) { if (cptr1 < r_top) { i2hex_blkfill(*(sm_uc_ptr_t)cptr1, (uchar_ptr_t)util_buff, field_width); util_buff[field_width] = 0; util_out_print(util_buff, FALSE); } else util_out_print(space_str, FALSE); } util_out_print("|", TRUE); util_out_print(prefix_str, FALSE); /* Display character/wide-character glyphs */ for (cptr1 = cptr0, cptr_top = cptr0 + NUM_BYTES_PER_LINE; cptr1 < cptr_top; cptr1++) { if (!rechdr_displayed && (cptr1 == (rp + SIZEOF(rec_hdr)))) rechdr_displayed = TRUE; assert(rechdr_displayed || (cptr1 < (rp + SIZEOF(rec_hdr)))); assert(!rechdr_displayed || (cptr1 >= (rp + SIZEOF(rec_hdr)))); switch (fastate) { case 0: /* prints single-byte characters or intepret multi-byte characters */ if (cptr1 >= r_top) util_out_print(space_str, FALSE); else if (!gtm_utf8_mode || IS_ASCII(*cptr1) || !rechdr_displayed) { /* single-byte characters */ if (PRINTABLE(*(sm_uc_ptr_t)cptr1)) util_out_print(format_str, FALSE, 1, cptr1); else util_out_print(dot_str, FALSE); } #ifdef UNICODE_SUPPORTED else { /* multi-byte characters */ cptr_next = UTF8_MBTOWC(cptr1, r_top, ch); chlen = cptr_next - cptr1; if (WEOF == ch || !U_ISPRINT(ch)) { /* illegal or non-printable characters */ cptr1--; fastate = 1; } else { /* multi-byte printable characters */ cptr_base = cptr1; chwidth = UTF8_WCWIDTH(ch); assert(chwidth >= 0 && chwidth <= 2); cptr1--; fastate = 2; } } #endif break; case 1: /* illegal or non-printable characters */ util_out_print(dot_str, FALSE); if (--chlen <= 0) fastate = 0; break; case 2: /* printable multi-byte characters */ if (chlen-- > 1) /* fill leading bytes with spaces */ util_out_print(space_str, FALSE); else { util_out_print("!AD", FALSE, field_width - chwidth, space_str); if (0 < chwidth) util_out_print("!AD", FALSE, cptr_next - cptr_base, cptr_base); fastate = 0; } break; } } util_out_print("|", TRUE); } } if (CLI_NEGATED != head) util_out_print(0, TRUE); } return (r_top == b_top) ? NULL : r_top; }