0,0 → 1,420 |
#include <stdio.h> |
#include <string.h> |
#include <ctype.h> |
#include <cstring> |
#include <string> |
using namespace std; |
|
char str[20000], *word[100]; |
int wordlen[sizeof(word) / sizeof(word[0])]; |
|
char words_ignore[100][100] = { "?debug", |
"if", |
"ifdef", |
"ifndef", |
"endif", |
"macro", |
"endm", |
"dgroup", |
"assume", |
"segment", |
"ends", |
"public", |
"proc", |
"endp", |
"extrn", |
"model", |
"label", |
"end", |
""}; |
|
#define WI_macro (words_ignore[5]) |
#define WI_endm (words_ignore[6]) |
#define WI_segment (words_ignore[9]) |
#define WI_ends (words_ignore[10]) |
#define WI_proc (words_ignore[12]) |
#define WI_endp (words_ignore[13]) |
#define WI_label (words_ignore[16]) |
const char *WI_END = "END"; |
|
int nwords_ignore = -1; |
char *words_ign_sort[sizeof(words_ignore) / sizeof(words_ignore[0])]; |
|
int strcmp1(const char *s0, int n0, const char *s1, int n1) |
{ |
while (n0 && n1) |
{ |
n0--; n1--; |
int c = (int)tolower(*s0) - (int)tolower(*s1); |
if (c < 0) return -1; |
if (c > 0) return 1; |
if (!*(s0++) || !*(s1++)) return 0; |
} |
if (n0 && *s0) return 1; |
if (n1 && *s1) return -1; |
return 0; |
} |
|
int strlen1(const char *s, int n) |
{ |
int i = 0; |
while (i < n && s[i]) i++; |
return i; |
} |
|
char *strcpy1(char *r, const char *s, int n) |
{ |
char *r0 = r; |
while (n-- && *s) *(r++) = *(s++); |
*r = 0; |
return r0; |
} |
|
char *strchr1(char *s, int n, char c) |
{ |
while (n-- && *s) |
{ |
if (*s == c) return s; |
s++; |
} |
return 0; |
} |
|
char *first_not_space(char *s) |
{ |
while (*s && isspace(*s)) s++; |
return s; |
} |
|
char get_word(char *s) |
{ |
int i = 0, k; |
for (k = 0; k < sizeof(word) / sizeof(word[0]); k++) |
{ |
s = first_not_space(s + i); |
word[k] = s; |
i = 0; |
while (s[i] && !isspace(s[i]) && s[i] != ';' && s[i] != ',' && s[i] != ':') |
{ |
i++; |
} |
if (i == 0) |
{ |
if (s[i] != ',' && s[i] != ':') break; |
i = 1; |
} |
wordlen[k] = i; |
} |
for (; k < sizeof(word) / sizeof(word[0]); k++) |
{ |
word[k] = s; wordlen[k] = 0; |
} |
return s[i]; |
} |
|
void build_words_ignore() |
{ |
int i, j; |
nwords_ignore = 0; |
while (words_ignore[nwords_ignore][0]) |
{ |
words_ign_sort[nwords_ignore] = words_ignore[nwords_ignore]; |
nwords_ignore++; |
} |
for (i = 0; i < nwords_ignore; i++) for (j = 0; j < i; j++) |
{ |
if (strcmp1(words_ign_sort[j], -1, words_ign_sort[i], -1) > 0) |
{ |
char *s = words_ign_sort[j]; |
words_ign_sort[j] = words_ign_sort[i]; |
words_ign_sort[i] = s; |
} |
} |
words_ign_sort[nwords_ignore] = words_ignore[nwords_ignore]; |
} |
|
int find_word_ign_sort(const char *s, int n) |
{ |
int i0, i1, i; |
if (nwords_ignore < 0) build_words_ignore(); |
i0 = -1; i1 = nwords_ignore; |
while (i1 > i0 + 1) |
{ |
i = (i0 + i1) / 2; |
if (strcmp1(s, n, words_ign_sort[i], -1) > 0) i0 = i; |
else i1 = i; |
} |
return i1; |
} |
|
char *find_word_ignore(const char *s, int n) |
{ |
int i = find_word_ign_sort(s, n); |
return (strcmp1(s, n, words_ign_sort[i], -1) == 0) ? words_ign_sort[i] : 0; |
} |
|
char *add_word_ignore(const char *s, int n) |
{ |
int i = find_word_ign_sort(s, n), j; |
if (strcmp1(s, n, words_ign_sort[i], -1) != 0) |
{ |
if (s[0] && strlen1(s, n) < sizeof(words_ignore[0]) && |
words_ignore[nwords_ignore+1] < words_ignore[0] + sizeof(words_ignore)) |
{ |
strcpy1(words_ignore[nwords_ignore], s, n); |
words_ignore[nwords_ignore+1][0] = 0; |
for (j = nwords_ignore; j >= i; j--) words_ign_sort[j+1] = words_ign_sort[j]; |
words_ign_sort[i] = words_ignore[nwords_ignore]; |
nwords_ignore++; |
words_ign_sort[nwords_ignore] = words_ignore[nwords_ignore]; |
} |
else return 0; |
} |
return words_ign_sort[i]; |
} |
|
struct CSegment |
{ |
char name[100]; |
int state; |
string text; |
}; |
|
int nsegment = 0, cursegment = 0, stack_segment[50], nstack_segment = 0; |
CSegment segment[100]; |
|
void push_stack_segment() |
{ |
if (nstack_segment < sizeof(stack_segment) / sizeof(stack_segment[0])) |
{ |
stack_segment[nstack_segment] = cursegment; |
} |
nstack_segment++; |
} |
|
void pop_stack_segment() |
{ |
if (nstack_segment > 0) nstack_segment--; |
if (nstack_segment < sizeof(stack_segment) / sizeof(stack_segment[0])) |
{ |
cursegment = stack_segment[nstack_segment]; |
} |
} |
|
void newsegment() |
{ |
segment[nsegment].name[0] = 0; |
segment[nsegment].state = 0; |
segment[nsegment].text = ""; |
cursegment = nsegment++; |
} |
|
void tosegment(char *name, int nameL) |
{ |
int i; |
cursegment = 0; |
if (strlen1(name, nameL) >= sizeof(segment[0].name)) return; |
for (i = 0; i < nsegment; i++) |
{ |
if (strcmp1(name, nameL, segment[i].name, -1) == 0) |
{ |
cursegment = i; |
return; |
} |
} |
if (nsegment >= sizeof(segment) / sizeof(segment[0])) return; |
newsegment(); |
strcpy1(segment[cursegment].name, name, nameL); |
} |
|
void outsegment() |
{ |
if (segment[cursegment].state == 0) return; |
fputs("\nsegment", stdout); |
if (segment[cursegment].name[0]) |
{ |
fputc(' ', stdout); |
fputs(segment[cursegment].name, stdout); |
} |
fputc('\n', stdout); |
fputs(segment[cursegment].text.c_str(), stdout); |
fputs("endseg", stdout); |
if (segment[cursegment].name[0]) |
{ |
fputs(" ", stdout); |
fputs(segment[cursegment].name, stdout); |
} |
fputc('\n', stdout); |
} |
|
void transform_label(int in_define, bool label = false) |
{ |
if (in_define) |
{ |
memmove(str + 8, word[0], wordlen[0]); |
memcpy(str, "nextdef ", 8); |
str[wordlen[0]+8] = '\n'; |
str[wordlen[0]+9] = 0; |
} |
else if (label) |
{ |
memmove(str, word[0], wordlen[0]); |
str[wordlen[0]] = ':'; |
str[wordlen[0]+1] = '\n'; |
str[wordlen[0]+2] = 0; |
} |
segment[cursegment].state |= 4; |
} |
|
int main() |
{ |
char *s; |
int in_macro = 0, in_define = 0, i; |
newsegment(); |
for (;;) |
{ |
i = sizeof(str) - 200; |
if (!fgets(str, i, stdin)) break; |
if ((s = strchr(str, '\n')) == NULL) |
{ |
if (strlen(str) < i-1) strcat(str, "\n"); |
else |
{ |
while (fgets(str, sizeof(str), stdin)) |
{ |
if (strchr(str, '\n')) break; |
} |
continue; |
} |
} |
char* p; |
while (p=strstr(str,"st(")) |
{ |
p[2]=p[3]; |
memmove(p+3,p+5,strlen(p+5)+1); |
} |
get_word(str); |
if (word[1][0] == ':') transform_label(in_define, false); |
else |
{ |
if (word[0][0] == '.') continue; |
if (strcmp1(word[0], wordlen[0], WI_macro, -1) == 0 || |
strcmp1(word[1], wordlen[1], WI_macro, -1) == 0) |
{ |
add_word_ignore(word[0], wordlen[0]); |
in_macro++; |
continue; |
} |
if (strcmp1(word[0], wordlen[0], WI_endm, -1) == 0) |
{ |
if (in_macro > 0) in_macro--; |
continue; |
} |
if (strcmp1(word[1], wordlen[1], WI_segment, -1) == 0) |
{ |
push_stack_segment(); |
add_word_ignore(word[0], wordlen[0]); |
tosegment(word[0], wordlen[0]); |
continue; |
} |
if (strcmp1(word[1], wordlen[1], WI_ends, -1) == 0) |
{ |
pop_stack_segment(); |
continue; |
} |
if (find_word_ignore(word[0], wordlen[0])) continue; |
if (wordlen[0] == 0 || strcmp1(word[0], wordlen[0], "align", -1) == 0) |
{ |
if (word[0][0] == 0) {str[0] = '\n'; str[1] = 0;} |
} |
else if (strcmp1(word[1], wordlen[1], WI_endp, -1) == 0) |
{ |
if (in_define > 0) strcpy(str, (--in_define) ? "newdef\n" : "enddef\n"); |
} |
else if (strcmp1(word[1], wordlen[1], WI_proc, -1) == 0) |
{ |
memmove(str + 8, word[0], wordlen[0]); |
memcpy(str, (in_define++) ? "newdef " : "define ", 8); |
str[wordlen[0]+8] = '\n'; |
str[wordlen[0]+9] = 0; |
segment[cursegment].state |= 4; |
} |
else if (strcmp1(word[1], wordlen[1], WI_label, -1) == 0) |
{ |
transform_label(in_define, true); |
} |
else |
{ |
for (i = 0; i <= 1; i++) |
{ |
if (strcmp1(word[i], wordlen[i], "db", -1) == 0 && |
wordlen[i+2] >= 3 && strcmp1(word[i+2], 3, "dup", 3) == 0) |
{ |
if (word[i][0] == 'd') word[i][0] = 'r'; |
else if (word[i][0] == 'D') word[i][0] = 'R'; |
word[i+1][wordlen[i+1]] = '\n'; |
word[i+1][wordlen[i+1]+1] = 0; |
segment[cursegment].state |= 2; |
break; |
} |
} |
if (i > 1) |
{ |
int word_shift = 0; |
for (i = 1; i < sizeof(word) / sizeof(word[0]); i++) |
{ |
word[i] += word_shift; |
if (wordlen[i] >= 4 && word[i][0] != '[' && |
word[i][wordlen[i]-1] == ']' && |
(s = strchr1(word[i], wordlen[i], '[')) != 0) |
{ |
*s = '+'; |
memmove(word[i] + 1, word[i], strlen(word[i]) + 1); |
word[i][0] = '['; |
wordlen[i]++; |
word_shift++; |
} |
else if (wordlen[i] >= 1 && !strchr1(word[i], wordlen[i], '[') && |
strcmp1(word[i-1], wordlen[i-1], "ptr", -1) == 0) |
{ |
memmove(word[i] + wordlen[i] + 2, word[i] + wordlen[i], |
strlen(word[i] + wordlen[i]) + 1); |
memmove(word[i] + 1, word[i], wordlen[i]); |
word[i][0] = '['; word[i][wordlen[i] + 1] = ']'; |
wordlen[i] += 2; |
word_shift += 2; |
} |
else if (wordlen[i] >= 5 && word[i][wordlen[i]-1] == ')' && |
strcmp1(word[i], wordlen[i], "st(", -1)) |
{ |
memmove(word[i] + 2, word[i] + 3, wordlen[i] - 4); |
memmove(word[i] + wordlen[i] - 2, word[i] + wordlen[i], |
strlen(word[i] + wordlen[i]) + 1); |
word_shift -= 2; |
} |
} |
segment[cursegment].state |= 1; |
} |
} |
} |
if (in_macro) continue; |
if ((s = strchr(str, ';')) != NULL) |
{ |
s[0] = '\n'; s[1] = 0; |
if (!first_not_space(str)[0]) continue; |
} |
segment[cursegment].text += str; |
} |
for (cursegment = 0; cursegment < nsegment; cursegment++) |
{ |
if ((segment[cursegment].state & 3) != 2) outsegment(); |
} |
fputs("\nI_END:\n", stdout); |
for (cursegment = 0; cursegment < nsegment; cursegment++) |
{ |
if ((segment[cursegment].state & 3) == 2) outsegment(); |
} |
fputs("\nalign 0x10\nU_END:\n", stdout); |
return 0; |
} |
|