-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.c
141 lines (130 loc) · 3.33 KB
/
utils.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
/**
* utils functions
*/
#include "headers.h"
#include "consts.h"
/**
* log error and exist
* @param err
* @param file_status
*/
void log_panic_wrapper(char *err, status *file_status) {
char error_msg[MAX_LOG_SIZE];
sprintf(error_msg, ERROR_WRAPPER, file_status->file_name, file_status->line_number, err);
fprintf(stderr, "%s", error_msg);
exit(1);
}
/**
* log error and update file status. set should skip if exist
* @param err
* @param file_status
* @param should_skip
*/
void log_error_wrapper(char *err, status *file_status,bool *should_skip) {
char error_msg[MAX_LOG_SIZE];
if (should_skip != NULL) {
*should_skip = true;
}
file_status->errors_flag = true;
sprintf(error_msg, ERROR_WRAPPER, file_status->file_name, file_status->line_number, err);
fprintf(stderr,"%s" ,error_msg);
}
/**
* log error without line and update file status. set should skip if exist
* @param err
* @param file_status
* @param should_skip
*/
void log_error_without_line_wrapper(char *err, status *file_status,bool *should_skip) {
char error_msg[MAX_LOG_SIZE];
if (should_skip != NULL) {
*should_skip = true;
}
file_status->errors_flag = true;
sprintf(error_msg, ERROR_WRAPPER_NO_LINE, file_status->file_name, err);
fprintf(stderr,"%s" ,error_msg);
}
/**
* safe malloc
* @param n - size of object
* @return pointer to created object
*/
void *safe_malloc(size_t n) {
void *p = malloc(n);
if (p == NULL) {
fprintf(stderr, "Fatal: failed to allocate memory.\n");
abort();
}
return p;
}
/**
* check if line is valid
* @param line - line to check
* @param fp - the file
* @param file_status - file status object
* @return if the line is valid
*/
bool is_valid_line(char *line, FILE *fp, status *file_status) {
if (strchr(line, '\n') == NULL && !feof(fp)) {
char err_msg[MAX_LINE_LENGTH];
sprintf(err_msg, "line maximum length is %d", MAX_LINE_LENGTH);
log_error_wrapper(err_msg, file_status,NULL);
return false;
}
return true;
}
/**
* concat 2 strings
* @param s1
* @param s2
* @return concat string
*/
char *concat(const char *s1, const char *s2) {
char *result = malloc(strlen(s1) + strlen(s2) + 1);
strcpy(result, s1);
strcat(result, s2);
return result;
}
/**
* extract the 4 bits from position p
* @param number - number to extract bits from
* @param p - position
* @return - extracted bits
*/
unsigned int extract_4_bits_from_pos(long number, int p) {
number = number >> p;
return ((number) & 0xF);
}
/**
* create new file status
* @param file_name - file name
* @param ext - file extension
* @return new file status
*/
status *new_status(char *file_name, char *ext) {
status *file_status = NULL;
file_status = (status *) safe_malloc(sizeof(status));
file_status->file_name = concat(file_name, ext);
file_status->line_number = 0;
file_status->errors_flag = false;
return file_status;
}
/**
* free file status from memory
* @param current_status
*/
void free_status(status *current_status) {
free(current_status->file_name);
free(current_status);
}
/**
* free all linked lists in project
*/
void free_linked_lists(){
free_symbol_table();
free_word_list();
free_macro_list();
free_entry_list();
free_data_list();
free_externals_list();
}