📄 main.c
字号:
// sccavr.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include "defs.h"
#include "data.h"
#include "headers.h"
static void readstkchk(void);
static int CheckAsciiSN(char *sn, char *num);
static int Inverse(char *f, char *num);
static int CheckINI(char *me);
static int AddINI(char *me, char *sn);
static char *CheckInStr(char *p, char *s);
static int mine();
static void DumpGlobalConstants();
static void ClearTable();
static void notrailers(char *val);
static char temp[50];
static char *version = " SCCAVR - SmallC Compiler for AVR, Version 2.4.7\n";
int main(int argc, char *argv[]) {
char *p,*bp;
int smacptr;
char path[200];
strcpy(path, argv[0]);
hardstk = 607;
softstk = 575;
macptr = 0;
ctext = 0;
Vtype = 1; // default for 8515
stkchk = 0;
gcptr = 0;
softstklimit = 0xffff; hardstklimit = 0xffff;
argc--; argv++;
errs = 0;
iflag = 1;
while (p = *argv++) {
if (*p == '-') {
while (*++p) {
switch(*p) {
case 'k': case 'K': // include stack checking
stkchk = 1;
break;
case 'c': case 'C': // include C code in output
ctext = 1;
break;
case 'n': // do not print included files
iflag = 0;
break;
case 'i': // include file in output
case 'I':
strcpy(incname, ++p);
while (*p) p++;
p--;
break;
case 's': case 'S': // softstack setting
strcpy(line, ++p);
lptr = NegFlag = 0;
if (line[0])
number(&softstk);
while (*p) p++;
p--;
break;
case 'h': case 'H': // hardstack setting
strcpy(line, ++p);
lptr = NegFlag = 0;
if (line[0])
number(&hardstk);
while (*p) p++;
p--;
break;
case 'v': // assembler v setting
strcpy(line, ++p);
lptr = NegFlag = 0;
if (line[0])
number(&Vtype);
while (*p) p++;
p--;
break;
case 'a': case 'A': // assemble after compile
cflag = 1;
break;
case 'l': case 'L': // link after compile
lflag = 1;
break;
case 'd': case 'D': // define
bp = ++p;
if (!*p)
usage();
while (*p && *p != '=')
p++;
if (*p == '=')
*p = '\t';
while (*p)
p++;
p--;
defmac(bp);
break;
default:
usage();
}
}
}
else
break;
}
smacptr = macptr;
if (!p)
usage();
EndGlobal = ENDGLB;
EndLocal = ENDLOC;
while (p) {
errfile = 0;
if (xtypeof(p) == 'c') {
glbptr = STARTGLB;
locptr = STARTLOC;
wsptr = ws;
inclsp =
iflevel =
skiplevel =
swstp =
litptr =
stkp =
errcnt =
ncmp =
nflag =
lastst =
quote[1] =
0;
macptr = smacptr;
input2 = NULL;
quote[0] = '"';
cmode = 1;
glbflag = 1;
nxtlab = 0;
FPdef = 0;
litlab = getlabel();
// defmac("end\tmemory");
addglb("constant", VARIABLE, CINT, 0, AUTO, 0);
// addglb("stack", ARRAY, CCHAR, 0, EXTERN);
rglbptr = glbptr;
// addglb("etext", ARRAY, CCHAR, 0, EXTERN);
// addglb("edata", ARRAY, CCHAR, 0, EXTERN);
// defmac("short\tint");
// initmac();
/*
* compiler body
*/
if (stkchk)
readstkchk();
if (stkchk) {
if (hardstklimit == 0xffff || softstklimit == 0xffff) {
printf("Both stack limits must be set\n");
exit(1);
}
}
if (!openin(p))
return 1;
if (!openout())
return 1;
header();
// gtext();
// ol("ASEG");
// jmptable();
parse();
fclose(input);
dumplits();
DumpGlobalConstants();
gdata();
dumpglbs();
errorsummary();
trailer();
fclose(output);
pl("");
errs = errs || errfile;
ClearTable();
}
if (!errfile && cflag)
errs = errs || assemble(p);
p = *argv++;
}
if (!errs && lflag)
errs = errs || link();
exit(errs != 0);
}
void usage(void) {
fputs(version, stderr);
fputs("Usage: sccavr [-clank] [-hxxx] [-sxxx] [-dxxx] files\n", stderr);
fputs("where -c include C code\n", stderr);
fputs(" -n used with -c, do not print include files\n", stderr);
fputs(" -h(num> specify end of SRAM\n", stderr);
fputs(" -s<num> specify top of stack\n", stderr);
fputs(" -a run assembler after (aa90)\n", stderr);
fputs(" -l run linker after (xlink)\n", stderr);
fputs(" -i<name> include filename <name> as in include\n", stderr);
fputs(" -vn where n matches the processor (0,1,2,3)\n", stderr);
fputs(" -k use stack monitoring\n", stderr);
fputs(" -d<const> define a constant\n", stderr);
exit(1);
}
static void readstkchk(void) {
FILE *fd;
char myline[150], val[50];
char *p, *q;
int m;
if ((fd = fopen("sccavr.ini", "r")) != NULL) {
while (fgets(myline, 100, fd)) {
if ((p = strstr(myline, "=")) == NULL)
continue;
strncpy(val, myline, p - myline);
val[p-myline] = '\0';
strupr(val);
notrailers(val);
p++;
while (*p == ' ')
p++;
if (strcmp("HARDSTKLIMIT", val) == 0) {
strcpy(line, p);
lptr = 0;
if (!number(&m) || m < 0 || m > 0xffff) {
strcpy(line, myline);
error("Syntax error in ini, hard stack limit not legal");
exit(1);
}
hardstklimit = m;
}
else
if (strcmp("SOFTSTKLIMIT", val) == 0) {
strcpy(line, p);
lptr = 0;
if (!number(&m) || m < 0 || m > 0xffff) {
strcpy(line, myline);
error("Syntax error in ini, soft stack limit not legal");
exit(1);
}
softstklimit = m;
}
else
if (strcmp("STKERR", val) == 0) {
strcpy(myline, p);
q = strtok(myline, ",");
strcpy(line, q);
strupr(line);
notrailers(line);
if (!(strcmp(line, "PORTA") == 0 ||
strcmp(line, "PORTB") == 0 ||
strcmp(line, "PORTC") == 0 ||
strcmp(line, "PORTD") == 0 )) {
strcpy(line, myline);
error("Legal port defintions are PORTA, PORTB, PORTC or PORTD");
exit(1);
}
switch (line[4]) {
case 'A': StkErrPort = 0x1b; break;
case 'B': StkErrPort = 0x18; break;
case 'C': StkErrPort = 0x15; break;
case 'D': StkErrPort = 0x12;
}
strcpy(line, strtok(0, ","));
lptr = 0;
if (!number(&m) || m < 0 || m > 7) {
strcpy(line, myline);
error("Legal error port bits are 7-0");
exit(1);
}
StkErrBit[0] = 1<<m;
strcpy(line, strtok(0, ","));
lptr = 0;
if (!number(&m) || m < 0 || m > 7) {
strcpy(line, myline);
error("Legal error port bits are 7-0");
exit(1);
}
StkErrBit[1] = 1<<m;
}
}
fclose(fd);
}
}
static void notrailers(char *val) {
char *q;
q = val + strlen(val)-1;
while (*q == ' ')
q--;
*(q+1) = '\0';
}
void FEvers(void) {
outstr(version);
printf("%s", version);
}
/*
* process all input text
*
* at this level, only static declarations, defines, includes,
* and function definitions are legal.
*
*/
void parse(void) {
while (!feof(input)) {
if (match("//"))
while (ch())
lptr++;
else
if (amatch("extern"))
dodcls(EXTERN);
else
if (amatch("static"))
dodcls(STATIC);
else
if (amatch("interrupt"))
dodcls(INTERRUPT);
else
if (dodcls(PUBLIC))
;
else
if (match("#asm"))
doasm();
else
if (match("#include"))
doinclude();
else
if (match("#define"))
dodefine();
else
if (match("#undef"))
doundef();
else
if (match("register"))
error("Global register variables not supported");
else
newfunc();
blanks();
}
}
// Parse top level declarations
int dodcls(int stclass) {
int ret;
int Unsigned;
char *p1, *p2;
blanks();
match("const");
Unsigned = 0;
if (amatch("unsigned")) {
Unsigned = 1;
if (!(testmatch("int") || testmatch("long") || testmatch("char"))) {
p1 = &line[strlen(line)+4];
p2 = &line[strlen(line)-1];
*p1-- = '\0';
while (p2 != &line[lptr]-1) {
*p1-- = *p2--;
}
*p1-- = ' ';
*p1-- = 't';
*p1-- = 'n';
*p1-- = 'i';
}
}
if (stclass == INTERRUPT) {
if (amatch("char") || amatch("int") || amatch("long") || amatch("struct") || amatch("void"))
error("Interrupt function cannot have a class");
else
ret = declglb(CINT, stclass);
}
else {
TypeDef = 0;
if (amatch("typedef"))
TypeDef = 1;
if (amatch("char")) {
if (Unsigned)
ret = declglb(UCCHAR, stclass);
else
ret = declglb(CCHAR, stclass);
}
else
if (amatch("int")) {
if (Unsigned)
ret = declglb(UCINT, stclass);
else
ret = declglb(CINT, stclass);
}
else
if (amatch("long"))
ret = declglb(CLONG, stclass);
else
if (amatch("struct"))
ret = GlobalStructure(stclass);
else
if (amatch("void"))
ret = declglb(VOID, stclass);
else
if (FindTypeDef())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -