]> de.git.xonotic.org Git - voretournament/voretournament.git/blob - misc/mediasource/extra/fteqcc-src/initlib.c
Rename the compiled fteqcc to fteqcc-win32 (as that's what it is)
[voretournament/voretournament.git] / misc / mediasource / extra / fteqcc-src / initlib.c
1 #define PROGSUSED
2 #include "progsint.h"
3 #include <stdlib.h>
4
5 typedef struct prmemb_s {
6         struct prmemb_s *prev;
7         int level;
8 } prmemb_t;
9 void *PRHunkAlloc(progfuncs_t *progfuncs, int ammount)
10 {
11         prmemb_t *mem;
12         ammount = sizeof(prmemb_t)+((ammount + 3)&~3);
13         mem = memalloc(ammount); 
14         memset(mem, 0, ammount);
15         mem->prev = memb;
16         if (!memb)
17                 mem->level = 1;
18         else
19                 mem->level = ((prmemb_t *)memb)->level+1;
20         memb = mem;
21
22         return ((char *)mem)+sizeof(prmemb_t);
23 }
24
25 int PRHunkMark(progfuncs_t *progfuncs)
26 {
27         return ((prmemb_t *)memb)->level;
28 }
29 void PRHunkFree(progfuncs_t *progfuncs, int mark)
30 {
31         prmemb_t *omem;
32         while(memb)
33         {
34                 if (memb->level <= mark)
35                         return;
36
37                 omem = memb;
38                 memb = memb->prev;
39                 memfree(omem);
40         }
41         return;
42 }
43
44 //for 64bit systems. :)
45 //addressable memory is memory available to the vm itself for writing.
46 //once allocated, it cannot be freed for the lifetime of the VM.
47 void *PRAddressableAlloc(progfuncs_t *progfuncs, int ammount)
48 {
49         ammount = (ammount + 4)&~3;     //round up to 4
50         if (addressableused + ammount > addressablesize)
51                 Sys_Error("Not enough addressable memory for progs VM");
52
53         addressableused += ammount;
54
55 #ifdef _WIN32
56         if (!VirtualAlloc (addressablehunk, addressableused, MEM_COMMIT, PAGE_READWRITE))
57                 Sys_Error("VirtualAlloc failed. Blame windows.");
58 #endif
59
60         return &addressablehunk[addressableused-ammount];
61 }
62
63 void PRAddressableFlush(progfuncs_t *progfuncs, int totalammount)
64 {
65         addressableused = 0;
66         if (totalammount < 0)   //flush
67         {
68                 totalammount = addressablesize;
69 //              return;
70         }
71
72         if (addressablehunk)
73 #ifdef _WIN32
74         VirtualFree(addressablehunk, 0, MEM_RELEASE);   //doesn't this look complicated? :p
75         addressablehunk = VirtualAlloc (NULL, totalammount, MEM_RESERVE, PAGE_NOACCESS);
76 #else
77         free(addressablehunk);
78         addressablehunk = malloc(totalammount); //linux will allocate-on-use anyway, which is handy.
79 //      memset(addressablehunk, 0xff, totalammount);
80 #endif
81         if (!addressablehunk)
82                 Sys_Error("Out of memory\n");
83         addressablesize = totalammount;
84 }
85
86 int PR_InitEnts(progfuncs_t *progfuncs, int max_ents)
87 {
88         maxedicts = max_ents;
89
90         sv_num_edicts = 0;
91
92         max_fields_size = fields_size;
93
94         prinst->edicttable = PRHunkAlloc(progfuncs, maxedicts*sizeof(struct edicts_s *));
95         sv_edicts = PRHunkAlloc(progfuncs, externs->edictsize);
96         prinst->edicttable[0] = sv_edicts;
97         ((edictrun_t*)prinst->edicttable[0])->fields = PRAddressableAlloc(progfuncs, max_fields_size);
98         QC_ClearEdict(progfuncs, sv_edicts);
99         sv_num_edicts = 1;
100
101         if (externs->entspawn)
102                 externs->entspawn((struct edict_s *)sv_edicts, false);
103
104         return max_fields_size;
105 }
106 edictrun_t tempedict;   //used as a safty buffer
107 float tempedictfields[2048];
108
109 void PR_Configure (progfuncs_t *progfuncs, int addressable_size, int max_progs) //can be used to wipe all memory
110 {
111         unsigned int i;
112         edictrun_t *e;
113
114 //      int a;
115 #ifdef QCJIT
116         prinst->usejit = true;
117 #endif
118
119         max_fields_size=0;
120         fields_size = 0;
121         progfuncs->stringtable = 0;
122         QC_StartShares(progfuncs);
123         QC_InitShares(progfuncs);
124
125         for ( i=1 ; i<maxedicts; i++)
126         {
127                 e = (edictrun_t *)(prinst->edicttable[i]);
128                 prinst->edicttable[i] = NULL;
129 //              e->entnum = i;
130                 if (e)
131                         memfree(e);
132         }
133
134         PRHunkFree(progfuncs, 0);       //clear mem - our hunk may not be a real hunk.
135         if (addressable_size<0)
136                 addressable_size = 8*1024*1024;
137         PRAddressableFlush(progfuncs, addressable_size);
138
139         pr_progstate = PRHunkAlloc(progfuncs, sizeof(progstate_t) * max_progs);
140
141 /*              for(a = 0; a < max_progs; a++)
142                 {
143                         pr_progstate[a].progs = NULL;
144                 }               
145 */
146                 
147         maxprogs = max_progs;
148         pr_typecurrent=-1;
149
150         prinst->reorganisefields = false;
151
152         maxedicts = 1;
153         prinst->edicttable = &sv_edicts;
154         sv_num_edicts = 1;      //set up a safty buffer so things won't go horribly wrong too often
155         sv_edicts=(struct edict_s *)&tempedict;
156         tempedict.readonly = true;
157         tempedict.fields = tempedictfields;
158         tempedict.isfree = false;
159 }
160
161
162
163 struct globalvars_s *PR_globals (progfuncs_t *progfuncs, progsnum_t pnum)
164 {
165         if (pnum < 0)
166         {
167                 if (!current_progstate)
168                         return NULL;    //err.. you've not loaded one yet.
169                 return (struct globalvars_s *)current_progstate->globals;
170         }
171         return (struct globalvars_s *)pr_progstate[pnum].globals;
172 }
173
174 struct entvars_s *PR_entvars (progfuncs_t *progfuncs, struct edict_s *ed)
175 {
176         if (((edictrun_t *)ed)->isfree)
177                 return NULL;
178
179         return (struct entvars_s *)edvars(ed);
180 }
181
182 int PR_GetFuncArgCount(progfuncs_t *progfuncs, func_t func)
183 {
184         unsigned int pnum;
185         unsigned int fnum;
186         dfunction_t *f;
187
188         pnum = (func & 0xff000000)>>24;
189         fnum = (func & 0x00ffffff);
190
191         if (pnum >= (unsigned)maxprogs || !pr_progstate[pnum].functions)
192                 return -1;
193         else if (fnum >= pr_progstate[pnum].progs->numfunctions)
194                 return -1;
195         else
196         {
197                 f = pr_progstate[pnum].functions + fnum;
198                 return f->numparms;
199         }
200 }
201
202 func_t PR_FindFunc(progfuncs_t *progfuncs, char *funcname, progsnum_t pnum)
203 {
204         dfunction_t *f=NULL;
205         if (pnum == PR_ANY)
206         {
207                 for (pnum = 0; (unsigned)pnum < maxprogs; pnum++)
208                 {
209                         if (!pr_progstate[pnum].progs)
210                                 continue;
211                         f = ED_FindFunction(progfuncs, funcname, &pnum, pnum);
212                         if (f)
213                                 break;
214                 }
215         }
216         else if (pnum == PR_ANYBACK)    //run backwards
217         {
218                 for (pnum = maxprogs-1; pnum >= 0; pnum--)
219                 {
220                         if (!pr_progstate[pnum].progs)
221                                 continue;
222                         f = ED_FindFunction(progfuncs, funcname, &pnum, pnum);
223                         if (f)
224                                 break;
225                 }
226         }
227         else
228                 f = ED_FindFunction(progfuncs, funcname, &pnum, pnum);
229         if (!f)
230                 return 0;
231
232         {
233         ddef16_t *var16;
234         ddef32_t *var32;
235         switch(pr_progstate[pnum].intsize)
236         {
237         case 24:
238         case 16:
239                 var16 = ED_FindTypeGlobalFromProgs16(progfuncs, funcname, pnum, ev_function);   //we must make sure we actually have a function def - 'light' is defined as a field before it is defined as a function.
240                 if (!var16)
241                         return (f - pr_progstate[pnum].functions) | (pnum << 24);
242                 return *(int *)&pr_progstate[pnum].globals[var16->ofs]; 
243         case 32:
244                 var32 = ED_FindTypeGlobalFromProgs32(progfuncs, funcname, pnum, ev_function);   //we must make sure we actually have a function def - 'light' is defined as a field before it is defined as a function.
245                 if (!var32)
246                         return (f - pr_progstate[pnum].functions) | (pnum << 24);
247                 return *(int *)&pr_progstate[pnum].globals[var32->ofs]; 
248         }
249         Sys_Error("Error with def size (PR_FindFunc)"); 
250         }
251         return 0;
252 }
253
254 eval_t *PR_FindGlobal(progfuncs_t *progfuncs, char *globname, progsnum_t pnum)
255 {
256         unsigned int i;
257         ddef16_t *var16;
258         ddef32_t *var32;
259         if (pnum == PR_CURRENT)
260                 pnum = pr_typecurrent;
261         if (pnum == PR_ANY)
262         {
263                 eval_t *ev;
264                 for (i = 0; i < maxprogs; i++)
265                 {
266                         if (!pr_progstate[i].progs)
267                                 continue;
268                         ev = PR_FindGlobal(progfuncs, globname, i);
269                         if (ev)
270                                 return ev;
271                 }
272                 return NULL;
273         }
274         if (pnum < 0 || (unsigned)pnum >= maxprogs || !pr_progstate[pnum].progs)
275                 return NULL;
276         switch(pr_progstate[pnum].intsize)
277         {
278         case 16:
279         case 24:
280                 if (!(var16 = ED_FindGlobalFromProgs16(progfuncs, globname, pnum)))
281                         return NULL;
282
283                 return (eval_t *)&pr_progstate[pnum].globals[var16->ofs];
284         case 32:
285                 if (!(var32 = ED_FindGlobalFromProgs32(progfuncs, globname, pnum)))
286                         return NULL;
287
288                 return (eval_t *)&pr_progstate[pnum].globals[var32->ofs];
289         }
290         Sys_Error("Error with def size (PR_FindGlobal)");
291         return NULL;
292 }
293
294 void SetGlobalEdict(progfuncs_t *progfuncs, struct edict_s *ed, int ofs)
295 {
296         ((int*)pr_globals)[ofs] = EDICT_TO_PROG(progfuncs, ed);
297 }
298
299 char *PR_VarString (progfuncs_t *progfuncs, int first)
300 {
301         int             i;
302         static char out[1024];
303         char *s;
304         
305         out[0] = 0;
306         for (i=first ; i<pr_argc ; i++)
307         {
308                 if (G_STRING(OFS_PARM0+i*3))
309                 {
310                         s=G_STRING((OFS_PARM0+i*3)) + progfuncs->stringtable;
311                         strcat (out, s);
312
313 //#ifdef PARANOID
314                         if (strlen(out)+1 >= sizeof(out))
315                                 Sys_Error("VarString (builtin call ending with strings) exceeded maximum string length of %i chars", sizeof(out));
316 //#endif
317                 }
318         }
319         return out;
320 }
321
322 int PR_QueryField (progfuncs_t *progfuncs, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache)
323 {
324         fdef_t *var;
325         var = ED_FieldAtOfs(progfuncs, fieldoffset);
326         if (!var)
327                 return false;
328
329         if (type)
330                 *type = var->type & ~(DEF_SAVEGLOBAL|DEF_SHARED);
331         if (name)
332                 *name = var->name;
333         if (fieldcache)
334         {
335                 fieldcache->ofs32 = var;
336                 fieldcache->varname = var->name;
337         }
338                 
339         return true;
340 }
341
342 eval_t *GetEdictFieldValue(progfuncs_t *progfuncs, struct edict_s *ed, char *name, evalc_t *cache)
343 {
344         fdef_t *var;
345         if (!cache)
346         {
347                 var = ED_FindField(progfuncs, name);
348                 if (!var)
349                         return NULL;
350                 return (eval_t *) &(((int*)(((edictrun_t*)ed)->fields))[var->ofs]);
351         }
352         if (!cache->varname)
353         {
354                 cache->varname = name;
355                 var = ED_FindField(progfuncs, name);            
356                 if (!var)
357                 {
358                         cache->ofs32 = NULL;
359                         return NULL;
360                 }
361                 cache->ofs32 = var;
362                 cache->varname = var->name;
363                 if (!ed)
364                         return (void*)~0;       //something not null
365                 return (eval_t *) &(((int*)(((edictrun_t*)ed)->fields))[var->ofs]);
366         }
367         if (cache->ofs32 == NULL)
368                 return NULL;
369         return (eval_t *) &(((int*)(((edictrun_t*)ed)->fields))[cache->ofs32->ofs]);
370 }
371
372 struct edict_s *ProgsToEdict (progfuncs_t *progfuncs, int progs)
373 {
374         if ((unsigned)progs >= (unsigned)maxedicts)
375         {
376                 printf("Bad entity index %i\n", progs);
377                 progs = 0;
378         }
379         return (struct edict_s *)PROG_TO_EDICT(progfuncs, progs);
380 }
381 int EdictToProgs (progfuncs_t *progfuncs, struct edict_s *ed)
382 {
383         return EDICT_TO_PROG(progfuncs, ed);
384 }
385
386 string_t PR_StringToProgs                       (progfuncs_t *progfuncs, char *str)
387 {
388         char **ntable;
389         int i, free=-1;
390
391         if (!str)
392                 return 0;
393
394 //      if (str-progfuncs->stringtable < progfuncs->stringtablesize)
395 //              return str - progfuncs->stringtable;
396
397         for (i = prinst->numallocedstrings-1; i >= 0; i--)
398         {
399                 if (prinst->allocedstrings[i] == str)
400                         return (string_t)((unsigned int)i | 0x80000000);
401                 if (!prinst->allocedstrings[i])
402                         free = i;
403         }
404
405         if (free != -1)
406         {
407                 i = free;
408                 prinst->allocedstrings[i] = str;
409                 return (string_t)((unsigned int)i | 0x80000000);
410         }
411
412         prinst->maxallocedstrings += 1024;
413         ntable = memalloc(sizeof(char*) * prinst->maxallocedstrings); 
414         memcpy(ntable, prinst->allocedstrings, sizeof(char*) * prinst->numallocedstrings);
415         memset(ntable + prinst->numallocedstrings, 0, sizeof(char*) * (prinst->maxallocedstrings - prinst->numallocedstrings));
416         prinst->numallocedstrings = prinst->maxallocedstrings;
417         if (prinst->allocedstrings)
418                 memfree(prinst->allocedstrings);
419         prinst->allocedstrings = ntable;
420
421         for (i = prinst->numallocedstrings-1; i >= 0; i--)
422         {
423                 if (!prinst->allocedstrings[i])
424                 {
425                         prinst->allocedstrings[i] = str;
426                         return (string_t)((unsigned int)i | 0x80000000);
427                 }
428         }
429
430         return 0;
431 }
432
433 char *PR_RemoveProgsString                              (progfuncs_t *progfuncs, string_t str)
434 {
435         char *ret;
436
437         //input string is expected to be an allocated string
438         //if its a temp, or a constant, just return NULL.
439         if ((unsigned int)str & 0xc0000000)
440         {
441                 if ((unsigned int)str & 0x80000000)
442                 {
443                         int i = str & ~0x80000000;
444                         if (i >= prinst->numallocedstrings)
445                         {
446                                 pr_trace = 1;
447                                 return NULL;
448                         }
449                         if (prinst->allocedstrings[i])
450                         {
451                                 ret = prinst->allocedstrings[i];
452                                 prinst->allocedstrings[i] = NULL;       //remove it
453                                 return ret;
454                         }
455                         else
456                         {
457                                 pr_trace = 1;
458                                 return NULL;    //urm, was freed...
459                         }
460                 }
461         }
462         pr_trace = 1;
463         return NULL;
464 }
465
466 char *PR_StringToNative                         (progfuncs_t *progfuncs, string_t str)
467 {
468         if ((unsigned int)str & 0xc0000000)
469         {
470                 if ((unsigned int)str & 0x80000000)
471                 {
472                         int i = str & ~0x80000000;
473                         if (i >= prinst->numallocedstrings)
474                         {
475                                 pr_trace = 1;
476                                 return "";
477                         }
478                         if (prinst->allocedstrings[i])
479                                 return prinst->allocedstrings[i];
480                         else
481                         {
482                                 pr_trace = 1;
483                                 return "";      //urm, was freed...
484                         }
485                 }
486                 if ((unsigned int)str & 0x40000000)
487                 {
488                         int i = str & ~0x40000000;
489                         if (i >= prinst->numtempstrings)
490                         {
491                                 pr_trace = 1;
492                                 return "";
493                         }
494                         return prinst->tempstrings[i];
495                 }
496         }
497
498         if (str >= progfuncs->stringtablesize)
499         {
500                 pr_trace = 1;
501                 return "";
502         }
503         return progfuncs->stringtable + str;
504 }
505
506
507 string_t PR_AllocTempString                     (progfuncs_t *progfuncs, char *str)
508 {
509         char **ntable;
510         int newmax;
511         int i;
512
513         if (!str)
514                 return 0;
515
516         if (prinst->numtempstrings == prinst->maxtempstrings)
517         {
518                 newmax = prinst->maxtempstrings += 1024;
519                 prinst->maxtempstrings += 1024;
520                 ntable = memalloc(sizeof(char*) * newmax);
521                 memcpy(ntable, prinst->tempstrings, sizeof(char*) * prinst->numtempstrings);
522                 prinst->maxtempstrings = newmax;
523                 if (prinst->tempstrings)
524                         memfree(prinst->tempstrings);
525                 prinst->tempstrings = ntable;
526         }
527
528         i = prinst->numtempstrings;
529         if (i == 0x10000000)
530                 return 0;
531
532         prinst->numtempstrings++;
533
534         prinst->tempstrings[i] = memalloc(strlen(str)+1);
535         strcpy(prinst->tempstrings[i], str);
536
537         return (string_t)((unsigned int)i | 0x40000000);
538 }
539
540 void PR_FreeTemps                       (progfuncs_t *progfuncs, int depth)
541 {
542         int i;
543         if (depth > prinst->numtempstrings)
544         {
545                 Sys_Error("QC Temp stack inverted\n");
546                 return;
547         }
548         for (i = depth; i < prinst->numtempstrings; i++)
549         {
550                 memfree(prinst->tempstrings[i]);
551         }
552
553         prinst->numtempstrings = depth;
554 }
555
556
557 struct qcthread_s *PR_ForkStack (progfuncs_t *progfuncs);
558 void PR_ResumeThread                    (progfuncs_t *progfuncs, struct qcthread_s *thread);
559 void    PR_AbortStack                   (progfuncs_t *progfuncs);
560
561
562 void RegisterBuiltin(progfuncs_t *progfncs, char *name, builtin_t func);
563
564 progfuncs_t deffuncs = {
565         PROGSTRUCT_VERSION,
566         PR_Configure,
567         PR_LoadProgs,
568         PR_InitEnts,
569         PR_ExecuteProgram,
570         PR_SwitchProgs,
571         PR_globals,
572         PR_entvars,
573         PR_RunError,
574         ED_Print,
575         ED_Alloc,
576         ED_Free,
577
578         EDICT_NUM,
579         NUM_FOR_EDICT,
580
581
582         SetGlobalEdict,
583
584         PR_VarString,
585
586         NULL,
587         PR_FindFunc,
588 #ifdef MINIMAL
589         NULL,
590         NULL,
591 #else
592         Comp_Begin,
593         Comp_Continue,
594 #endif
595
596         filefromprogs,
597         NULL,//filefromnewprogs,
598
599         SaveEnts,
600         LoadEnts,
601
602         SaveEnt,
603         RestoreEnt,
604
605         PR_FindGlobal,
606         ED_NewString,
607         (void*)PRHunkAlloc,
608
609         GetEdictFieldValue,
610         ProgsToEdict,
611         EdictToProgs,
612
613         EvaluateDebugString,
614
615         NULL,
616         PR_StackTrace,
617
618         PR_ToggleBreakpoint,
619         0,
620         NULL,
621 #ifdef MINIMAL
622         NULL,
623 #else
624         Decompile,
625 #endif
626         NULL,
627         NULL,
628         RegisterBuiltin,
629
630         0,
631         0,
632
633         PR_ForkStack,
634         PR_ResumeThread,
635         PR_AbortStack,
636
637         0,
638
639         QC_RegisterFieldVar,
640
641         0,
642         0,
643
644         PR_AllocTempString,
645
646         PR_StringToProgs,
647         PR_StringToNative,
648         0,
649         PR_QueryField,
650         QC_ClearEdict
651 };
652 #undef printf
653
654 //defs incase following structure is not passed.
655 struct edict_s *safesv_edicts;
656 int safesv_num_edicts;
657 double safetime=0;
658
659 progexterns_t defexterns = {
660         PROGSTRUCT_VERSION,             
661
662         NULL, //char *(*ReadFile) (char *fname, void *buffer, int len);
663         NULL, //int (*FileSize) (char *fname);  //-1 if file does not exist
664         NULL, //bool (*WriteFile) (char *name, void *data, int len);
665         printf, //void (*printf) (char *, ...);
666         (void*)exit, //void (*Sys_Error) (char *, ...);
667         NULL, //void (*Abort) (char *, ...);
668         sizeof(edictrun_t), //int edictsize;    //size of edict_t
669
670         NULL, //void (*entspawn) (struct edict_s *ent); //ent has been spawned, but may not have all the extra variables (that may need to be set) set
671         NULL, //bool (*entcanfree) (struct edict_s *ent);       //return true to stop ent from being freed
672         NULL, //void (*stateop) (float var, func_t func);
673         NULL,
674         NULL,
675         NULL,
676
677         //used when loading a game
678         NULL, //builtin_t *(*builtinsfor) (int num);    //must return a pointer to the builtins that were used before the state was saved.
679         NULL, //void (*loadcompleate) (int edictsize);  //notification to reset any pointers.
680
681         (void*)malloc, //void *(*memalloc) (int size);  //small string allocation       malloced and freed randomly by the executor. (use memalloc if you want)
682         free, //void (*memfree) (void * mem);
683
684
685         NULL, //builtin_t *globalbuiltins;      //these are available to all progs
686         0, //int numglobalbuiltins;
687
688         PR_NOCOMPILE,
689
690         &safetime, //double *gametime;
691
692         &safesv_edicts, //struct edict_s **sv_edicts;
693         &safesv_num_edicts, //int *sv_num_edicts;
694
695         NULL, //int (*useeditor) (char *filename, int line, int nump, char **parms);
696 };
697
698 //progfuncs_t *progfuncs = NULL;
699 #undef memfree
700 #undef prinst
701 #undef extensionbuiltin
702 #undef field
703 #undef shares
704 #undef sv_num_edicts
705
706
707 #ifdef QCLIBDLL_EXPORTS
708 __declspec(dllexport)
709 #endif 
710 void CloseProgs(progfuncs_t *inst)
711 {
712 //      extensionbuiltin_t *eb;
713         void (VARGS *f) (void *);
714
715         unsigned int i;
716         edictrun_t *e;
717
718         f = inst->parms->memfree;
719
720         for ( i=1 ; i<inst->maxedicts; i++)
721         {
722                 e = (edictrun_t *)(inst->prinst->edicttable[i]);
723                 inst->prinst->edicttable[i] = NULL;
724                 if (e)
725                 {
726 //                      e->entnum = i;
727                         f(e);
728                 }
729         }
730
731         PRHunkFree(inst, 0);
732
733 #ifdef _WIN32
734         VirtualFree(inst->addressablehunk, 0, MEM_RELEASE);     //doesn't this look complicated? :p
735 #else
736         free(inst->addressablehunk);
737 #endif
738
739 /*
740         while(inst->prinst->extensionbuiltin)
741         {
742                 eb = inst->prinst->extensionbuiltin->prev;
743                 f(inst->prinst->extensionbuiltin);
744                 inst->prinst->extensionbuiltin = eb;
745         }
746 */
747         if (inst->prinst->field)
748                 f(inst->prinst->field);
749         if (inst->prinst->shares)
750                 f(inst->prinst->shares);        //free memory
751         f(inst->prinst);
752         f(inst);
753 }
754
755 void RegisterBuiltin(progfuncs_t *progfuncs, char *name, builtin_t func)
756 {
757 /*
758         extensionbuiltin_t *eb;
759         eb = memalloc(sizeof(extensionbuiltin_t));
760         eb->prev = progfuncs->prinst->extensionbuiltin;
761         progfuncs->prinst->extensionbuiltin = eb;
762         eb->name = name;
763         eb->func = func;
764 */
765 }
766
767 #ifndef WIN32
768 #define QCLIBINT        //don't use dllspecifications
769 #endif
770
771 #if defined(QCLIBDLL_EXPORTS)
772 __declspec(dllexport)
773 #endif
774 progfuncs_t * InitProgs(progexterns_t *ext)
775 {       
776         progfuncs_t *funcs;
777
778         if (!ext)
779                 ext = &defexterns;
780         else
781         {
782                 int i;
783                 if (ext->progsversion > PROGSTRUCT_VERSION)
784                         return NULL;
785
786                 for (i=0;i<sizeof(progexterns_t); i+=4) //make sure there are no items left out.
787                         if (!*(int *)((char *)ext+i))
788                                 *(int *)((char *)ext+i) = *(int *)((char *)&defexterns+i);              
789         }       
790 #undef memalloc
791 #undef pr_trace
792         funcs = ext->memalloc(sizeof(progfuncs_t));     
793         memcpy(funcs, &deffuncs, sizeof(progfuncs_t));
794
795         funcs->prinst = ext->memalloc(sizeof(prinst_t));
796         memset(funcs->prinst,0, sizeof(prinst_t));
797
798         funcs->pr_trace = &funcs->prinst->pr_trace;
799         funcs->progstate = &funcs->pr_progstate;
800         funcs->callargc = &funcs->pr_argc;
801
802         funcs->parms = ext;
803
804         SetEndian();
805         
806         return funcs;
807 }
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824 #ifdef QCC
825 void main (int argc, char **argv)
826 {
827         progexterns_t ext;
828
829         progfuncs_t *funcs;
830         funcs = InitProgs(&ext);
831         if (funcs->PR_StartCompile(argc, argv))
832                 while(funcs->PR_ContinueCompile());
833 }
834 #endif