~ubuntu-branches/ubuntu/hardy/codeblocks/hardy-backports

« back to all changes in this revision

Viewing changes to src/sdk/scripting/sqplus/SqPlus.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Casadevall
  • Date: 2008-07-17 04:39:23 UTC
  • Revision ID: james.westby@ubuntu.com-20080717043923-gmsy5cwkdjswghkm
Tags: upstream-8.02
ImportĀ upstreamĀ versionĀ 8.02

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "sqplus.h"
 
2
#include <stdio.h>
 
3
 
 
4
namespace SqPlus {
 
5
 
 
6
static SQInteger getVarInfo(StackHandler & sa,VarRefPtr & vr) {
 
7
  HSQOBJECT htable = sa.GetObjectHandle(1);
 
8
  SquirrelObject table(htable);
 
9
#ifdef _DEBUG
 
10
  SQObjectType type = (SQObjectType)sa.GetType(2);
 
11
#endif
 
12
  const SQChar * el = sa.GetString(2);
 
13
  ScriptStringVar256 varNameTag;
 
14
  getVarNameTag(varNameTag,sizeof(varNameTag),el);
 
15
  SQUserPointer data=0;
 
16
  if (!table.RawGetUserData(varNameTag,&data)) {
 
17
//    throw SquirrelError("getVarInfo: Could not retrieve UserData");
 
18
    return sa.ThrowError(sqT("getVarInfo: Could not retrieve UserData")); // Results in variable not being found error.
 
19
  } // if
 
20
  vr = (VarRefPtr)data;
 
21
  return SQ_OK;
 
22
} // getVarInfo
 
23
 
 
24
static SQInteger getInstanceVarInfo(StackHandler & sa,VarRefPtr & vr,SQUserPointer & data) {
 
25
  HSQOBJECT ho = sa.GetObjectHandle(1);
 
26
  SquirrelObject instance(ho);
 
27
#ifdef _DEBUG
 
28
  SQObjectType type = (SQObjectType)sa.GetType(2);
 
29
#endif
 
30
  const SQChar * el = sa.GetString(2);
 
31
  ScriptStringVar256 varNameTag;
 
32
  getVarNameTag(varNameTag,sizeof(varNameTag),el);
 
33
  SQUserPointer ivrData=0;
 
34
  if (!instance.RawGetUserData(varNameTag,&ivrData)) {
 
35
//    throw SquirrelError("getInstanceVarInfo: Could not retrieve UserData");
 
36
    return sa.ThrowError(sqT("getInstanceVarInfo: Could not retrieve UserData")); // Results in variable not being found error.
 
37
  } // if
 
38
  vr = (VarRefPtr)ivrData;
 
39
  unsigned char * up;
 
40
  if (!(vr->access & (VAR_ACCESS_STATIC|VAR_ACCESS_CONSTANT))) {
 
41
#ifdef SQ_USE_CLASS_INHERITANCE
 
42
    SQUserPointer typetag; instance.GetTypeTag(&typetag);
 
43
    if (typetag != vr->instanceType) {
 
44
      SquirrelObject typeTable = instance.GetValue(SQ_CLASS_OBJECT_TABLE_NAME);
 
45
      up = (unsigned char *)typeTable.GetUserPointer(INT((size_t)vr->instanceType)); // <TODO> 64-bit compatible version.
 
46
      if (!up) {
 
47
        throw SquirrelError(sqT("Invalid Instance Type"));
 
48
      } // if
 
49
    } else {
 
50
      up = (unsigned char *)instance.GetInstanceUP(0);
 
51
    } // if
 
52
#else
 
53
    up = (unsigned char *)instance.GetInstanceUP(0);
 
54
#endif
 
55
    up += (size_t)vr->offsetOrAddrOrConst;         // Offset
 
56
  } else {
 
57
    up = (unsigned char *)vr->offsetOrAddrOrConst; // Address
 
58
  } // if
 
59
  data = up;
 
60
  return SQ_OK;
 
61
} // getInstanceVarInfo
 
62
 
 
63
static SQInteger setVar(StackHandler & sa,VarRef * vr,void * data) {
 
64
  if (vr->access & (VAR_ACCESS_READ_ONLY|VAR_ACCESS_CONSTANT)) {
 
65
    ScriptStringVar256 msg;
 
66
    const SQChar * el = sa.GetString(2);
 
67
    SCSNPRINTF(msg.s,sizeof(msg),sqT("setVar(): Cannot write to constant: %s"),el);
 
68
    throw SquirrelError(msg.s);
 
69
  } // if
 
70
  switch (vr->type) {
 
71
  case TypeInfo<INT>::TypeID: {
 
72
    INT * val = (INT *)data; // Address
 
73
    if (val) {
 
74
      *val = sa.GetInt(3);
 
75
      return sa.Return(*val);
 
76
    } // if
 
77
    break;
 
78
  } // case
 
79
  case TypeInfo<FLOAT>::TypeID: {
 
80
    FLOAT * val = (FLOAT *)data; // Address
 
81
    if (val) {
 
82
      *val = sa.GetFloat(3);
 
83
      return sa.Return(*val);
 
84
    } // if
 
85
    break;
 
86
  } // case
 
87
  case TypeInfo<bool>::TypeID: {
 
88
    bool * val = (bool *)data; // Address
 
89
    if (val) {
 
90
      *val = sa.GetBool(3) ? true : false;
 
91
      return sa.Return(*val);
 
92
    } // if
 
93
    break;
 
94
  } // case
 
95
  case VAR_TYPE_INSTANCE: {
 
96
    // C::B patch: Comment out unused variable
 
97
    //HSQUIRRELVM v = sa.GetVMPtr();
 
98
    // vr->copyFunc is the LHS variable type: the RHS var's type is ClassType<>::type() (both point to ClassType<>::copy()).
 
99
    // src will be null if the LHS and RHS types don't match.
 
100
    SQUserPointer src = sa.GetInstanceUp(3,(SQUserPointer)vr->copyFunc); // Effectively performs: ClassType<>::type() == ClassType<>getCopyFunc().
 
101
    if (!src) throw SquirrelError(sqT("INSTANCE type assignment mismatch"));
 
102
    vr->copyFunc(data,src);
 
103
#if 0 // Return an instance on the stack (allocates memory)
 
104
    if (!CreateNativeClassInstance(sa.GetVMPtr(),vr->typeName,data,0)) { // data = address
 
105
      ScriptStringVar256 msg;
 
106
      SCSNPRINTF(msg.s,sizeof(msg),sqT("getVar(): Could not create instance: %s"),vr->typeName);
 
107
      throw SquirrelError(msg.s);
 
108
    } // if
 
109
    return 1;
 
110
#else // Don't return on stack.
 
111
    return 0;
 
112
#endif
 
113
  }
 
114
  case TypeInfo<SQUserPointer>::TypeID: {
 
115
    ScriptStringVar256 msg;
 
116
    const SQChar * el = sa.GetString(2);
 
117
    SCSNPRINTF(msg.s,sizeof(msg),sqT("setVar(): Cannot write to an SQUserPointer: %s"),el);
 
118
    throw SquirrelError(msg.s);
 
119
  } // case
 
120
  case TypeInfo<ScriptStringVarBase>::TypeID: {
 
121
    ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address
 
122
    if (val) {
 
123
      const SQChar * strVal = sa.GetString(3);
 
124
      if (strVal) {
 
125
        *val = strVal;
 
126
        return sa.Return(val->s);
 
127
      } // if
 
128
    } // if
 
129
    break;
 
130
  } // case
 
131
  // C::B patch: Handle all switch cases
 
132
  default: break;
 
133
  } // switch
 
134
  return SQ_ERROR;
 
135
} // setVar
 
136
 
 
137
static SQInteger getVar(StackHandler & sa,VarRef * vr,void * data) {
 
138
  switch (vr->type) {
 
139
  case TypeInfo<INT>::TypeID: {
 
140
    if (!(vr->access & VAR_ACCESS_CONSTANT)) {
 
141
      INT * val = (INT *)data; // Address
 
142
      if (val) {
 
143
        return sa.Return(*val);
 
144
      } // if
 
145
    } else {
 
146
      INT * val = (INT *)&data; // Constant value
 
147
      return sa.Return(*val);
 
148
    } // if
 
149
    break;
 
150
  } // case
 
151
  case TypeInfo<FLOAT>::TypeID: {
 
152
    if (!(vr->access & VAR_ACCESS_CONSTANT)) {
 
153
      FLOAT * val = (FLOAT *)data; // Address
 
154
      if (val) {
 
155
        return sa.Return(*val);
 
156
      } // if
 
157
    } else {
 
158
      FLOAT * val = (FLOAT *)&data; // Constant value
 
159
      return sa.Return(*val);
 
160
    } // if
 
161
    break;
 
162
  } // case
 
163
  case TypeInfo<bool>::TypeID: {
 
164
    if (!(vr->access & VAR_ACCESS_CONSTANT)) {
 
165
      bool * val = (bool *)data; // Address
 
166
      if (val) {
 
167
        return sa.Return(*val);
 
168
      } // if
 
169
    } else {
 
170
      bool * val = (bool *)&data; // Constant value
 
171
      return sa.Return(*val);
 
172
    } // if
 
173
    break;
 
174
  } // case
 
175
  case VAR_TYPE_INSTANCE:
 
176
    if (!CreateNativeClassInstance(sa.GetVMPtr(),vr->typeName,data,0)) { // data = address. Allocates memory.
 
177
      ScriptStringVar256 msg;
 
178
      SCSNPRINTF(msg.s,sizeof(msg),sqT("getVar(): Could not create instance: %s"),vr->typeName);
 
179
      throw SquirrelError(msg.s);
 
180
    } // if
 
181
    return 1;
 
182
  case TypeInfo<SQUserPointer>::TypeID: {
 
183
    return sa.Return(data); // The address of member variable, not the variable itself.
 
184
  } // case
 
185
  case TypeInfo<ScriptStringVarBase>::TypeID: {
 
186
    if (!(vr->access & VAR_ACCESS_CONSTANT)) {
 
187
      ScriptStringVarBase * val = (ScriptStringVarBase *)data; // Address
 
188
      if (val) {
 
189
        return sa.Return(val->s);
 
190
      } // if
 
191
    } else {
 
192
      throw SquirrelError(sqT("getVar(): Invalid type+access: 'ScriptStringVarBase' with VAR_ACCESS_CONSTANT (use VAR_ACCESS_READ_ONLY instead)"));
 
193
    } // if
 
194
    break;
 
195
  } // case
 
196
  case TypeInfo<const SQChar *>::TypeID: {
 
197
    if (!(vr->access & VAR_ACCESS_CONSTANT)) {
 
198
      throw SquirrelError(sqT("getVar(): Invalid type+access: 'const SQChar *' without VAR_ACCESS_CONSTANT"));
 
199
    } else {
 
200
      return sa.Return((const SQChar *)data); // Address
 
201
    } // if
 
202
    break;
 
203
  } // case
 
204
  // C::B patch: Handle all switch cases
 
205
  default: break;
 
206
  } // switch
 
207
  return SQ_ERROR;
 
208
} // getVar
 
209
 
 
210
// === Global Vars ===
 
211
 
 
212
SQInteger setVarFunc(HSQUIRRELVM v) {
 
213
  StackHandler sa(v);
 
214
  if (sa.GetType(1) == OT_TABLE) {
 
215
    VarRefPtr vr;
 
216
    SQInteger res = getVarInfo(sa,vr);
 
217
    if (res != SQ_OK) return res;
 
218
    return setVar(sa,vr,vr->offsetOrAddrOrConst);
 
219
  } // if
 
220
  return SQ_ERROR;
 
221
} // setVarFunc
 
222
 
 
223
SQInteger getVarFunc(HSQUIRRELVM v) {
 
224
  StackHandler sa(v);
 
225
  if (sa.GetType(1) == OT_TABLE) {
 
226
    VarRefPtr vr;
 
227
    SQInteger res = getVarInfo(sa,vr);
 
228
    if (res != SQ_OK) return res;
 
229
    return getVar(sa,vr,vr->offsetOrAddrOrConst);
 
230
  } // if
 
231
  return SQ_ERROR;
 
232
} // getVarFunc
 
233
 
 
234
// === Instance Vars ===
 
235
 
 
236
SQInteger setInstanceVarFunc(HSQUIRRELVM v) {
 
237
  StackHandler sa(v);
 
238
  if (sa.GetType(1) == OT_INSTANCE) {
 
239
    VarRefPtr vr;
 
240
    void * data;
 
241
    SQInteger res = getInstanceVarInfo(sa,vr,data);
 
242
    if (res != SQ_OK) return res;
 
243
    return setVar(sa,vr,data);
 
244
  } // if
 
245
  return SQ_ERROR;
 
246
} // setInstanceVarFunc
 
247
 
 
248
SQInteger getInstanceVarFunc(HSQUIRRELVM v) {
 
249
  StackHandler sa(v);
 
250
  if (sa.GetType(1) == OT_INSTANCE) {
 
251
    VarRefPtr vr;
 
252
    void * data;
 
253
    SQInteger res = getInstanceVarInfo(sa,vr,data);
 
254
    if (res != SQ_OK) return res;
 
255
    return getVar(sa,vr,data);
 
256
  } // if
 
257
  return SQ_ERROR;
 
258
} // getInstanceVarFunc
 
259
 
 
260
// === Classes ===
 
261
 
 
262
BOOL CreateClass(HSQUIRRELVM v,SquirrelObject & newClass,SQUserPointer classType,const SQChar * name,const SQChar * baseName) {
 
263
  // C::B patch: Comment out unused variable
 
264
  //SQInteger n = 0;
 
265
  SQInteger oldtop = sq_gettop(v);
 
266
  sq_pushroottable(v);
 
267
  sq_pushstring(v,name,-1);
 
268
  if (baseName) {
 
269
    sq_pushstring(v,baseName,-1);
 
270
    if (SQ_FAILED(sq_get(v,-3))) { // Make sure the base exists if specified by baseName.
 
271
      sq_settop(v,oldtop);
 
272
      return FALSE;
 
273
    } // if
 
274
  } // if
 
275
  if (SQ_FAILED(sq_newclass(v,baseName ? 1 : 0))) { // Will inherit from base class on stack from sq_get() above.
 
276
    sq_settop(v,oldtop);
 
277
    return FALSE;
 
278
  } // if
 
279
  newClass.AttachToStackObject(-1);
 
280
  sq_settypetag(v,-1,classType);
 
281
  sq_createslot(v,-3);
 
282
  sq_pop(v,1);
 
283
  return TRUE;
 
284
} // CreateClass
 
285
 
 
286
SquirrelObject RegisterClassType(HSQUIRRELVM v,const SQChar * scriptClassName,SQUserPointer classType,SQFUNCTION constructor) {
 
287
  SQInteger top = sq_gettop(v);
 
288
  SquirrelObject newClass;
 
289
  if (CreateClass(v,newClass,classType,scriptClassName)) {
 
290
    SquirrelVM::CreateFunction(newClass,constructor,sqT("constructor"));
 
291
  } // if
 
292
  sq_settop(v,top);
 
293
  return newClass;
 
294
} // RegisterClassType
 
295
 
 
296
}; // namespace SqPlus
 
297
 
 
298
// sqPlus