PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/CSC586A/A1/PrintClassFile.c

https://github.com/jordanell/School
C | 146 lines | 125 code | 14 blank | 7 comment | 10 complexity | 3c208ca4e6827b75fd1265add6350db0 MD5 | raw file
  1. /* PrintClassFile.c */
  2. /*
  3. Prints all the information for a class in a format
  4. similar to that produced by the command
  5. javap -c -verbose foo.class
  6. */
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #include <stdint.h>
  12. #include "ClassFileFormat.h"
  13. #include "MyAlloc.h"
  14. #include "PrintClassFile.h"
  15. #include "PrintByteCode.h"
  16. char *CP_Tagname[] = {
  17. "??", "UTF8", "??", "Integer", "Float", "Long", "Double", "Class",
  18. "String", "Field", "Method", "Interface", "NameAndType"
  19. };
  20. void PrintUTF8( uint8_t *s ) {
  21. int len;
  22. if (s == NULL) {
  23. printf("*NULL*");
  24. return;
  25. }
  26. len = (s[0]<<8) + s[1];
  27. s += 2;
  28. putchar('\"');
  29. while(len-- > 0) {
  30. int c = (*s++) & 0xFF;
  31. switch(c) {
  32. case '\"':
  33. case '\\':
  34. case '\'':
  35. putchar('\\'); break;
  36. case '\n':
  37. putchar('\\'); c = 'n'; break;
  38. case '\r':
  39. putchar('\\'); c = 'r'; break;
  40. case '\t':
  41. putchar('\\'); c = 't'; break;
  42. case '\b':
  43. putchar('\\'); c = 'b'; break;
  44. case '\f':
  45. putchar('\\'); c = 'f'; break;
  46. default:
  47. if (!isprint(c)) {
  48. printf("\\x%2x", c);
  49. continue;
  50. }
  51. break;
  52. }
  53. putchar(c);
  54. }
  55. putchar('\"');
  56. }
  57. void PrintConstantPool( ClassFile *cf ) {
  58. int ix;
  59. printf("\n Constant Pool\n =============\n\n");
  60. for( ix=1; ix<cf->constant_pool_count; ix++ ) {
  61. ConstantPoolTag t = cf->cp_tag[ix];
  62. ConstantPoolItem *cpi = &cf->cp_item[ix];
  63. char *s = GetCPItemAsString(cf,ix);
  64. if (t > 12) t = 0;
  65. printf(" #%d: %s ", ix, CP_Tagname[t]);
  66. switch(t) {
  67. case CP_Field:
  68. case CP_Method:
  69. case CP_Interface:
  70. printf("#%d.#%d %s\n", cpi->ss.sval1, cpi->ss.sval2, s);
  71. break;
  72. case CP_NameAndType:
  73. printf("#%d:#%d %s\n", cpi->ss.sval1, cpi->ss.sval2, s);
  74. break;
  75. case CP_UTF8:
  76. PrintUTF8(cpi->sval);
  77. putchar('\n');
  78. break;
  79. case CP_Double:
  80. case CP_Long:
  81. ix++;
  82. printf("%s\n", s);
  83. break;
  84. default:
  85. printf("%s\n", s);
  86. break;
  87. }
  88. SafeFree(s);
  89. }
  90. }
  91. void PrintMethod( ClassFile *cf, int ix ) {
  92. method_info *m = &(cf->methods[ix]);
  93. char *s = GetCPItemAsString(cf, m->name_index);
  94. printf("\n Method %s\n", s);
  95. SafeFree(s);
  96. s = GetCPItemAsString(cf, m->descriptor_index);
  97. printf(" signature = %s\n", s);
  98. SafeFree(s);
  99. printf(" args_size=%d, max_stack=%d, max_locals=%d\n",
  100. (int)m->nArgs, (int)m->max_stack, (int)m->max_locals);
  101. printf(" Code:\n");
  102. PrintByteCode(cf, m->code, m->code_length);
  103. }
  104. void PrintInterfaces( ClassFile *cf, int ifcnt, uint16_t *ip ) {
  105. if (ifcnt == 0) return;
  106. printf("\n interfaces implemented:\n");
  107. while(ifcnt-- > 0) {
  108. uint16_t ix = *ip++;
  109. // ConstantPoolTag t = cf->cp_tag[ix];
  110. char *s = GetCPItemAsString(cf, ix);
  111. printf(" %s\n", s);
  112. SafeFree(s);
  113. }
  114. printf("\n");
  115. }
  116. void PrintClassFile( ClassFile *cf ) {
  117. char *s;
  118. int i;
  119. if (cf == NULL) {
  120. printf("Null\n");
  121. return;
  122. }
  123. printf("Class %s:\n", cf->cname);
  124. s = GetCPItemAsString(cf, cf->super_class);
  125. printf(" parent = %s\n", s);
  126. SafeFree(s);
  127. PrintConstantPool(cf);
  128. PrintInterfaces(cf, cf->interfaces_count, cf->interfaces);
  129. for( i=0; i<cf->methods_count; i++ ) {
  130. PrintMethod(cf, i);
  131. }
  132. }