view anagram/agcore/sums.syn @ 1:60d3ca9d3f6b

Fix stupid bug in help2html.
author David A. Holland
date Tue, 12 Aug 2008 00:13:42 -0400
parents 13d2b8934445
children
line wrap: on
line source

{
/*
 * 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;
  }
}