print.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /* $Header$ */
  2. #include <alloc.h>
  3. #include <assert.h>
  4. #include <stdio.h>
  5. #include "type.h"
  6. #include "message.h"
  7. #include "langdep.h"
  8. #include "scope.h"
  9. #include "symbol.h"
  10. #include "position.h"
  11. #include "idf.h"
  12. #include "expr.h"
  13. extern FILE *db_out;
  14. extern long float_size, pointer_size, int_size;
  15. extern char *strindex();
  16. static
  17. print_unsigned(tp, v, format)
  18. p_type tp;
  19. long v;
  20. register char *format;
  21. {
  22. while (format && *format) {
  23. if (strindex("cdohx", *format)) break;
  24. format++;
  25. }
  26. switch(format == 0 ? 0 : *format) {
  27. default:
  28. if (tp != uchar_type) {
  29. fprintf(db_out, currlang->uns_fmt, v);
  30. break;
  31. }
  32. /* fall through */
  33. case 'c':
  34. (*currlang->printchar)((int) v);
  35. break;
  36. case 'd':
  37. fprintf(db_out, currlang->decint_fmt, v);
  38. break;
  39. case 'o':
  40. fprintf(db_out, currlang->octint_fmt, v);
  41. break;
  42. case 'x':
  43. case 'h':
  44. fprintf(db_out, currlang->hexint_fmt, v);
  45. break;
  46. }
  47. }
  48. static
  49. print_literal(tp, v, compressed, format)
  50. p_type tp;
  51. long v;
  52. int compressed;
  53. char *format;
  54. {
  55. register struct literal *lit = tp->ty_literals;
  56. register int i;
  57. if (format) {
  58. print_unsigned(tp, v, format);
  59. return;
  60. }
  61. for (i = tp->ty_nenums; i; i--, lit++) {
  62. if (lit->lit_val == v) {
  63. fputs(lit->lit_name, db_out);
  64. break;
  65. }
  66. }
  67. if (! i) {
  68. fprintf(db_out,
  69. compressed ? "?%ld?" : "unknown enumeration value %ld",
  70. v);
  71. }
  72. }
  73. static
  74. print_integer(tp, v, format)
  75. p_type tp;
  76. long v;
  77. register char *format;
  78. {
  79. while (format && *format) {
  80. if (strindex("cdohx", *format)) break;
  81. format++;
  82. }
  83. switch(format == 0 ? 0 : *format) {
  84. default:
  85. if (tp != char_type) {
  86. fprintf(db_out, currlang->decint_fmt, v);
  87. break;
  88. }
  89. /* fall through */
  90. case 'c':
  91. (*currlang->printchar)((int) v);
  92. break;
  93. case 'd':
  94. fprintf(db_out, currlang->decint_fmt, v);
  95. break;
  96. case 'o':
  97. fprintf(db_out, currlang->octint_fmt, v);
  98. break;
  99. case 'x':
  100. case 'h':
  101. fprintf(db_out, currlang->hexint_fmt, v);
  102. break;
  103. }
  104. }
  105. print_params(tp, AB, static_link)
  106. p_type tp;
  107. t_addr AB;
  108. {
  109. char *param_bytes;
  110. register char *p;
  111. register int i;
  112. register struct param *par;
  113. long size;
  114. if (! tp) return;
  115. assert(tp->ty_class == T_PROCEDURE);
  116. if ((i = tp->ty_nparams) == 0) return;
  117. /* get parameter bytes */
  118. par = tp->ty_params;
  119. size = tp->ty_nbparams;
  120. if (static_link) size += pointer_size;
  121. param_bytes = p = malloc((unsigned)size);
  122. if (! p) {
  123. error("could not allocate enough memory");
  124. return;
  125. }
  126. if (static_link) p += pointer_size;
  127. if (! get_bytes(size, AB, param_bytes)) {
  128. free(param_bytes);
  129. return;
  130. }
  131. while (i--) {
  132. if (par->par_kind == 'v' || par->par_kind == 'i') {
  133. /* call by reference parameter, or
  134. call by value parameter, but address is passed;
  135. try and get value.
  136. */
  137. char *q;
  138. t_addr addr = get_int(p, pointer_size, T_UNSIGNED);
  139. if ((size = par->par_type->ty_size) == 0) {
  140. size = compute_size(par->par_type, param_bytes);
  141. }
  142. q = malloc((unsigned) size);
  143. if (! q) {
  144. error("could not allocate enough memory");
  145. free(param_bytes);
  146. return;
  147. }
  148. if (! get_bytes(size, addr, q)) {
  149. fprintf(db_out, currlang->addr_fmt, (long) addr);
  150. }
  151. else {
  152. print_val(par->par_type, size, q, 1, 0, (char *)0);
  153. }
  154. free(q);
  155. }
  156. else print_val(par->par_type, par->par_type->ty_size, p, 1, 0, (char *)0);
  157. if (i) fputs(", ", db_out);
  158. p += param_size(par->par_type, par->par_kind);
  159. par++;
  160. }
  161. free(param_bytes);
  162. }
  163. print_val(tp, tp_sz, addr, compressed, indent, format)
  164. p_type tp; /* type of value to be printed */
  165. long tp_sz; /* size of object to be printed */
  166. char *addr; /* address to get value from */
  167. int compressed; /* for parameter lists */
  168. int indent; /* indentation */
  169. register char *format; /* format given or 0 */
  170. {
  171. register int i;
  172. long elsize;
  173. if (indent == 0) indent = 4;
  174. switch(tp->ty_class) {
  175. case T_CROSS:
  176. if (! tp->ty_cross) {
  177. error("unknown type");
  178. break;
  179. }
  180. print_val(tp->ty_cross, tp_sz, addr, compressed, indent, format);
  181. break;
  182. case T_SUBRANGE:
  183. print_val(tp->ty_base, tp_sz, addr, compressed, indent, format);
  184. break;
  185. case T_ARRAY:
  186. if ((!format || strindex(format, 'a') == 0) &&
  187. (tp->ty_elements == char_type ||
  188. tp->ty_elements == uchar_type)) {
  189. print_val(string_type, tp_sz, addr, compressed, indent, format);
  190. break;
  191. }
  192. if (compressed) {
  193. fprintf(db_out, currlang->open_array_display);
  194. }
  195. else {
  196. fprintf(db_out, "\n%*c%s%*c",
  197. indent,
  198. ' ',
  199. currlang->open_array_display,
  200. 4-strlen(currlang->open_array_display), ' ');
  201. }
  202. indent += 4;
  203. elsize = (*currlang->arrayelsize)(tp->ty_elements->ty_size);
  204. for (i = tp_sz/elsize; i; i--) {
  205. print_val(tp->ty_elements, tp->ty_elements->ty_size, addr, compressed, indent, format);
  206. addr += elsize;
  207. if (compressed && i > 1) {
  208. fprintf(db_out, ", ...");
  209. break;
  210. }
  211. if (i > 1) {
  212. putc(',', db_out);
  213. }
  214. fprintf(db_out, "\n%*c", i > 1 ? indent : indent - 4, ' ');
  215. }
  216. fprintf(db_out, currlang->close_array_display);
  217. indent -= 4;
  218. break;
  219. case T_STRUCT: {
  220. register struct fields *fld = tp->ty_fields;
  221. if (compressed) {
  222. fprintf(db_out, currlang->open_struct_display);
  223. }
  224. else {
  225. fprintf(db_out, "\n%*c%s%*c",
  226. indent,
  227. ' ',
  228. currlang->open_struct_display,
  229. 4-strlen(currlang->open_struct_display), ' ');
  230. }
  231. indent += 4;
  232. for (i = tp->ty_nfields; i; i--, fld++) {
  233. long sz = fld->fld_type->ty_size;
  234. if (! compressed) fprintf(db_out, "%s = ", fld->fld_name);
  235. if (fld->fld_bitsize < (sz << 3)) {
  236. /* apparently a bit field */
  237. /* ??? */
  238. fprintf(db_out, "<bitfield, %d, %ld>", fld->fld_bitsize, sz);
  239. }
  240. else print_val(fld->fld_type, sz, addr+(fld->fld_pos>>3), compressed, indent, format);
  241. if (compressed && i > 1) {
  242. fprintf(db_out, ", ...");
  243. break;
  244. }
  245. if (i > 1) {
  246. putc(',', db_out);
  247. }
  248. fprintf(db_out, "\n%*c", i > 1 ? indent : indent - 4, ' ');
  249. }
  250. indent -= 4;
  251. fprintf(db_out, currlang->close_struct_display);
  252. break;
  253. }
  254. case T_UNION:
  255. fprintf(db_out, "<union>");
  256. break;
  257. case T_ENUM:
  258. print_literal(tp, get_int(addr, tp_sz, T_ENUM), compressed, format);
  259. break;
  260. case T_PROCEDURE: {
  261. register p_scope sc = get_scope_from_addr((t_addr) get_int(addr, pointer_size, T_UNSIGNED));
  262. if (sc && sc->sc_definedby) {
  263. fprintf(db_out, sc->sc_definedby->sy_idf->id_text);
  264. break;
  265. }
  266. }
  267. fprintf(db_out, currlang->addr_fmt, get_int(addr, pointer_size, T_UNSIGNED));
  268. break;
  269. case T_POINTER: {
  270. t_addr a = get_int(addr, tp_sz, T_UNSIGNED);
  271. fprintf(db_out, currlang->addr_fmt, a);
  272. if (format && strindex(format, 's') &&
  273. (tp->ty_ptrto == char_type || tp->ty_ptrto == uchar_type)) {
  274. char *naddr = malloc(512);
  275. if (! naddr) {
  276. fputs(" (could not allocate memory)", db_out);
  277. break;
  278. }
  279. if (! get_string(511L, a, naddr)) {
  280. fputs(" (not a valid pointer)", db_out);
  281. free(naddr);
  282. break;
  283. }
  284. fputs(" (", db_out);
  285. print_val(string_type, 512L, naddr, 0, indent, format);
  286. fputs(")", db_out);
  287. free(naddr);
  288. break;
  289. }
  290. if (tp->ty_ptrto->ty_class == T_PROCEDURE) {
  291. p_scope sc = get_scope_from_addr(a);
  292. if (sc && sc->sc_definedby && a == sc->sc_start) {
  293. fprintf(db_out, " (%s)", sc->sc_definedby->sy_idf->id_text);
  294. }
  295. }
  296. break;
  297. }
  298. case T_FILE:
  299. fprintf(db_out, "<file>");
  300. break;
  301. case T_SET: {
  302. long val = tp->ty_setlow;
  303. p_type base = tp->ty_setbase;
  304. long nelements = tp->ty_size << 3;
  305. int count = 0;
  306. int rsft = 3 + (int_size == 2 ? 1 : 2);
  307. long mask = int_size == 2 ? 017: 037;
  308. if (base->ty_class == T_SUBRANGE) base = base->ty_base;
  309. if (compressed) {
  310. fprintf(db_out, currlang->open_set_display);
  311. }
  312. else {
  313. fprintf(db_out, "\n%*c%s%*c",
  314. indent,
  315. ' ',
  316. currlang->open_set_display,
  317. 4-strlen(currlang->open_set_display), ' ');
  318. }
  319. indent += 4;
  320. for (i = 0; i < nelements; i++) {
  321. if (get_int(addr + (i >> rsft), int_size, T_UNSIGNED) & (1 << (i & mask))) {
  322. count++;
  323. if (count > 1) {
  324. if (compressed) {
  325. fprintf(db_out, ", ...");
  326. break;
  327. }
  328. fprintf(db_out, ",\n%*c", indent , ' ');
  329. }
  330. switch(base->ty_class) {
  331. case T_INTEGER:
  332. print_integer(base, val+i, format);
  333. break;
  334. case T_UNSIGNED:
  335. print_unsigned(base, val+i, format);
  336. break;
  337. case T_ENUM:
  338. print_literal(base, val+i, compressed, format);
  339. break;
  340. default:
  341. assert(0);
  342. }
  343. }
  344. }
  345. if (! compressed) {
  346. fprintf(db_out, "\n%*c", indent-4 , ' ');
  347. }
  348. indent -= 4;
  349. fprintf(db_out, currlang->close_set_display);
  350. }
  351. break;
  352. case T_REAL:
  353. fprintf(db_out, currlang->real_fmt, get_real(addr, tp->ty_size));
  354. break;
  355. case T_UNSIGNED:
  356. print_unsigned(tp, get_int(addr, tp_sz, T_UNSIGNED), format);
  357. break;
  358. case T_INTEGER:
  359. print_integer(tp, get_int(addr, tp_sz, T_INTEGER), format);
  360. break;
  361. case T_STRING:
  362. (*currlang->printstring)(db_out, addr, (int) tp_sz);
  363. break;
  364. default:
  365. assert(0);
  366. break;
  367. }
  368. }