Overhauled Section checker, and added ability to find code in not executable segements.

This commit is contained in:
n-a-c-h
2005-07-10 12:37:08 +00:00
parent 5bd3b89854
commit fc4176bf24
4 changed files with 111 additions and 14 deletions

View File

@@ -119,7 +119,7 @@ extraext: ${TOOLSOBJ}
@CXX@ @CFLAGS@ -o ${TOOLSDIR}/extraext ${TOOLSDIR}/extraext.cpp ${TOOLSOBJ}
sec-test: ${TOOLSOBJ}
@CXX@ @CFLAGS@ -o ${TOOLSDIR}/sec-test ${TOOLSDIR}/sec-test.cpp ${TOOLSDIR}/fileutil.o
@CXX@ @CFLAGS@ -o ${TOOLSDIR}/sec-test ${TOOLSDIR}/sec-test.cpp ${TOOLSOBJ}
srccount: ${TOOLSOBJ}
@CXX@ @CFLAGS@ -o ${TOOLSDIR}/srccount ${TOOLSDIR}/srccount.cpp ${TOOLSDIR}/fileutil.o

View File

@@ -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

View File

@@ -44,3 +44,15 @@ void Tokenize(const string& str, vector<string>& tokens, const string& delimiter
pos = str.find_first_of(delimiters, lastPos);
}
}
bool all_whitespace(const char *str)
{
for (; *str; str++)
{
if (!isspace(*str))
{
return(false);
}
}
return(true);
}

View File

@@ -28,5 +28,6 @@ This is part of a toolkit used to assist in ZSNES development
#include <vector>
void Tokenize(const std::string&, std::vector<std::string>&, const std::string&);
bool all_whitespace(const char *);
#endif