1/*****************************************************************************/
2/* */
3/* asserts.c */
4/* */
5/* Assertions for the ld65 linker */
6/* */
7/* */
8/* */
9/* (C) 2003-2011, Ullrich von Bassewitz */
10/* Roemerstrasse 52 */
11/* D-70794 Filderstadt */
12/* EMail: uz@cc65.org */
13/* */
14/* */
15/* This software is provided 'as-is', without any expressed or implied */
16/* warranty. In no event will the authors be held liable for any damages */
17/* arising from the use of this software. */
18/* */
19/* Permission is granted to anyone to use this software for any purpose, */
20/* including commercial applications, and to alter it and redistribute it */
21/* freely, subject to the following restrictions: */
22/* */
23/* 1. The origin of this software must not be misrepresented; you must not */
24/* claim that you wrote the original software. If you use this software */
25/* in a product, an acknowledgment in the product documentation would be */
26/* appreciated but is not required. */
27/* 2. Altered source versions must be plainly marked as such, and must not */
28/* be misrepresented as being the original software. */
29/* 3. This notice may not be removed or altered from any source */
30/* distribution. */
31/* */
32/*****************************************************************************/
33
34
35
36/* common */
37#include "assertion.h"
38#include "coll.h"
39#include "xmalloc.h"
40
41/* ld65 */
42#include "asserts.h"
43#include "error.h"
44#include "expr.h"
45#include "fileio.h"
46#include "lineinfo.h"
47#include "objdata.h"
48#include "spool.h"
49
50
51
52/*****************************************************************************/
53/* Data */
54/*****************************************************************************/
55
56
57
58/* Assertion struct decl */
59struct Assertion {
60 Collection LineInfos; /* File position of assertion */
61 ExprNode* Expr; /* Expression to evaluate */
62 AssertAction Action; /* What to do */
63 unsigned Msg; /* Message to print */
64 ObjData* Obj; /* Object file containing the assertion */
65};
66
67/* List with all assertions */
68static Collection Assertions = STATIC_COLLECTION_INITIALIZER;
69
70
71
72/*****************************************************************************/
73/* Code */
74/*****************************************************************************/
75
76
77
78Assertion* ReadAssertion (FILE* F, struct ObjData* O)
79/* Read an assertion from the given file */
80{
81 /* Allocate memory */
82 Assertion* A = xmalloc (sizeof (Assertion));
83
84 /* Read the fields from the file */
85 A->LineInfos = EmptyCollection;
86 A->Expr = ReadExpr (F, O);
87 A->Action = (AssertAction) ReadVar (F);
88 A->Msg = MakeGlobalStringId (O, ReadVar (F));
89 ReadLineInfoList (F, O, &A->LineInfos);
90
91 /* Set remaining fields */
92 A->Obj = O;
93
94 /* Add the assertion to the global list */
95 CollAppend (&Assertions, A);
96
97 /* Return the new struct */
98 return A;
99}
100
101
102
103void CheckAssertions (void)
104/* Check all assertions */
105{
106 unsigned I;
107
108 /* Walk over all assertions */
109 for (I = 0; I < CollCount (&Assertions); ++I) {
110
111 const LineInfo* LI;
112 const char* Module;
113 unsigned Line;
114
115 /* Get the assertion */
116 Assertion* A = CollAtUnchecked (&Assertions, I);
117
118 /* Ignore assertions that shouldn't be handled at link time */
119 if (!AssertAtLinkTime (A->Action)) {
120 continue;
121 }
122
123 /* Retrieve the relevant line info for this assertion */
124 LI = CollConstAt (&A->LineInfos, 0);
125
126 /* Get file name and line number from the source */
127 Module = GetSourceName (LI);
128 Line = GetSourceLine (LI);
129
130 /* If the expression is not constant, we're not able to handle it */
131 if (!IsConstExpr (A->Expr)) {
132 Warning ("Cannot evaluate assertion in module '%s', line %u",
133 Module, Line);
134 } else if (GetExprVal (A->Expr) == 0) {
135
136 /* Assertion failed */
137 const char* Message = GetString (A->Msg);
138
139 switch (A->Action) {
140
141 case ASSERT_ACT_WARN:
142 case ASSERT_ACT_LDWARN:
143 Warning ("%s(%u): %s", Module, Line, Message);
144 break;
145
146 case ASSERT_ACT_ERROR:
147 case ASSERT_ACT_LDERROR:
148 Error ("%s(%u): %s", Module, Line, Message);
149 break;
150
151 default:
152 Internal ("Invalid assertion action (%u) in module '%s', "
153 "line %u (file corrupt?)",
154 A->Action, Module, Line);
155 break;
156 }
157 }
158 }
159}
160