1 | #include <string>
|
2 | #include <stdio.h>
|
3 | #include <stdlib.h>
|
4 |
|
5 | #include "id_kind.h"
|
6 | #include "osh.asdl.h"
|
7 |
|
8 | // Returns the root ref, or -1 for invalid
|
9 | int GetRootRef(uint8_t* image) {
|
10 | if (image[0] != 'O') return -1;
|
11 | if (image[1] != 'H') return -1;
|
12 | if (image[2] != 'P') return -1;
|
13 | if (image[3] != 1) return -1; // version 1
|
14 | if (image[4] != 4) return -1; // alignment 4
|
15 |
|
16 | return image[5] + (image[6] << 8) + (image[7] << 16);
|
17 | }
|
18 |
|
19 | void PrintToken(const uint32_t* base, const token_t& e, int indent) {
|
20 | for (int i = 0; i < indent; ++i) {
|
21 | putchar('\t');
|
22 | }
|
23 | printf("Token %hhu %s\n", e.id(), e.val(base));
|
24 | }
|
25 |
|
26 | void PrintWordPart(const uint32_t* base, const word_part_t& e, int indent) {
|
27 | for (int i = 0; i < indent; ++i) {
|
28 | putchar('\t');
|
29 | }
|
30 | printf("t%hhu ", e.tag());
|
31 | switch (e.tag()) {
|
32 | case word_part_e::LiteralPart: {
|
33 | auto& e2 = static_cast<const LiteralPart&>(e);
|
34 | printf("LiteralPart\n");
|
35 | PrintToken(base, e2.token(base), indent+1);
|
36 | break;
|
37 | }
|
38 | default:
|
39 | printf("OTHER word_part\n");
|
40 | break;
|
41 | }
|
42 | }
|
43 |
|
44 | void PrintWord(const uint32_t* base, const word_t& e, int indent) {
|
45 | for (int i = 0; i < indent; ++i) {
|
46 | putchar('\t');
|
47 | }
|
48 | printf("t%hhu ", e.tag());
|
49 | switch (e.tag()) {
|
50 | case word_e::CompoundWord: {
|
51 | auto& e2 = static_cast<const CompoundWord&>(e);
|
52 | printf("CompoundWord %d\n", e2.parts_size(base));
|
53 | for (int i = 0; i < e2.parts_size(base); ++i) {
|
54 | PrintWordPart(base, e2.parts(base, i), indent+1);
|
55 | }
|
56 | break;
|
57 | }
|
58 | default:
|
59 | printf("OTHER word\n");
|
60 | break;
|
61 | }
|
62 | }
|
63 |
|
64 | void PrintCommand(const uint32_t* base, const command_t& e, int indent) {
|
65 | for (int i = 0; i < indent; ++i) {
|
66 | putchar('\t');
|
67 | }
|
68 | printf("t%hhu ", e.tag());
|
69 |
|
70 | switch (e.tag()) {
|
71 | case command_e::SimpleCommand: {
|
72 | auto& e2 = static_cast<const SimpleCommand&>(e);
|
73 | printf("SimpleCommand %d\n", e2.words_size(base));
|
74 | for (int i = 0; i < e2.words_size(base); ++i) {
|
75 | PrintWord(base, e2.words(base, i), indent+1);
|
76 | }
|
77 | break;
|
78 | }
|
79 | case command_e::Assignment: {
|
80 | auto& e2 = static_cast<const Assignment&>(e);
|
81 | printf("Assignment flags: ");
|
82 | for (int i = 0; i < e2.flags_size(base); ++i) {
|
83 | printf("%s ", e2.flags(base, i));
|
84 | }
|
85 | printf("\n");
|
86 | break;
|
87 | }
|
88 | case command_e::AndOr: {
|
89 | auto& e2 = static_cast<const AndOr&>(e);
|
90 | printf("Ops: ");
|
91 | for (int i = 0; i < e2.ops_size(base); ++i) {
|
92 | printf("%hhu ", e2.ops(base, i));
|
93 | }
|
94 | printf("\n");
|
95 | for (int i = 0; i < e2.children_size(base); ++i) {
|
96 | PrintCommand(base, e2.children(base, i), indent+1);
|
97 | }
|
98 | printf("\n");
|
99 | break;
|
100 | }
|
101 | case command_e::CommandList: {
|
102 | auto& e2 = static_cast<const CommandList&>(e);
|
103 | printf("CommandList %d\n", e2.children_size(base));
|
104 | for (int i = 0; i < e2.children_size(base); ++i) {
|
105 | PrintCommand(base, e2.children(base, i), indent+1);
|
106 | }
|
107 | break;
|
108 | }
|
109 | default:
|
110 | printf("OTHER\n");
|
111 | break;
|
112 | }
|
113 | }
|
114 |
|
115 | int main(int argc, char **argv) {
|
116 | if (argc == 0) {
|
117 | printf("Expected filename\n");
|
118 | return 1;
|
119 | }
|
120 | FILE *f = fopen(argv[1], "rb");
|
121 | if (!f) {
|
122 | fprintf(stderr, "Error opening %s\n", argv[1]);
|
123 | return 1;
|
124 | }
|
125 | fseek(f, 0, SEEK_END);
|
126 | size_t num_bytes = ftell(f);
|
127 | fseek(f, 0, SEEK_SET); //same as rewind(f);
|
128 |
|
129 | uint8_t* image = static_cast<uint8_t*>(malloc(num_bytes + 1));
|
130 | fread(image, num_bytes, 1, f);
|
131 | fclose(f);
|
132 |
|
133 | image[num_bytes] = 0;
|
134 | printf("Read %zu bytes\n", num_bytes);
|
135 |
|
136 | int root_ref = GetRootRef(image);
|
137 | if (root_ref == -1) {
|
138 | printf("Invalid image\n");
|
139 | return 1;
|
140 | }
|
141 | // Hm we could make the root ref be a BYTE offset?
|
142 | int alignment = 4;
|
143 | printf("alignment: %d root: %d\n", alignment, root_ref);
|
144 |
|
145 | auto base = reinterpret_cast<uint32_t*>(image);
|
146 |
|
147 | size_t offset = alignment * root_ref;
|
148 | auto expr = reinterpret_cast<command_t*>(image + offset);
|
149 | PrintCommand(base, *expr, 0);
|
150 | }
|