From: Justin Seyster Date: Fri, 3 Sep 2010 22:24:21 +0000 (-0400) Subject: Rewrote format_c_type() to deal with all aop_type objects. X-Git-Tag: release-v1.0~48^2~10 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=17306a26619cfa4d8a652bc0dc2c96943fde2d46;p=interaspect.git Rewrote format_c_type() to deal with all aop_type objects. --- diff --git a/src/aop-type.c b/src/aop-type.c index acf30aa..fb42c6c 100644 --- a/src/aop-type.c +++ b/src/aop-type.c @@ -792,11 +792,24 @@ are_types_equal (const struct aop_type *a, const struct aop_type *b) return (a == b); } +/* Quick-and-dirty printf variant that will output to a buffer without + overrunning it. */ +#define BUF_PRINTF(format, ...) \ + do { \ + int bytes; \ + bytes = snprintf (out, size, format, __VA_ARGS__); \ + out += bytes; \ + total_bytes += bytes; \ + size -= bytes; \ + } while (0) + /* C names for special aop_type objects. */ static const char *all_signed_name = "ALL_SIGNED_T"; static const char *all_unsigned_name = "ALL_UNSIGNED_T"; static const char *all_fp_name = "ALL_FP_T"; static const char *all_pointer_name = "ALL_POINTER_T"; +static const char *signed_char_name = "signed char"; +static const char *unsigned_char_name = "unsigned char"; /* Format an aop_type as a C/C++ typename. The result is stored in the output buffer (n is the size of the buffer). Returns the @@ -805,37 +818,94 @@ static const char *all_pointer_name = "ALL_POINTER_T"; int format_c_type (const struct aop_type *type, int n, char *output) { - int size; + /* Initialize these for the sake of BUF_PRINTF. */ + int total_bytes = 0; + int size = n; + char *out = output; - if (type->kind == ATK_ALL_POINTER) - { - size = snprintf (output, n, "%s", all_pointer_name); - } - else if (is_all_integer_type (type)) + switch (type->kind) { - if (type->kind == ATK_SIGNED_INT) - size = snprintf (output, n, "%s", all_signed_name); - else if (type->kind == ATK_UNSIGNED_INT) - size = snprintf (output, n, "%s", all_unsigned_name); + case ATK_SIGNED_INT: + case ATK_UNSIGNED_INT: + if (type->size == 0) + { + BUF_PRINTF ("%s", (type->kind == ATK_SIGNED_INT) ? all_signed_name + : all_unsigned_name); + } + else if (type->size == 1) + { + /* We special case one byte integers because it looks really + awkward to see (int8_t *) when you wanted a (char *). + + It's ok to do this because the standard guarantees that + char == 1 byte. */ + BUF_PRINTF ("%s", (type->kind == ATK_SIGNED_INT) ? signed_char_name + : unsigned_char_name); + } else - aop_assert (0); /* Should never happen. */ - } - else if (is_all_fp_type (type)) - { - size = snprintf (output, n, "%s", all_fp_name); + { + aop_assert (type->size == 2 || type->size == 4 || type->size == 8 + || type->size == 16); + + BUF_PRINTF ("%s%d_t", (type->kind == ATK_SIGNED_INT) ? "int" : "uint", + 8 * type->size); + } + break; + case ATK_FP: + switch (type->size) + { + case 4: + BUF_PRINTF ("%s", "float"); + break; + case 8: + BUF_PRINTF ("%s", "double"); + break; + case 16: + BUF_PRINTF ("%s", "long double"); + break; + case 0: + BUF_PRINTF ("%s", all_fp_name); + break; + default: + /* Invalid size for floating point type. */ + aop_assert (0); + } + break; + case ATK_ALL_POINTER: + BUF_PRINTF ("%s", all_pointer_name); + break; + case ATK_STRUCT: + BUF_PRINTF ("struct %s", type->tag); + break; + case ATK_UNION: + BUF_PRINTF ("union %s", type->tag); + break; + case ATK_ENUM: + BUF_PRINTF ("enum %s", type->tag); + break; + default: + /* Unknown type kind. */ + aop_assert (0); } - else + + if (type->pointer_levels > 0) { - aop_assert (0); /* Not yet supported. */ + int i; + + /* What can I say? It's the C convention. */ + BUF_PRINTF("%s", " "); + + for (i = 0; i < type->pointer_levels; i++) + BUF_PRINTF("%s", "*"); } /* Before returning, make absolutely sure that the result is NULL-terminated. Note that snprintf will not terminate a string that it has to truncate because of too small buffer. */ - if (size < n) - output[size] = '\0'; + if (total_bytes < n) + output[total_bytes] = '\0'; else output[n - 1] = '\0'; - return size; + return total_bytes; }