Mercurial > ~dholland > hg > ag > index.cgi
diff anagram/agcore/sums.syn @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/anagram/agcore/sums.syn Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,168 @@ +{ +/* + * AnaGram, A System for Syntax Directed Programming + * Copyright 1993-2002 Parsifal Software. All Rights Reserved. + * Copyright 2006 David A. Holland. All Rights Reserved. + * See the file COPYING for license and usage terms. + * + * sums.syn - read checksum and build information + */ + +#include "port.h" + +#include "agstack.h" +#include "agstring.h" +#include "build.h" +#include "checksum.h" +#include "sums-defs.h" + +//#define INCLUDE_LOGGING +#include "log.h" +} + +[ + //pointer input + event driven + parser name = parseSumData + parser file name = "#.cpp" + line numbers path = "sumparse.syn" +] + +eof = 0 +digit = '0-9' +ascii = 32..126 + +(void) inserted data $ + -> checksum data, build date, build os, eof + +(void) build date + -> "Build date:", text, '\n' = build_date = stringbuf; + +(void) build os + -> "Build OS:", text, '\n' = build_os = stringbuf; + +(void) checksum data + -> "Checksum data:\n", sum entry?... + +(void) sum entry + -> summable:w, '=', length:l, ',', sum:s, offset:o, '\n' = addsum(w,l,s,o); + +(summable) summable + -> "ag1" = SUM_AG1; + -> "ag" = SUM_AG; + -> "agcl" = SUM_AGCL; + +(unsigned long) length + -> integer:i = i; + +(unsigned long) sum + -> integer:i = i; + +(unsigned long) offset + -> = 0; + -> '@', integer:i = i; + +(unsigned long) integer + -> digit:d = d - '0'; + -> integer:i, digit:d = 10*i + d - '0'; + +(void) text + -> ascii:c = startstring(c); + -> text, ascii:c = addstring(c); + +{ +#define SYNTAX_ERROR {\ + char buf[500];\ + sprintf(buf,"%s, line %d, column %d\n", \ + (PCB).error_message, (PCB).line, (PCB).column);\ + LOGV(buf);\ +} + + /* note - cannot compute skiplen at runtime */ + static char sumInfo[512] = "Checksum data:\n"; + static const size_t skiplen = 15; /* length of "Checksum data:\n" */ + + static AgStack<sumentry> sums; + + static char stringbuf[128]; + static size_t stringbufpos; + + AgString build_date, build_os; + + static void addstring(int ch) { + if (stringbufpos < sizeof(stringbuf)-1) { + stringbuf[stringbufpos++] = ch; + stringbuf[stringbufpos] = 0; + } + } + + static void startstring(int ch) { + stringbufpos = 0; + addstring(ch); + } + + static void addsum(summable what, unsigned long len, unsigned long sum, + unsigned long offset) { + sumentry se; + se.what = what; + se.offset = offset; + se.correct.length = len; + se.correct.sum = sum; + se.observed.length = 0; + se.observed.sum = 0; + sums.push(se); + } + + const char *checksums_ok(void) { + LOGSECTION("checksums_ok"); + + char *p = sumInfo; + size_t i; + + init_parseSumData(); + + for (i=0; i<sizeof(sumInfo); i++) { + unsigned char c = (unsigned char)p[i]; + if (i >= skiplen) { + c ^= PADBYTE; + } + //LOGV(c) + PCB.input_code = c; + if (PCB.exit_flag == AG_RUNNING_CODE) parseSumData(); + if (c == 0) break; + } + + if (PCB.exit_flag != AG_SUCCESS_CODE) { + LOGV(PCB.exit_flag); + return "Parse error in checksum data"; + } + + if (sums.size() == 0) { + LOGS("no sums"); + return "Checksum data empty"; + } + + for (i=0; i<sums.size(); i++) { + observeSum(&sums[i]); + } + + for (i=0; i<sums.size(); i++) { + LOGV(sums[i].what) LCV(sums[i].offset); + LOGV(sums[i].correct.length) LCV(sums[i].correct.sum); + LOGV(sums[i].observed.length) LCV(sums[i].observed.sum); + + if (sums[i].observed != sums[i].correct) { + switch (sums[i].what) { + case SUM_AG1: return "Bad checksum for ag1 shared library"; + case SUM_AG: return "Bad checksum for ag executable"; + case SUM_AGCL: return "Bad checksum for agcl executable"; + } + // this shouldn't happen + return "Bad checksum for unknown object (?)"; + } + } + + // ok + return NULL; + } +}