|
|
|
|
@@ -21,44 +21,128 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
This is part of a toolkit used to assist in ZSNES development
|
|
|
|
|
|
|
|
|
|
This program tells us is a variable is declared in the wrong section.
|
|
|
|
|
Or if code is not in an executable section.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include "strutil.h"
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
#include "fileutil.h"
|
|
|
|
|
|
|
|
|
|
#define LINE_LENGTH 500
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool contains_resx(const char *str)
|
|
|
|
|
{
|
|
|
|
|
return(!strncmp(str, "resd ", strlen("resd ")) ||
|
|
|
|
|
!strncmp(str, "resw ", strlen("resw ")) ||
|
|
|
|
|
!strncmp(str, "resb ", strlen("resb ")) ||
|
|
|
|
|
strstr(str, " resd ") ||
|
|
|
|
|
strstr(str, " resw ") ||
|
|
|
|
|
strstr(str, " resb ") ||
|
|
|
|
|
strstr(str, ",resd ") ||
|
|
|
|
|
strstr(str, ",resw ") ||
|
|
|
|
|
strstr(str, ",resb "));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool contains_dx(const char *str)
|
|
|
|
|
{
|
|
|
|
|
return(!strncmp(str, "dd ", strlen("dd ")) ||
|
|
|
|
|
!strncmp(str, "dw ", strlen("dw ")) ||
|
|
|
|
|
!strncmp(str, "db ", strlen("db ")) ||
|
|
|
|
|
strstr(str, " dd ") ||
|
|
|
|
|
strstr(str, " dw ") ||
|
|
|
|
|
strstr(str, " db ") ||
|
|
|
|
|
strstr(str, ",dd ") ||
|
|
|
|
|
strstr(str, ",dw ") ||
|
|
|
|
|
strstr(str, ",db "));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool label(const char *str)
|
|
|
|
|
{
|
|
|
|
|
return(!strchr(str, ' ') && !strchr(str, '\t') && (str[strlen(str)-1] == ':'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void handle_file(const char *filename)
|
|
|
|
|
{
|
|
|
|
|
enum sections { sec_unknown, sec_bss, sec_data, sec_text };
|
|
|
|
|
enum sections { sec_unknown, sec_bss, sec_data, sec_text, sec_macro };
|
|
|
|
|
|
|
|
|
|
ifstream file(filename, ios::in);
|
|
|
|
|
if (file)
|
|
|
|
|
{
|
|
|
|
|
char line[LINE_LENGTH];
|
|
|
|
|
sections cur_section = sec_unknown;
|
|
|
|
|
for (size_t i = 0; file.getline(line, LINE_LENGTH); i++)
|
|
|
|
|
char buffer[LINE_LENGTH];
|
|
|
|
|
sections cur_section = sec_unknown, prev_section = sec_unknown;
|
|
|
|
|
for (size_t i = 1; file.getline(buffer, LINE_LENGTH); i++)
|
|
|
|
|
{
|
|
|
|
|
if (!strcasecmp(line, "SECTION .BSS")) { cur_section = sec_bss; }
|
|
|
|
|
if (!strcasecmp(line, "SECTION .DATA")) { cur_section = sec_data; }
|
|
|
|
|
if (!strcasecmp(line, "SECTION .text")) { cur_section = sec_text; }
|
|
|
|
|
char *line = buffer;
|
|
|
|
|
|
|
|
|
|
if ((cur_section != sec_bss) &&
|
|
|
|
|
(strstr(line, " resd ") || strstr(line, " resw ") || strstr(line, " resb ") ||
|
|
|
|
|
(strstr(line, ",resd ") || strstr(line, ",resw ") || strstr(line, ",resb ")) ))
|
|
|
|
|
char *comment_p = strchr(line, ';');
|
|
|
|
|
if (comment_p) { *comment_p = 0; }
|
|
|
|
|
|
|
|
|
|
if (all_whitespace(line)) { continue; }
|
|
|
|
|
|
|
|
|
|
for (char *p = line+strlen(line)-1; isspace(*p); p--) { *p = 0; }
|
|
|
|
|
while (isspace(*line)) { line++; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp(line, "SECTION .BSS"))
|
|
|
|
|
{
|
|
|
|
|
prev_section = cur_section;
|
|
|
|
|
cur_section = sec_bss;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp(line, "SECTION .DATA"))
|
|
|
|
|
{
|
|
|
|
|
prev_section = cur_section;
|
|
|
|
|
cur_section = sec_data;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp(line, "SECTION .text"))
|
|
|
|
|
{
|
|
|
|
|
prev_section = cur_section;
|
|
|
|
|
cur_section = sec_text;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strncmp(line, "%macro", strlen("%macro")) ||
|
|
|
|
|
!strncmp(line, "%imacro", strlen("%imacro")))
|
|
|
|
|
{
|
|
|
|
|
prev_section = cur_section;
|
|
|
|
|
cur_section = sec_macro;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strncmp(line, "%endmacro", strlen("%endmacro")))
|
|
|
|
|
{
|
|
|
|
|
cur_section = prev_section;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((cur_section != sec_bss) && contains_resx(line))
|
|
|
|
|
{
|
|
|
|
|
cout << filename << ": line " << i << ": Error, resx in non BSS section. \"" << line << "\"" << endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((cur_section != sec_data) &&
|
|
|
|
|
(strstr(line, " dd ") || strstr(line, " dw ") || strstr(line, " db ") ||
|
|
|
|
|
(strstr(line, ",dd ") || strstr(line, ",dw ") || strstr(line, ",db ")) ))
|
|
|
|
|
if ((cur_section != sec_data) && contains_dx(line))
|
|
|
|
|
{
|
|
|
|
|
cout << filename << ": line " << i << ": Error, dx in non DATA section. \"" << line << "\"" << endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((cur_section != sec_text) && (cur_section != sec_macro))
|
|
|
|
|
{
|
|
|
|
|
if (!contains_resx(line) && !contains_dx(line) && !label(line) &&
|
|
|
|
|
!strstr(line, "NEWSYM") && !strstr(line, "EXTSYM") && !strstr(line, " equ ") &&
|
|
|
|
|
(*line != '%') && !strstr(line, "ALIGN") && strncmp(line, "bits ", strlen("bits ")))
|
|
|
|
|
{
|
|
|
|
|
cout << filename << ": line " << i << ": Error, code in non TEXT section. \"" << line << "\"" << endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
|