utility.cpp

来自「一个面向对像语言的编译器」· C++ 代码 · 共 127 行

CPP
127
字号
/*
 * File: utiliy.cc
 * ---------------
 * Some of this code is based on code from Eric Roberts' cslib libraries.
 */

#include "utility.h"
#include <stdarg.h>
#include <string.h>
#include "scanner.h"
#include "parser.h" // for struct yyltype
#define BufferSize   2048
int numErrors = 0;

static void UnderlineErrorInLine(const char *line, struct yyltype *pos);
  
void ReportError(struct yyltype *pos, const char *format, ...)
{
  va_list args;
  char errbuf[BufferSize];
  
  numErrors++;
  va_start(args, format);
  vsprintf(errbuf,format, args);
  va_end(args);
  if (strlen(errbuf) > BufferSize) {
    Failure("Error message too long\n");
  } else {
    fflush(stdout); // make sure any buffered text has been output
    if (pos) {
      fprintf(stderr,"\n*** Error line %d.\n", pos->first_line);
      UnderlineErrorInLine(GetLineNumbered(pos->first_line), pos);
    }
    fprintf(stderr,"*** %s\n\n", errbuf);
  }
}


// Map standard yacc error function to ours
void yyerror(char *msg)
{
  ReportError(&yylloc, "%s", msg);
}

static void UnderlineErrorInLine(const char *line, struct yyltype *pos)
{
  if (!line) return;
  fprintf(stderr, "%s\n", line);
  for (int i = 1; i <= pos->last_column; i++)
    fprintf(stderr, "%c", i >= pos->first_column ? '^' : ' ');
  fprintf(stderr, "\n");
}

void Failure(const char *format, ...)
{
  va_list args;
  char errbuf[BufferSize];
  
  va_start(args, format);
  vsprintf(errbuf, format, args);
  va_end(args);
  fflush(stdout);
  if (strlen(errbuf) > BufferSize) 
    fprintf(stderr, "\n*** Failure: Failure message too long\n\n");
  else 
    fprintf(stderr,"\n*** Failure: %s\n\n", errbuf);
  exit(1);
}



#define MaxDebugKeys 256

static char *gDebugKeys[MaxDebugKeys];
static int gNumDebugKeys = 0;
static const int NotFound = -1;

static int FindKeyInList(const char *key)
{
  int i;
  for (i = 0; i < gNumDebugKeys; i++) 
    if (strcmp(key, gDebugKeys[i]) == 0)
      return i;
  return NotFound;
}

bool IsDebugOn(const char *key)
{
   return (FindKeyInList(key) != NotFound);
}


void SetDebugForKey(const char *key, bool value)
{
  int pos = FindKeyInList(key);

  if (value) {
    if (pos != NotFound)
	return;
    Assert(gNumDebugKeys < MaxDebugKeys - 1);
    gDebugKeys[gNumDebugKeys++] = strdup(key);
  } else {
    if (pos == NotFound)
	return;
    gDebugKeys[pos] = "";
  }
}



void PrintDebug(const char *key, const char *format, ...)
{
  va_list args;
  char buf[BufferSize];

  if (!IsDebugOn(key))
     return;
  
  va_start(args, format);
  vsprintf(buf, format, args);
  va_end(args);
  if (strlen(buf) > BufferSize) 
    Failure("PrintDebug message too long\n");
  else
    printf("+++ (%s): %s%s", key, buf, buf[strlen(buf)-1] != '\n'? "\n" : "");
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?