-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInputOutputHandler.c
206 lines (172 loc) · 5.41 KB
/
InputOutputHandler.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#include "declarationsHeader.h"
static int address = STARTING_ADDRESS;
extern struct keyWords keys[];
extern symPtr symTableHead;
extern dataPtr dataListHead;
extern extPtr extListHead;
extern insPtr insListHead;
extern char *fileName;
extern size_t dataListLength;
extern size_t insListLength;
/*
* Creates all the relevant files.
*/
void createFiles() {
/*Coding the memory words according to its type*/
writeObjectFile();
/*Creating the ex.ps File.*/
writeExtFile();
/*Creating the ent.ps File.*/
writeEntFile();
}
/*
* Creates the object file.
*/
void writeObjectFile() {
FILE *res_fd;
char objectFile[] = ".ob", temp[TMP_STR_LEN];
char tempFileName[STRING_SIZE];
insPtr ptr = insListHead;
/*File naming and adding extension.*/
strcpy(tempFileName, fileName);
strcat(tempFileName, objectFile);
if (insListLength == 0 && dataListLength == 0) /*Nothing to code.*/
return;
/*Appending the machine code file*/
if ((!(res_fd = fopen(tempFileName, WRITE_ONLY)))) {
printErrorWithComment(err_app_file, "object file");
exit(EXIT_FAILURE);
}
/*Adding sizes to file.*/
addSizesToObjectFile(res_fd, insListLength, dataListLength);
for (address = STARTING_ADDRESS; ptr; ptr = ptr->next) {
sprintf(temp, "%d", address);/*Converting the address to string*/
fputs(temp, res_fd);
fputs(TAB, res_fd);
/*If the current word is used with external symbol, we update its address for later use.*/
if ((ptr->data)->ERAforAdd == 1)
updateExtList(address);
address++;
fputs(ptr->strWord, res_fd);
fputs(NEWLINE, res_fd);
}
/*Adding the data code to the object file.*/
addDataCodeToFile(res_fd);
fclose(res_fd);
}
/*
* Creates the ent file.
*/
void writeEntFile() {
FILE *fd;
char entAddress[TMP_STR_LEN], tempFileName[STRING_SIZE], entFile[] = ".ent";
size_t entSym = 0;
symPtr ptr;
/*File naming and adding extension.*/
strcpy(tempFileName, fileName);
strcat(tempFileName, entFile);
if (!(fd = fopen(tempFileName, WRITE_ONLY))) {
printErrorWithComment(writing_to_file, "ent file");
exit(EXIT_FAILURE);
}
/*Writing to file the symbols & address.*/
for (ptr = symTableHead; ptr; ptr = ptr->next) {
if (ptr->isEnt && ++entSym) {
sprintf(entAddress, "%d", ptr->data);/*Converting the address to string*/
fputs(ptr->symName, fd);
fputs(TAB, fd);
fputs(entAddress, fd);
fputs(NEWLINE, fd);
}
}
/*If we didnt have entry symbols, we remove the file.*/
if (entSym == 0) {
remove(tempFileName);
return;
}
fclose(fd);
}
/*
* Creates the ext file/
*/
void writeExtFile() {
FILE *fd;
char tempFileName[STRING_SIZE], extFile[] = ".ext", extAddress[TMP_STR_LEN];
extPtr ptr = extListHead;
/*File naming and adding extension.*/
strcpy(tempFileName, fileName);
strcat(tempFileName, extFile);
if (extListHead == NULL)/*No extern symbols within the file.*/
return;
if (!(fd = fopen(tempFileName, WRITE_ONLY))) {
printErrorWithComment(writing_to_file, "ext file");
exit(EXIT_FAILURE);
}
/*Writing the symbols and its address to the File.*/
for (; ptr; ptr = ptr->next) {
sprintf(extAddress, "%d", ptr->address);/*Converting the address to string.*/
fputs(ptr->symbol, fd); /*Writing the symbol.*/
fputs(TAB, fd);
fputs(extAddress, fd);/*Writing its address.*/
fputs(NEWLINE, fd);
}
fclose(fd);
}
/*
* Adding the sizes of the data & instructions code length to the top of the object file.
*/
void addSizesToObjectFile(FILE *res_fd, int insSize, int dataSize) {
char temp[CMD_LENGTH];
fputs(TAB, res_fd);
/*Converting the address to string.*/
sprintf(temp, "%d", insSize);
/*Putting the size of the instructions.*/
fputs(temp, res_fd);
fputs(TAB, res_fd);
/*Putting the size of the data.*/
sprintf(temp, "%d", dataSize);
fputs(temp, res_fd);
fputs(NEWLINE, res_fd);
}
/*
* Adds the data code after the instruction part code to the object file.
*/
void addDataCodeToFile(FILE *res_fd) {
const size_t theEndOfFile = 0;
dataPtr ptr = dataListHead;
char temp[TMP_STR_LEN];
if (dataListLength == 0)/*Nothing to code.*/
return;
/*Getting to the end of the file*/
fseek(res_fd, theEndOfFile, SEEK_END);
/*Writing the code into the file*/
for (; ptr; ptr = ptr->next, address++) {
sprintf(temp, "%d", address);/*Converting the address to string*/
if (ptr != dataListHead)
fputs(NEWLINE, res_fd);
fputs(temp, res_fd);
fputs(TAB, res_fd);
fputs(ptr->data, res_fd);
}
}
/*
* Changes the type of the symbol to entry.
*/
void preWritingToFileEnt() {
char lineCpy[LINE_SIZE];
char tempLabel[SYM_SIZE];
symPtr sPtr = symTableHead;
const int entStrLen = 6;
strcpy(lineCpy, line);
/*Taking the label after the .entry*/
strcpy(tempLabel, (strstr(lineCpy, GUIDING_SENTENCE_ENT) + entStrLen));
removeSpaces(tempLabel);
/*Validating the sym is legit.*/
symIsIllegal(tempLabel);
/*Changing the value of the ent sym to be true for later use.*/
for (; sPtr; sPtr = sPtr->next) {
if (strcmp(tempLabel, sPtr->symName) == EQUAL) {
sPtr->isEnt = TRUE;
}
}
}