tree gfc_build_wide_string_const (int kind, int length, const gfc_char_t *string) { int i; tree str, len; size_t size; char *s; i = gfc_validate_kind (BT_CHARACTER, kind, false); size = length * gfc_character_kinds[i].bit_size / 8; s = XCNEWVAR (char, size); gfc_encode_character (kind, length, string, (unsigned char *) s, size); str = build_string (size, s); free (s); len = size_int (length); TREE_TYPE (str) = build_array_type (gfc_get_char_type (kind), build_range_type (gfc_charlen_type_node, size_one_node, len)); TYPE_STRING_FLAG (TREE_TYPE (str)) = 1; return str; }
int gfc_encode_character (int kind, int length, const gfc_char_t *string, unsigned char *buffer, size_t buffer_size) { size_t elsize = size_character (1, kind); tree type = gfc_get_char_type (kind); int i; gcc_assert (buffer_size >= size_character (length, kind)); for (i = 0; i < length; i++) native_encode_expr (build_int_cst (type, string[i]), &buffer[i*elsize], elsize); return length; }
int gfc_interpret_character (unsigned char *buffer, size_t buffer_size, gfc_expr *result) { int i; if (result->ts.cl && result->ts.cl->length) result->value.character.length = (int) mpz_get_ui (result->ts.cl->length->value.integer); gcc_assert (buffer_size >= size_character (result->value.character.length, result->ts.kind)); result->value.character.string = gfc_get_wide_string (result->value.character.length + 1); if (result->ts.kind == gfc_default_character_kind) for (i = 0; i < result->value.character.length; i++) result->value.character.string[i] = (gfc_char_t) buffer[i]; else { mpz_t integer; unsigned bytes = size_character (1, result->ts.kind); mpz_init (integer); gcc_assert (bytes <= sizeof (unsigned long)); for (i = 0; i < result->value.character.length; i++) { gfc_conv_tree_to_mpz (integer, native_interpret_expr (gfc_get_char_type (result->ts.kind), &buffer[bytes*i], buffer_size-bytes*i)); result->value.character.string[i] = (gfc_char_t) mpz_get_ui (integer); } mpz_clear (integer); } result->value.character.string[result->value.character.length] = '\0'; return result->value.character.length; }