1/*****************************************************************************/
2/* */
3/* asserts.c */
4/* */
5/* Linker assertions for the ca65 crossassembler */
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 "coll.h"
38#include "xmalloc.h"
39
40/* ca65 */
41#include "asserts.h"
42#include "error.h"
43#include "expr.h"
44#include "lineinfo.h"
45#include "objfile.h"
46#include "spool.h"
47
48
49
50/*****************************************************************************/
51/* Data */
52/*****************************************************************************/
53
54
55
56/* An assertion entry */
57typedef struct Assertion Assertion;
58struct Assertion {
59 ExprNode* Expr; /* Expression to evaluate */
60 AssertAction Action; /* Action to take */
61 unsigned Msg; /* Message to print (if any) */
62 Collection LI; /* Line infos for the assertion */
63};
64
65/* Collection with all assertions for a module */
66static Collection Assertions = STATIC_COLLECTION_INITIALIZER;
67
68
69
70/*****************************************************************************/
71/* Code */
72/*****************************************************************************/
73
74
75
76static Assertion* NewAssertion (ExprNode* Expr, AssertAction Action, unsigned Msg)
77/* Create a new Assertion struct and return it */
78{
79 /* Allocate memory */
80 Assertion* A = xmalloc (sizeof (Assertion));
81
82 /* Initialize the fields */
83 A->Expr = Expr;
84 A->Action = Action;
85 A->Msg = Msg;
86 A->LI = EmptyCollection;
87 GetFullLineInfo (&A->LI);
88
89 /* Return the new struct */
90 return A;
91}
92
93
94
95void AddAssertion (ExprNode* Expr, AssertAction Action, unsigned Msg)
96/* Add an assertion to the assertion table */
97{
98 /* Add an assertion object to the table */
99 CollAppend (&Assertions, NewAssertion (Expr, Action, Msg));
100}
101
102
103
104void CheckAssertions (void)
105/* Check all assertions and evaluate the ones we can evaluate here. */
106{
107 unsigned I;
108
109 /* Get the number of assertions */
110 unsigned Count = CollCount (&Assertions);
111
112 /* Check the assertions */
113 for (I = 0; I < Count; ++I) {
114
115 long Val;
116
117 /* Get the next assertion */
118 Assertion* A = CollAtUnchecked (&Assertions, I);
119
120 /* Ignore it, if it should only be evaluated by the linker */
121 if (!AssertAtAsmTime (A->Action)) {
122 continue;
123 }
124
125 /* Can we evaluate the expression? */
126 if (IsConstExpr (A->Expr, &Val) && Val == 0) {
127 /* Apply the action */
128 const char* Msg = GetString (A->Msg);
129 switch (A->Action) {
130
131 case ASSERT_ACT_WARN:
132 LIWarning (&A->LI, 0, "%s", Msg);
133 break;
134
135 case ASSERT_ACT_ERROR:
136 LIError (&A->LI, "%s", Msg);
137 break;
138
139 default:
140 Internal ("Illegal assert action specifier");
141 break;
142 }
143 }
144 }
145}
146
147
148
149void WriteAssertions (void)
150/* Write the assertion table to the object file */
151{
152 unsigned I;
153
154 /* Get the number of assertions */
155 unsigned Count = CollCount (&Assertions);
156
157 /* Tell the object file module that we're about to start the assertions */
158 ObjStartAssertions ();
159
160 /* Write the string count to the list */
161 ObjWriteVar (Count);
162
163 /* Write the assertions */
164 for (I = 0; I < Count; ++I) {
165
166 /* Get the next assertion */
167 Assertion* A = CollAtUnchecked (&Assertions, I);
168
169 /* Write it to the file */
170 WriteExpr (A->Expr);
171 ObjWriteVar ((unsigned) A->Action);
172 ObjWriteVar (A->Msg);
173 WriteLineInfo (&A->LI);
174 }
175
176 /* Done writing the assertions */
177 ObjEndAssertions ();
178}
179