/* * Show a '%p' thing. A kernel extension is that the '%p' is followed * by an extra set of alphanumeric characters that are extended format * specifiers. * * Right now we handle: * * - 'I' [4] for IPv4 addresses printed in the usual way * IPv4 uses dot-separated decimal without leading 0's (1.2.3.4) * - 'S' For symbolic direct pointers * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form * "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" * Options for %pU are: * b big endian lower case hex (default) * B big endian UPPER case hex * l little endian lower case hex * L little endian UPPER case hex * big endian output byte order is: * [0][1][2][3]-[4][5]-[6][7]-[8][9]-[10][11][12][13][14][15] * little endian output byte order is: * [3][2][1][0]-[5][4]-[7][6]-[8][9]-[10][11][12][13][14][15] * - 'a[pd]' For address types [p] phys_addr_t, [d] dma_addr_t and derivatives * (default assumed to be phys_addr_t, passed by reference) * * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 * function pointers are really function descriptors, which contain a * pointer to the real address. */ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags) { switch (*fmt) { case 'S': return symbol_string(buf, end, ptr, field_width, precision, flags); case 'U': if (IS_ENABLED(CONFIG_PRINTF_UUID)) return uuid_string(buf, end, ptr, field_width, precision, flags, fmt); break; case 'a': return address_val(buf, end, ptr, field_width, precision, flags, fmt); case 'I': switch (fmt[1]) { case '4': return ip4_addr_string(buf, end, ptr, field_width, precision, flags, fmt); } break; } flags |= SMALL; if (field_width == -1) { field_width = 2*sizeof(void *); flags |= ZEROPAD; } return number(buf, end, (unsigned long) ptr, 16, field_width, precision, flags); }
object symbol(char *str, unsigned long len) { unsigned long bucket; object el, o; char *symstr; unsigned long symlen; bucket = symbol_string_hash(str, len) % symbol_table.nbuckets; el = symbol_table.buckets[bucket]; while (!is_null(el)) { o = symbol_string(car(el)); symstr = string_value(o); symlen = string_length(o); if ((len == symlen) && (memcmp(symstr, str, len) == 0)) return car(el); el = cdr(el); } /* not there, intern now */ o = make_string_buffer(str, len); el = make_symbol_with_string(o); symbol_table.buckets[bucket] = cons(el, symbol_table.buckets[bucket]); return el; }
/* * Show a '%p' thing. A kernel extension is that the '%p' is followed * by an extra set of alphanumeric characters that are extended format * specifiers. * * Right now we handle: * * - 'S' For symbolic direct pointers * * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 * function pointers are really function descriptors, which contain a * pointer to the real address. */ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags) { switch (*fmt) { case 'S': return symbol_string(buf, end, ptr, field_width, precision, flags); } flags |= SMALL; if (field_width == -1) { field_width = 2*sizeof(void *); flags |= ZEROPAD; } return number(buf, end, (unsigned long) ptr, 16, field_width, precision, flags); }
void lisp_print(object exp, FILE *out) { unsigned long i, len; char c; char *str; object *vptr; switch (type_of(exp)) { case T_NIL: fprintf(out, "()"); break; case T_FIXNUM: fprintf(out, "%ld", fixnum_value(exp)); break; case T_CHARACTER: c = character_value(exp); fprintf(out, "#\\"); switch (c) { case '\n': fprintf(out, "newline"); break; case ' ': fprintf(out, "space"); break; default: fprintf(out, "%c", c); } break; case T_PAIR: if (is_finite_list(exp, NULL)) { fprintf(out, "("); write_pair(exp, out); fprintf(out, ")"); } else { fprintf(out, "#<unprintable-structure>"); } break; case T_BOOLEAN: fprintf(out, is_false(exp) ? "#f" : "#t"); break; case T_STRING: fprintf(out, "\""); str = string_value(exp); len = string_length(exp); for (i = 0; i < len; i++) { switch (str[i]) { case '\n': fprintf(out, "\\n"); break; case '"': fprintf(out, "\\\""); break; case '\\': fprintf(out, "\\\\"); break; default: fprintf(out, "%c", str[i]); } } fprintf(out, "\""); break; case T_VECTOR: fprintf(out, "#("); len = vector_length(exp); vptr = vector_ptr(exp); for (i = 0; i < len; i++) { if (i) fputc(' ', out); lisp_print(*vptr++, out); } fprintf(out, ")"); break; case T_SYMBOL: fprintf(out, "%.*s", (int) string_length(symbol_string(exp)), string_value(symbol_string(exp))); break; case T_FOREIGN_PTR: fprintf(out, "#<foreign-pointer %p>", foreign_ptr_value(exp)); break; case T_PRIMITIVE: fprintf(out, "#<primitive-procedure %p>", primitive_implementation(exp)); break; case T_PROCEDURE: fprintf(out, "#<procedure "); lisp_print(procedure_parameters(exp), out); fprintf(out, ">"); break; case T_EOF: fprintf(out, "#<eof>"); break; case T_PORT: fprintf(out, "#<%s-port %p>", is_input_port(exp) ? "input" : "output", port_implementation(exp)); break; case T_UNSPECIFIED: /* actually, I could read this back... */ fprintf(out, "#<unspecified>"); break; case T_MACRO: fprintf(out, "#<macro "); lisp_print(macro_parameters(exp), out); fprintf(out, ">"); break; case T_MAX_TYPE: break; } }