add some hacky code to allow passing sfc files with -b
[openc2e.git] / exceptions.cpp
blob6c27e67e1b7737695493ae75418d40258001e367
1 /*
2 * exceptions.cpp
3 * openc2e
5 * Created by Bryan Donlan on Sun 22 Jan 2006.
6 * Copyright (c) 2006 Bryan Donlan. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
19 #include "exceptions.h"
20 #include "bytecode.h"
21 #include "token.h"
22 #include "caosScript.h"
24 std::string parseFailure::prettyPrint() const {
25 std::ostringstream oss;
26 std::string filename = this->filename;
27 if (filename == "")
28 filename = std::string("(UNKNOWN)");
29 oss << "Parse error at line ";
30 if (lineno == -1)
31 oss << "(UNKNOWN)";
32 else
33 oss << lineno;
34 oss << " in file " << filename << ": " << what();
35 if (!context)
36 oss << std::endl;
37 else {
38 oss << " near:" << std::endl;
39 int toklen = -1, stlen = 0;
40 for (size_t i = 0; i < context->size(); i++) {
41 std::string tokstr = (*context)[i].format();
42 if (i == (size_t)ctxoffset) {
43 toklen = tokstr.size();
44 } else if (toklen == -1) {
45 stlen += tokstr.size() + 1;
47 oss << tokstr << " ";
49 oss << std::endl;
50 if (toklen != -1) {
51 for (int i = 0; i < stlen; i++)
52 oss << " ";
53 for (int i = 0; i < toklen; i++)
54 oss << "^";
55 oss << std::endl;
58 return oss.str();
61 void caosException::trace(boost::shared_ptr<class script> scr, int traceindex) throw() {
62 this->script = scr;
63 this->traceindex = traceindex;
66 std::string caosException::prettyPrint() const {
67 std::ostringstream oss;
68 oss << what() << std::endl;
69 if (!script) return oss.str() + "Source information unavailable.\n";
70 oss << "in file " << script->filename;
71 if (traceindex < 0 || (size_t)traceindex >= script->tokinfo->size()) {
72 oss << std::endl;
73 return oss.str();
75 toktrace tr = (*script->tokinfo)[traceindex];
76 oss << " near line " << tr.lineno;
78 int start = 0;
79 for (int i = 0; i < traceindex; i++) {
80 start += (*script->tokinfo)[i].width + 1;
82 int end = start + tr.width;
83 if ((size_t)start >= script->code->size() || (size_t)end >= script->code->size()) {
84 oss << std::endl;
85 return oss.str();
87 oss << ":" << std::endl;
89 int linelen = 73; // XXX, margins aren't being counted it seems
90 int contextl = (linelen - tr.width) / 2;
91 int contextr = linelen - contextl;
92 int marginl = 0;
93 int marginr = 0;
95 if (linelen <= tr.width) {
96 contextl = contextr = 0;
99 if (contextl > start) {
100 contextr += contextl - start;
101 contextl = start;
104 if ((size_t)(end + contextr) >= script->code->size()) {
105 int overflow = end + contextr - script->code->size();
106 contextr -= overflow;
107 contextl += overflow;
108 if (contextl > start)
109 contextl = start;
112 if (contextl < start) {
113 marginl = 3;
114 oss << "...";
115 contextl -= 3;
116 if (contextl < 0) {
117 contextr += contextl;
118 contextl = 0;
120 if (contextr < 0)
121 contextr = 0;
124 if ((size_t)(end + contextr) < script->code->size()) {
125 marginr = 3;
126 contextr -= 3;
127 if (contextr < 0) {
128 contextl += contextr;
129 contextr = 0;
130 if (contextl < 0)
131 contextl = 0;
135 for (int i = start - contextl; i < end + contextr; i++)
136 oss << (*script->code)[i];
137 if (marginr)
138 oss << "...";
139 oss << std::endl;
141 for (int i = 0; i < contextl + marginl; i++)
142 oss << " ";
143 for (int i = 0; i < tr.width; i++)
144 oss << "^";
145 oss << std::endl;
146 return oss.str();