static engine_return_t engine_fixed_whole_line_match(error_t **error, void *data, const UString *subject) { FETCH_DATA(data, p, fixed_pattern_t); if (ustring_empty(p->pattern)) { return ustring_empty(subject) ? ENGINE_WHOLE_LINE_MATCH : ENGINE_NO_MATCH; } else if (NULL != p->usearch) { int32_t ret; UErrorCode status; status = U_ZERO_ERROR; usearch_setText(p->usearch, subject->ptr, subject->len, &status); if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "usearch_setText"); return ENGINE_FAILURE; } ret = usearch_first(p->usearch, &status); if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "usearch_first"); return ENGINE_FAILURE; } usearch_unbindText(p->usearch); return (ret != USEARCH_DONE && ((size_t) usearch_getMatchedLength(p->usearch)) == subject->len ? ENGINE_WHOLE_LINE_MATCH : ENGINE_NO_MATCH); } else { if (IS_CASE_INSENSITIVE(p->flags)) { return (0 == u_strcasecmp(p->pattern->ptr, subject->ptr, 0) ? ENGINE_WHOLE_LINE_MATCH : ENGINE_NO_MATCH); } else { return (0 == u_strcmp(p->pattern->ptr, subject->ptr) ? ENGINE_WHOLE_LINE_MATCH : ENGINE_NO_MATCH); } } }
static int print_insn_z8k (bfd_vma addr, disassemble_info *info, int is_segmented) { instr_data_s instr_data; info->private_data = (PTR) &instr_data; instr_data.max_fetched = 0; instr_data.insn_start = addr; if (setjmp (instr_data.bailout) != 0) /* Error return. */ return -1; info->bytes_per_chunk = 2; info->bytes_per_line = 6; info->display_endian = BFD_ENDIAN_BIG; instr_data.tabl_index = z8k_lookup_instr (instr_data.nibbles, info); if (instr_data.tabl_index >= 0) { unpack_instr (&instr_data, is_segmented, info); unparse_instr (&instr_data, is_segmented); output_instr (&instr_data, addr, info); return z8k_table[instr_data.tabl_index].length + seg_length; } else { FETCH_DATA (info, 4); (*info->fprintf_func) (info->stream, ".word %02x%02x", instr_data.bytes[0], instr_data.bytes[2]); return 2; } }
/** * Don't modify this function, it reproduces a part of fixed engine (engine_fixed_split) **/ static UBool engine_bin_split(error_t **error, void *data, const UString *subject, DArray *array, interval_list_t *intervals) { UErrorCode status; int32_t l, lastU; dlist_element_t *el; FETCH_DATA(data, p, bin_pattern_t); lastU = l = 0; status = U_ZERO_ERROR; CASE_FOLD_FORBIDDEN(error, p, FALSE); /* the only engine specific thing */ if (NULL != p->ubrk) { ubrk_setText(p->ubrk, subject->ptr, subject->len, &status); if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "ubrk_setText"); return FALSE; } } for (el = intervals->head; NULL != el; el = el->next) { FETCH_DATA(el->data, i, interval_t); if (i->lower_limit > 0) { if (!binary_fwd_n(p->ubrk, p->pattern, subject, NULL, i->lower_limit - lastU, &l)) { break; } } if (!binary_fwd_n(p->ubrk, p->pattern, subject, array, i->upper_limit - i->lower_limit, &l)) { break; } lastU = i->upper_limit; } ubrk_unbindText(p->ubrk); return TRUE; }
static engine_return_t engine_bin_whole_line_match(error_t **UNUSED(error), void *data, const UString *subject) { FETCH_DATA(data, p, bin_pattern_t); /* If search is case insensitive, we don't do case folding here, u_strcasecmp suffice (it does full case folding internally) */ if (ustring_empty(p->pattern)) { return ustring_empty(subject) ? ENGINE_WHOLE_LINE_MATCH : ENGINE_NO_MATCH; } else { if (IS_CASE_INSENSITIVE(p->flags)) { return (0 == u_strcasecmp(p->pattern->ptr, subject->ptr, 0) ? ENGINE_WHOLE_LINE_MATCH : ENGINE_NO_MATCH); } else { return (0 == u_strcmp(p->pattern->ptr, subject->ptr) ? ENGINE_WHOLE_LINE_MATCH : ENGINE_NO_MATCH); } } }
static void output_instr (instr_data_s *instr_data, unsigned long addr ATTRIBUTE_UNUSED, disassemble_info *info) { int num_bytes; char out_str[100]; out_str[0] = 0; num_bytes = (z8k_table[instr_data->tabl_index].length + seg_length) * 2; FETCH_DATA (info, num_bytes); strcat (out_str, instr_data->instr_asmsrc); (*info->fprintf_func) (info->stream, "%s", out_str); }
static void unpack_instr (instr_data_s *instr_data, int is_segmented, disassemble_info *info) { int nibl_count, loop; unsigned short instr_nibl, instr_byte, instr_word; long instr_long; unsigned int tabl_datum, datum_class; unsigned short datum_value; nibl_count = 0; loop = 0; seg_length = 0; while (z8k_table[instr_data->tabl_index].byte_info[loop] != 0) { FETCH_DATA (info, nibl_count + 4 - (nibl_count % 4)); instr_nibl = instr_data->nibbles[nibl_count]; instr_byte = instr_data->bytes[nibl_count & ~1]; instr_word = instr_data->words[nibl_count & ~3]; tabl_datum = z8k_table[instr_data->tabl_index].byte_info[loop]; datum_class = tabl_datum & CLASS_MASK; datum_value = tabl_datum & ~CLASS_MASK; switch (datum_class) { case CLASS_DISP: switch (datum_value) { case ARG_DISP16: instr_data->displacement = instr_data->insn_start + 4 + (signed short) (instr_word & 0xffff); nibl_count += 3; break; case ARG_DISP12: if (instr_word & 0x800) /* Negative 12 bit displacement. */ instr_data->displacement = instr_data->insn_start + 2 - (signed short) ((instr_word & 0xfff) | 0xf000) * 2; else instr_data->displacement = instr_data->insn_start + 2 - (instr_word & 0x0fff) * 2; nibl_count += 2; break; default: break; } break; case CLASS_IMM: switch (datum_value) { case ARG_IMM4: instr_data->immediate = instr_nibl; break; case ARG_NIM4: instr_data->immediate = (- instr_nibl) & 0xf; break; case ARG_NIM8: instr_data->immediate = (- instr_byte) & 0xff; nibl_count += 1; break; case ARG_IMM8: instr_data->immediate = instr_byte; nibl_count += 1; break; case ARG_IMM16: instr_data->immediate = instr_word; nibl_count += 3; break; case ARG_IMM32: FETCH_DATA (info, nibl_count + 8); instr_long = (instr_data->words[nibl_count] << 16) | (instr_data->words[nibl_count + 4]); instr_data->immediate = instr_long; nibl_count += 7; break; case ARG_IMMN: instr_data->immediate = instr_nibl - 1; break; case ARG_IMM4M1: instr_data->immediate = instr_nibl + 1; break; case ARG_IMM_1: instr_data->immediate = 1; break; case ARG_IMM_2: instr_data->immediate = 2; break; case ARG_IMM2: instr_data->immediate = instr_nibl & 0x3; break; default: break; } break; case CLASS_CC: instr_data->cond_code = instr_nibl; break; case CLASS_ADDRESS: if (is_segmented) { if (instr_nibl & 0x8) { FETCH_DATA (info, nibl_count + 8); instr_long = (instr_data->words[nibl_count] << 16) | (instr_data->words[nibl_count + 4]); instr_data->address = ((instr_word & 0x7f00) << 16) + (instr_long & 0xffff); nibl_count += 7; seg_length = 2; } else { instr_data->address = ((instr_word & 0x7f00) << 16) + (instr_word & 0x00ff); nibl_count += 3; } } else { instr_data->address = instr_word; nibl_count += 3; } break; case CLASS_0CCC: case CLASS_1CCC: instr_data->ctrl_code = instr_nibl & 0x7; break; case CLASS_0DISP7: instr_data->displacement = instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2; nibl_count += 1; break; case CLASS_1DISP7: instr_data->displacement = instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2; nibl_count += 1; break; case CLASS_01II: instr_data->interrupts = instr_nibl & 0x3; break; case CLASS_00II: instr_data->interrupts = instr_nibl & 0x3; break; case CLASS_IGNORE: case CLASS_BIT: instr_data->ctrl_code = instr_nibl & 0x7; break; case CLASS_FLAGS: instr_data->flags = instr_nibl; break; case CLASS_REG: instr_data->arg_reg[datum_value] = instr_nibl; break; case CLASS_REGN0: instr_data->arg_reg[datum_value] = instr_nibl; break; case CLASS_DISP8: instr_data->displacement = instr_data->insn_start + 2 + (signed char) instr_byte * 2; nibl_count += 1; break; case CLASS_BIT_1OR2: instr_data->immediate = ((instr_nibl >> 1) & 0x1) + 1; nibl_count += 1; break; default: abort (); break; } loop += 1; nibl_count += 1; } }
int z8k_lookup_instr (unsigned char *nibbles, disassemble_info *info) { int nibl_index, tabl_index; int nibl_matched; int need_fetch = 0; unsigned short instr_nibl; unsigned short tabl_datum, datum_class, datum_value; nibl_matched = 0; tabl_index = 0; FETCH_DATA (info, 4); while (!nibl_matched && z8k_table[tabl_index].name) { nibl_matched = 1; for (nibl_index = 0; nibl_index < z8k_table[tabl_index].length * 2 && nibl_matched; nibl_index++) { if ((nibl_index % 4) == 0) { /* Fetch data only if it isn't already there. */ if (nibl_index >= 4 || (nibl_index < 4 && need_fetch)) FETCH_DATA (info, nibl_index + 4); /* Fetch one word at a time. */ if (nibl_index < 4) need_fetch = 0; else need_fetch = 1; } instr_nibl = nibbles[nibl_index]; tabl_datum = z8k_table[tabl_index].byte_info[nibl_index]; datum_class = tabl_datum & CLASS_MASK; datum_value = ~CLASS_MASK & tabl_datum; switch (datum_class) { case CLASS_BIT: if (datum_value != instr_nibl) nibl_matched = 0; break; case CLASS_IGNORE: break; case CLASS_00II: if (!((~instr_nibl) & 0x4)) nibl_matched = 0; break; case CLASS_01II: if (!(instr_nibl & 0x4)) nibl_matched = 0; break; case CLASS_0CCC: if (!((~instr_nibl) & 0x8)) nibl_matched = 0; break; case CLASS_1CCC: if (!(instr_nibl & 0x8)) nibl_matched = 0; break; case CLASS_0DISP7: if (!((~instr_nibl) & 0x8)) nibl_matched = 0; nibl_index += 1; break; case CLASS_1DISP7: if (!(instr_nibl & 0x8)) nibl_matched = 0; nibl_index += 1; break; case CLASS_REGN0: if (instr_nibl == 0) nibl_matched = 0; break; case CLASS_BIT_1OR2: if ((instr_nibl | 0x2) != (datum_value | 0x2)) nibl_matched = 0; break; default: break; } } if (nibl_matched) return tabl_index; tabl_index++; } return -1; }
static engine_return_t engine_fixed_match(error_t **error, void *data, const UString *subject) { int32_t ret; UErrorCode status; FETCH_DATA(data, p, fixed_pattern_t); status = U_ZERO_ERROR; if (ustring_empty(p->pattern)) { if (IS_WORD_BOUNDED(p->flags)) { if (ustring_empty(subject)) { return ENGINE_MATCH_FOUND; } else { int32_t l, u, lastState, state; ubrk_setText(p->ubrk, subject->ptr, subject->len, &status); if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "ubrk_setText"); return ENGINE_FAILURE; } if (UBRK_DONE != (l = ubrk_first(p->ubrk))) { lastState = ubrk_getRuleStatus(p->ubrk); while (UBRK_DONE != (u = ubrk_next(p->ubrk))) { state = ubrk_getRuleStatus(p->ubrk); if (UBRK_WORD_NONE == lastState && lastState == state) { return ENGINE_MATCH_FOUND; } lastState = state; l = u; } } return ENGINE_NO_MATCH; } } else { return ENGINE_MATCH_FOUND; } } else if (NULL != p->usearch) { if (subject->len > 0) { usearch_setText(p->usearch, subject->ptr, subject->len, &status); if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "usearch_setText"); return ENGINE_FAILURE; } ret = usearch_first(p->usearch, &status); if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "usearch_first"); return ENGINE_FAILURE; } usearch_unbindText(p->usearch); return (ret != USEARCH_DONE ? ENGINE_MATCH_FOUND : ENGINE_NO_MATCH); } else { return ENGINE_NO_MATCH; } } else { UChar *m; int32_t pos; pos = 0; ret = ENGINE_NO_MATCH; if (NULL != p->ubrk) { ubrk_setText(p->ubrk, subject->ptr, subject->len, &status); if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "ubrk_setText"); return ENGINE_FAILURE; } } while (NULL != (m = u_strFindFirst(subject->ptr + pos, subject->len - pos, p->pattern->ptr, p->pattern->len))) { pos = m - subject->ptr; if (NULL == p->ubrk || (ubrk_isBoundary(p->ubrk, pos) && ubrk_isBoundary(p->ubrk, pos + p->pattern->len))) { ret = ENGINE_MATCH_FOUND; } pos += p->pattern->len; } ubrk_unbindText(p->ubrk); return ret; } }
static void engine_fixed_destroy(void *data) { FETCH_DATA(data, p, fixed_pattern_t); fixed_pattern_destroy(p); }
static UBool engine_fixed_split(error_t **error, void *data, const UString *subject, DArray *array, interval_list_t *intervals) { UErrorCode status; int32_t l, lastU; dlist_element_t *el; FETCH_DATA(data, p, fixed_pattern_t); lastU = l = 0; status = U_ZERO_ERROR; if (NULL != p->usearch) { usearch_setText(p->usearch, subject->ptr, subject->len, &status); if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "usearch_setText"); return FALSE; } /* <X> */ if (NULL == intervals) { int32_t u; while (U_SUCCESS(status) && USEARCH_DONE != (u = usearch_next(p->usearch, &status))) { add_match(array, subject, l, u); l = u += usearch_getMatchedLength(p->usearch); } add_match(array, subject, l, subject->len); } else { /* </X> */ for (el = intervals->head; NULL != el; el = el->next) { FETCH_DATA(el->data, i, interval_t); if (i->lower_limit > 0) { if (!usearch_fwd_n(p->usearch, subject, NULL, i->lower_limit - lastU, &l, &status)) { break; } } if (!usearch_fwd_n(p->usearch, subject, array, i->upper_limit - i->lower_limit, &l, &status)) { break; } lastU = i->upper_limit; } /* <X> */ } /* </X> */ usearch_unbindText(p->usearch); if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "usearch_next"); return FALSE; } } else { if (NULL != p->ubrk) { ubrk_setText(p->ubrk, subject->ptr, subject->len, &status); if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "ubrk_setText"); return FALSE; } } /* <X> */ if (NULL == intervals) { UChar *m; int32_t u; u = 0; while (NULL != (m = u_strFindFirst(subject->ptr + u, subject->len - u, p->pattern->ptr, p->pattern->len))) { u = m - subject->ptr; if (NULL == p->ubrk || (ubrk_isBoundary(p->ubrk, u) && ubrk_isBoundary(p->ubrk, u + p->pattern->len))) { add_match(array, subject, l, u); } l = u = u + p->pattern->len; } add_match(array, subject, l, subject->len); } else { /* </X> */ for (el = intervals->head; NULL != el; el = el->next) { FETCH_DATA(el->data, i, interval_t); if (i->lower_limit > 0) { if (!binary_fwd_n(p->ubrk, p->pattern, subject, NULL, i->lower_limit - lastU, &l)) { break; } } if (!binary_fwd_n(p->ubrk, p->pattern, subject, array, i->upper_limit - i->lower_limit, &l)) { break; } lastU = i->upper_limit; } /* <X> */ } /* </X> */ ubrk_unbindText(p->ubrk); } return TRUE; }
static engine_return_t engine_fixed_match_all(error_t **error, void *data, const UString *subject, interval_list_t *intervals) { int32_t matches; UErrorCode status; FETCH_DATA(data, p, fixed_pattern_t); matches = 0; status = U_ZERO_ERROR; if (ustring_empty(p->pattern)) { if (IS_WORD_BOUNDED(p->flags)) { if (ustring_empty(subject)) { return ENGINE_MATCH_FOUND; } else { int32_t l, u, lastState, state; ubrk_setText(p->ubrk, subject->ptr, subject->len, &status); if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "ubrk_setText"); return ENGINE_FAILURE; } if (UBRK_DONE != (l = ubrk_first(p->ubrk))) { lastState = ubrk_getRuleStatus(p->ubrk); while (UBRK_DONE != (u = ubrk_next(p->ubrk))) { state = ubrk_getRuleStatus(p->ubrk); if (UBRK_WORD_NONE == lastState && lastState == state) { return ENGINE_MATCH_FOUND; } lastState = state; l = u; } } return ENGINE_NO_MATCH; } } else { return ENGINE_MATCH_FOUND; } } else if (NULL != p->usearch) { int32_t l, u; if (subject->len > 0) { usearch_setText(p->usearch, subject->ptr, subject->len, &status); if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "usearch_setText"); return ENGINE_FAILURE; } for (l = usearch_first(p->usearch, &status); U_SUCCESS(status) && USEARCH_DONE != l; l = usearch_next(p->usearch, &status)) { matches++; u = l + usearch_getMatchedLength(p->usearch); if (interval_list_add(intervals, subject->len, l, u)) { return ENGINE_WHOLE_LINE_MATCH; } } if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "usearch_[first|next]"); return ENGINE_FAILURE; } usearch_unbindText(p->usearch); return (matches ? ENGINE_MATCH_FOUND : ENGINE_NO_MATCH); } else { return ENGINE_NO_MATCH; } } else { UChar *m; int32_t pos; pos = 0; if (NULL != p->ubrk) { ubrk_setText(p->ubrk, subject->ptr, subject->len, &status); if (U_FAILURE(status)) { icu_error_set(error, FATAL, status, "ubrk_setText"); return ENGINE_FAILURE; } } while (NULL != (m = u_strFindFirst(subject->ptr + pos, subject->len - pos, p->pattern->ptr, p->pattern->len))) { pos = m - subject->ptr; if (NULL == p->ubrk || (ubrk_isBoundary(p->ubrk, pos) && ubrk_isBoundary(p->ubrk, pos + p->pattern->len))) { matches++; if (interval_list_add(intervals, subject->len, pos, pos + p->pattern->len)) { return ENGINE_WHOLE_LINE_MATCH; } } pos += p->pattern->len; } ubrk_unbindText(p->ubrk); return (matches ? ENGINE_MATCH_FOUND : ENGINE_NO_MATCH); } }
static void engine_bin_destroy(void *data) { FETCH_DATA(data, p, bin_pattern_t); bin_pattern_destroy(p); }