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;
+  }
+}