00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 #include <stdlib.h>
00164 #include <string.h>
00165 #include <stdio.h>
00166
00167 #include "filesys.h"
00168 #include "report.h"
00169 #include "lexer.h"
00170 #include "sym.h"
00171 #include "expression.h"
00172 #include "myalloc.h"
00173 #include "builder.h"
00174 #include "errcodes.h"
00175 #include "buildnum.h"
00176
00177 #if _WIN32
00178 #include <windows.h>
00179 #if BCC32 || CYGWIN
00180 extern char *_pgmptr;
00181 #endif
00182 #endif
00183
00184
00185 #define REPORT(x1,x2,x3,x4) if( pBuild->report )pBuild->report(pBuild->reportptr,x1,x2,x3,REPORT_ERROR,&(pBuild->iErrorCounter),x4,(&pBuild->fErrorFlags))
00186
00187 #define CALL_PREPROCESSOR(X,Y) if( pBuild->pPREP && pBuild->pPREP->n )ipreproc_Process(pBuild->pPREP,X,Y)
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 void build_AllocateStringTable(pBuildObject pBuild,
00228 int *piFailure
00229 ){
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 if( pBuild->cbStringTable == 0L )pBuild->cbStringTable=1L;
00249 pBuild->StringTable = alloc_Alloc(pBuild->cbStringTable ,pBuild->pMemorySegment);
00250 pBuild->cbCollectedStrings = 0L;
00251 if( pBuild->StringTable == NULL ){
00252 REPORT("",0L,BU_ERROR_MEMORY_LOW,NULL);
00253 *piFailure = BU_ERROR_MEMORY_LOW;
00254 return;
00255 }
00256 *piFailure = BU_ERROR_SUCCESS;
00257 return;
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 unsigned long build_StringIndex(pBuildObject pBuild,
00275 char *s,
00276 long sLen
00277 ){
00278
00279
00280 unsigned long ulIndex;
00281 char *r;
00282 long lLen;
00283
00284 ulIndex = 0;
00285 while( ulIndex < pBuild->cbCollectedStrings ){
00286
00287 memcpy( &lLen, pBuild->StringTable + ulIndex , sizeof(long));
00288 ulIndex += sizeof(long);
00289 if( sLen == lLen && !memcmp(s,pBuild->StringTable + ulIndex,lLen) )return ulIndex;
00290 ulIndex += lLen;
00291 ulIndex++;
00292 }
00293
00294 r = pBuild->StringTable + pBuild->cbCollectedStrings;
00295 if( sLen+1+pBuild->cbCollectedStrings > pBuild->cbStringTable ){
00296 fprintf(stderr,"String table build up. Internal error!\n");
00297 exit(2000);
00298 }
00299 memcpy(r,&sLen,sizeof(long));
00300 r += sizeof(long);
00301 memcpy(r,s,sLen+1);
00302 ulIndex = pBuild->cbCollectedStrings + sizeof(long);
00303 pBuild->cbCollectedStrings += sLen + sizeof(long) + 1;
00304 return ulIndex;
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314 int build_Build_l(pBuildObject pBuild,
00315 peNODE_l Result
00316 ){
00317
00318
00319
00320
00321 int iFailure;
00322
00323 while( Result ){
00324 pBuild->CommandArray[Result->NodeId-1].OpCode = eNTYPE_LST;
00325 pBuild->CommandArray[Result->NodeId-1].Parameter.NodeList.actualm = Result->actualm ? Result->actualm->NodeId : 0;
00326 pBuild->CommandArray[Result->NodeId-1].Parameter.NodeList.rest = Result->rest ? Result->rest->NodeId : 0;
00327 if( iFailure = build_Build_r(pBuild,Result->actualm) )return iFailure;
00328 Result = Result->rest;
00329 }
00330
00331 return BU_ERROR_SUCCESS;
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 int build_Build_r(pBuildObject pBuild,
00345 peNODE Result
00346 ){
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 pcNODE pThis;
00357 unsigned long *q;
00358 pLineSyntax pCommand;
00359 int iFailure;
00360 int j;
00361
00362 if( Result == NULL )return BU_ERROR_SUCCESS;
00363 pThis = pBuild->CommandArray+Result->NodeId-1;
00364 pThis->OpCode = Result->OpCode;
00365
00366
00367 if( Result->OpCode == eNTYPE_ARR || Result->OpCode == eNTYPE_SAR ){
00368 pThis->Parameter.Arguments.Argument = Result->Parameter.Arguments.Argument->NodeId;
00369 return build_Build_l(pBuild,Result->Parameter.Arguments.Argument);
00370 }
00371
00372
00373 if( Result->OpCode == eNTYPE_FUN ){
00374 if( Result->Parameter.UserFunction.pFunction->node == 0 ){
00375 REPORT("",0L,EX_ERROR_FUNCTION_NOT_DEFINED,Result->Parameter.UserFunction.pFunction->FunctionName);
00376 }
00377 pThis->Parameter.UserFunction.NodeId = Result->Parameter.UserFunction.pFunction->node;
00378 pThis->Parameter.UserFunction.Argument = Result->Parameter.UserFunction.Argument ?
00379 Result->Parameter.UserFunction.Argument->NodeId : 0;
00380 return build_Build_l(pBuild,Result->Parameter.UserFunction.Argument);
00381 }
00382
00383
00384 if( Result->OpCode == eNTYPE_LVR || Result->OpCode == eNTYPE_GVR ){
00385 pThis->Parameter.Variable.Serial = Result->Parameter.Variable.Serial;
00386 return BU_ERROR_SUCCESS;
00387 }
00388
00389 if( Result->OpCode == eNTYPE_DBL ){
00390 pThis->Parameter.Constant.dValue = Result->Parameter.Constant.Value.dValue;
00391 return BU_ERROR_SUCCESS;
00392 }
00393
00394 if( Result->OpCode == eNTYPE_LNG ){
00395 pThis->Parameter.Constant.lValue = Result->Parameter.Constant.Value.lValue;
00396 return BU_ERROR_SUCCESS;
00397 }
00398
00399 if( Result->OpCode == eNTYPE_STR ){
00400 pThis->Parameter.Constant.sValue = build_StringIndex(pBuild,Result->Parameter.Constant.Value.sValue,Result->Parameter.Constant.sLen);
00401 return BU_ERROR_SUCCESS;
00402 }
00403
00404 q = pBuild->pEx->Binaries;
00405
00406 while( *q && *q != (unsigned)pThis->OpCode )q+=2;
00407 if( *q ){
00408 pThis->Parameter.Arguments.Argument = Result->Parameter.Arguments.Argument->NodeId;
00409 return build_Build_l(pBuild,Result->Parameter.Arguments.Argument);
00410 }
00411
00412 q = pBuild->pEx->Unaries;
00413 while( *q && *q != (unsigned)pThis->OpCode )q++;
00414 if( *q ){
00415 pThis->Parameter.Arguments.Argument = Result->Parameter.Arguments.Argument->NodeId;
00416 return build_Build_l(pBuild,Result->Parameter.Arguments.Argument);
00417 }
00418
00419 pCommand = pBuild->pEx->Command;
00420 while( pCommand && pCommand->CommandOpCode != 0 && pCommand->CommandOpCode != pThis->OpCode )pCommand++;
00421
00422 #define NEXT_ARGUMENT if( Result->Parameter.CommandArgument.next ){\
00423 if( pThis->Parameter.CommandArgument.next = Result->Parameter.CommandArgument.next->NodeId ){\
00424 pThis = pBuild->CommandArray+Result->Parameter.CommandArgument.next->NodeId-1;\
00425 pThis->OpCode = eNTYPE_CRG;\
00426 Result = Result->Parameter.CommandArgument.next;\
00427 }\
00428 break;\
00429 }\
00430 else{\
00431 pThis->Parameter.CommandArgument.next = 0;\
00432 return BU_ERROR_SUCCESS;\
00433 }
00434
00435 if( pCommand && pCommand->CommandOpCode ){
00436 for( j=0 ; j < MAX_LEXES_PER_LINE && pCommand->lexes[j].type ; j++ ){
00437 switch( pCommand->lexes[j].type ){
00438
00439
00440
00441 case EX_LEX_NSYMBOL:
00442 case EX_LEX_SET_NAME_SPACE:
00443 case EX_LEX_CHARACTER:
00444 case EX_LEX_LOCAL:
00445 case EX_LEX_LOCALL:
00446 case EX_LEX_FUNCTION:
00447 case EX_LEX_THIS_FUNCTION:
00448 case EX_LEX_LABEL_DEFINITION:
00449 case EX_LEX_STAR:
00450 case EX_LEX_NOEXEC:
00451 case EX_LEX_COME_FORWARD:
00452 case EX_LEX_COME_BACK:
00453 case EX_LEX_LOCAL_END:
00454 break;
00455
00456
00457
00458
00459
00460 case EX_LEX_LABEL:
00461 case EX_LEX_GO_FORWARD:
00462 case EX_LEX_GO_BACK:
00463 pThis->Parameter.CommandArgument.Argument.pNode =
00464 Result->Parameter.CommandArgument.Argument.pLabel ?
00465 Result->Parameter.CommandArgument.Argument.pLabel->node : 0;
00466 NEXT_ARGUMENT;
00467
00468 case EX_LEX_LVAL:
00469 case EX_LEX_EXP:
00470 pThis->Parameter.CommandArgument.Argument.pNode =
00471 Result->Parameter.CommandArgument.Argument.pNode->NodeId;
00472 iFailure = build_Build_r(pBuild,Result->Parameter.CommandArgument.Argument.pNode);
00473 if( iFailure )return iFailure;
00474 NEXT_ARGUMENT;
00475
00476 case EX_LEX_LVALL:
00477 case EX_LEX_EXPL:
00478 pThis->Parameter.CommandArgument.Argument.pNode =
00479 Result->Parameter.CommandArgument.Argument.pNodeList->NodeId;
00480 iFailure = build_Build_l(pBuild,Result->Parameter.CommandArgument.Argument.pNodeList);
00481 if( iFailure )return iFailure;
00482 NEXT_ARGUMENT;
00483
00484 case EX_LEX_STRING:
00485 case EX_LEX_SYMBOL:
00486 case EX_LEX_ASYMBOL:
00487 pThis->Parameter.CommandArgument.Argument.szStringValue =
00488 build_StringIndex(pBuild,Result->Parameter.CommandArgument.Argument.szStringValue,Result->Parameter.CommandArgument.sLen);
00489 NEXT_ARGUMENT;
00490
00491 case EX_LEX_ARG_NUM:
00492 case EX_LEX_LOCAL_START:
00493 case EX_LEX_LONG:
00494 pThis->Parameter.CommandArgument.Argument.lLongValue =
00495 Result->Parameter.CommandArgument.Argument.lLongValue;
00496 NEXT_ARGUMENT;
00497
00498 case EX_LEX_DOUBLE:
00499 pThis->Parameter.CommandArgument.Argument.dDoubleValue =
00500 Result->Parameter.CommandArgument.Argument.dDoubleValue;
00501 NEXT_ARGUMENT;
00502
00503 default:
00504 fprintf(stderr,"This is a serious internal error. STOP\n");
00505 exit(1000);
00506 }
00507 }
00508 return BU_ERROR_SUCCESS;
00509 }
00510
00511 pThis->OpCode = Result->OpCode;
00512 if( Result->Parameter.Arguments.Argument )
00513 pThis->Parameter.Arguments.Argument = Result->Parameter.Arguments.Argument->NodeId;
00514 else
00515 pThis->Parameter.Arguments.Argument = 0;
00516 return build_Build_l(pBuild,Result->Parameter.Arguments.Argument);
00517 }
00518
00519
00520
00521
00522
00523
00524
00525
00526 int build_Build(pBuildObject pBuild
00527 ){
00528
00529
00530 int iFailure;
00531
00532 pBuild->cbFTable = 0;
00533 pBuild->cbVTable = 0;
00534 pBuild->FTable = NULL;
00535 pBuild->VTable = NULL;
00536
00537 pBuild->NodeCounter = pBuild->pEx->NodeCounter;
00538 pBuild->cGlobalVariables = pBuild->pEx->cGlobalVariables;
00539 pBuild->report = pBuild->pEx->report;
00540 pBuild->reportptr = pBuild->pEx->reportptr;
00541 if( pBuild->pEx->NodeCounter ==0 ){
00542
00543
00544
00545 pBuild->pMemorySegment = NULL;
00546 REPORT("",0L,BU_ERROR_NO_CODE,NULL);
00547 return BU_ERROR_NO_CODE;
00548 }
00549 pBuild->pMemorySegment = alloc_InitSegment(pBuild->memory_allocating_function,
00550 pBuild->memory_releasing_function);
00551 if( pBuild->pMemorySegment == NULL ){
00552 REPORT("",0L,BU_ERROR_MEMORY_LOW,NULL);
00553 return BU_ERROR_MEMORY_LOW;
00554 }
00555 pBuild->CommandArray = alloc_Alloc(sizeof(cNODE) * pBuild->NodeCounter , pBuild->pMemorySegment );
00556 if( pBuild->CommandArray == NULL ){
00557 REPORT("",0L,BU_ERROR_MEMORY_LOW,NULL);
00558 return BU_ERROR_MEMORY_LOW;
00559 }
00560 pBuild->cbStringTable = pBuild->pEx->cbStringTable;
00561 build_AllocateStringTable(pBuild,&iFailure);
00562 if( iFailure )return iFailure;
00563
00564 if( (iFailure = build_CreateVTable(pBuild)) != BU_ERROR_SUCCESS )return iFailure;
00565 if( (iFailure = build_CreateFTable(pBuild)) != BU_ERROR_SUCCESS )return iFailure;
00566
00567
00568 pBuild->StartNode = pBuild->pEx->pCommandList->NodeId;
00569 return build_Build_l(pBuild, pBuild->pEx->pCommandList);
00570 }
00571
00572 static VersionInfo sVersionInfo;
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 unsigned long build_MagicCode(pVersionInfo p
00584 ){
00585
00586
00587 unsigned long magic;
00588 unsigned char *s;
00589
00590 s = (unsigned char *)__DATE__;
00591
00592 magic = *s++;
00593 magic += *s++;
00594 magic += *s++;
00595 magic -= 199;
00596 if( magic > 9 )magic -= 10;
00597 if( magic > 15 )magic -=4;
00598 if( magic == 16 )magic =15;
00599 s++;
00600 magic <<= 8;
00601 magic |= ((unsigned long)*s++) << 4;
00602 magic |= ((unsigned long)*s++) << 0;
00603 s++;
00604 magic |= ((unsigned long)*s++) << 24;
00605 magic |= ((unsigned long)*s++) << 20;
00606 magic |= ((unsigned long)*s++) << 16;
00607 magic |= ((unsigned long)*s++) << 12;
00608
00609 sVersionInfo.Build = SCRIPTBASIC_BUILD;
00610 sVersionInfo.Date = magic;
00611 sVersionInfo.MagicCode = MAGIC_CODE;
00612 sVersionInfo.VersionHigh = VERSION_HIGH;
00613 sVersionInfo.VersionLow = VERSION_LOW;
00614 sVersionInfo.MyVersionHigh = MYVERSION_HIGH;
00615 sVersionInfo.MyVersionLow = MYVERSION_LOW;
00616 memcpy(sVersionInfo.Variation, VARIATION, 9);
00617 if( p ){
00618 p->Build = SCRIPTBASIC_BUILD;
00619 p->Date = magic;
00620 p->MagicCode = MAGIC_CODE;
00621 p->VersionHigh = VERSION_HIGH;
00622 p->VersionLow = VERSION_LOW;
00623 p->MyVersionHigh = MYVERSION_HIGH;
00624 p->MyVersionLow = MYVERSION_LOW;
00625 memcpy(p->Variation, VARIATION, 9);
00626 }
00627 return magic;
00628 }
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 void build_SaveCCode(pBuildObject pBuild,
00641 char *szFileName
00642 ){
00643
00644
00645 FILE *fp;
00646 unsigned long i,j;
00647 unsigned char *s;
00648
00649 fp = file_fopen(szFileName,"w");
00650 if( fp == NULL )return;
00651
00652 fprintf(fp,"/* FILE: %s\n",szFileName);
00653 fprintf(fp," This file contains the binary code of a ScriptBasic program\n");
00654 fprintf(fp," To run this file you have to compile it to object file and\n");
00655 fprintf(fp," link it with scribast.lib or whatever the library code is\n");
00656 fprintf(fp," called on your platform.\n");
00657 fprintf(fp,"*/\n");
00658
00659 fprintf(fp,"unsigned long ulGlobalVariables=%ld;\n",pBuild->cGlobalVariables);
00660 fprintf(fp,"unsigned long ulNodeCounter=%ld;\n",pBuild->NodeCounter);
00661 fprintf(fp,"unsigned long ulStartNode=%ld;\n",pBuild->StartNode);
00662 fprintf(fp,"unsigned long ulStringTableSize=%ld;\n",pBuild->cbStringTable);
00663
00664 fprintf(fp,"unsigned char szCommandArray[] ={\n");
00665 for( i=0 ; i < pBuild->NodeCounter ; i++ ){
00666 s = (unsigned char *)(pBuild->CommandArray+i);
00667 for( j=0 ; j < sizeof(cNODE) ; j++ )
00668 fprintf(fp,"0x%02X, ",s[j]);
00669 fprintf(fp,"\n");
00670 }
00671 fprintf(fp,"0x00 };\n");
00672
00673 fprintf(fp,"char szStringTable[]={\n");
00674 s = (unsigned char *)pBuild->StringTable;
00675 for( i=0 ; i < pBuild->cbStringTable ; i++ ){
00676 fprintf(fp,"0x%02X, ",s[i]);
00677 if( i%16 == 15 )fprintf(fp,"\n");
00678 }
00679 fprintf(fp,"\n0x00 };\n");
00680 fprintf(fp,"#ifdef WIN32\n");
00681 fprintf(fp,"main(int argc, char *argv[]){stndlone(argc,argv);}\n");
00682 fprintf(fp,"#else\n");
00683 fprintf(fp,"char **_environ;\n");
00684 fprintf(fp,"main(int argc, char *argv[], char *env[]){stndlone(argc,argv,env);}\n");
00685 fprintf(fp,"#endif\n");
00686
00687 fprintf(fp,"/*End of file %s */",szFileName);
00688 file_fclose(fp);
00689 }
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 int build_SaveCorePart(pBuildObject pBuild,
00708 FILE *fp,
00709 unsigned long fFlag
00710 ){
00711
00712
00713
00714
00715 unsigned char longsize;
00716
00717 #define MYFWRITE(buffer,pieces,size,fp) if( fwrite(buffer,size,pieces,fp) != pieces ){\
00718 return BU_ERROR_FAIL;\
00719 }
00720 longsize = sizeof(long)+0x30;
00721 MYFWRITE((void *)&longsize,1,1,fp)
00722 build_MagicCode(NULL);
00723
00724 MYFWRITE((void *)&sVersionInfo,1,sizeof(sVersionInfo),fp);
00725
00726 MYFWRITE((void *)&(pBuild->cGlobalVariables),1,sizeof(unsigned long),fp);
00727 MYFWRITE((void *)&(pBuild->NodeCounter),1,sizeof(unsigned long),fp);
00728 MYFWRITE((void *)&(pBuild->StartNode),1,sizeof(unsigned long),fp);
00729 MYFWRITE((void *)&(pBuild->cbCollectedStrings),1,sizeof(unsigned long),fp);
00730 MYFWRITE((void *)pBuild->CommandArray,pBuild->NodeCounter,sizeof(cNODE),fp);
00731 MYFWRITE((void *)pBuild->StringTable,pBuild->cbCollectedStrings,sizeof(char),fp);
00732
00733
00734
00735 if( fFlag & BU_SAVE_FTABLE ){
00736 MYFWRITE((void *)&(pBuild->cbFTable),1,sizeof(unsigned long),fp);
00737 MYFWRITE((void *)pBuild->FTable,pBuild->cbFTable,sizeof(char),fp);
00738 }
00739 if( fFlag & BU_SAVE_VTABLE ){
00740 MYFWRITE((void *)&(pBuild->cbVTable),1,sizeof(unsigned long),fp);
00741 MYFWRITE((void *)pBuild->VTable,pBuild->cbVTable,sizeof(char),fp);
00742 }
00743 #undef MYFWRITE
00744 return BU_ERROR_SUCCESS;
00745 }
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763 int build_SaveCore(pBuildObject pBuild,
00764 FILE *fp
00765 ){
00766
00767
00768
00769
00770 return build_SaveCorePart(pBuild,fp,BU_SAVE_FTABLE|BU_SAVE_VTABLE);
00771 }
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 int build_SaveCode(pBuildObject pBuild,
00819 char *szFileName
00820 ){
00821
00822
00823
00824
00825 FILE *fp;
00826
00827
00828 if( ! pBuild->cbCollectedStrings )pBuild->cbCollectedStrings = 1;
00829
00830 fp = file_fopen(szFileName,"wb");
00831 if( fp == NULL )return BU_ERROR_FAIL;
00832
00833 if( pBuild->FirstUNIXline )fprintf(fp,pBuild->FirstUNIXline);
00834
00835 build_SaveCore(pBuild,fp);
00836 file_fclose(fp);
00837 return BU_ERROR_SUCCESS;
00838 }
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 void build_SaveECode(pBuildObject pBuild,
00853 char *pszInterpreter,
00854 char *szFileName
00855 ){
00856
00857
00858 FILE *fp,*fi;
00859 int ch;
00860 long lCodeStart;
00861
00862 char magics[11+sizeof(long)];
00863
00864 #if _WIN32
00865
00866 pszInterpreter = _pgmptr;
00867 #endif
00868
00869
00870 fi = file_fopen(pszInterpreter,"rb");
00871
00872 if( fi == NULL ){
00873 REPORT("",0L,BU_ERROR_ECODE_INPUT,NULL);
00874 return;
00875 }
00876
00877
00878 fp = file_fopen(szFileName,"wb");
00879 if( fp == NULL ){
00880 file_fclose(fi);
00881 REPORT("",0L,BU_ERROR_FAIL,NULL);
00882 return;
00883 }
00884
00885 while( EOF != (ch=getc(fi)) ){
00886 putc(ch,fp);
00887 }
00888 file_fclose(fi);
00889
00890 lCodeStart = ftell(fp);
00891
00892 build_SaveCore(pBuild,fp);
00893
00894
00895 strcpy(magics,"SCRIPTBASIC");
00896
00897 memcpy(magics+11,&lCodeStart,sizeof(long));
00898
00899 file_fwrite(magics,1,11+sizeof(long),fp);
00900
00901 file_fclose(fp);
00902 }
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 int build_GetExeCodeOffset(char *pszInterpreter,
00926 long *plOffset,
00927 long *plEOFfset
00928 ){
00929
00930
00931 FILE *fp;
00932 char magics[11+sizeof(long)];
00933 long lOf;
00934
00935 #if _WIN32
00936
00937 pszInterpreter = _pgmptr;
00938 #endif
00939
00940 *plOffset = *plEOFfset = 0L;
00941
00942 fp = file_fopen(pszInterpreter,"rb");
00943
00944 if( fp == NULL )return 0;
00945
00946
00947
00948 lOf = 11 + sizeof(long);
00949
00950 fseek(fp,-lOf,SEEK_END);
00951 *plEOFfset = ftell(fp) - 1;
00952
00953 file_fread(magics,1,11+sizeof(long),fp);
00954 file_fclose(fp);
00955 if( memcmp(magics,"SCRIPTBASIC",11) ){
00956 *plEOFfset = 0L;
00957 return 0L;
00958 }
00959 memcpy(plOffset,magics+11,sizeof(long));
00960 return 1;
00961 }
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981 void build_LoadCore(pBuildObject pBuild,
00982 char *szFileName,
00983 FILE *fp,
00984 long lEOFfset
00985 ){
00986
00987
00988
00989
00990 unsigned long mc;
00991 unsigned long longsize;
00992 int ch;
00993
00994 #define CORRUPTFILE {REPORT(szFileName,0L,BU_ERROR_FILE_CORRUPT,NULL);return;}
00995 #define CHECKEOF() feof(fp) || (lEOFfset && lEOFfset < ftell(fp))
00996 #define ASSERTEOF if( CHECKEOF() )CORRUPTFILE
00997
00998 ASSERTEOF
00999 longsize = ch = fgetc(fp);
01000 if( CHECKEOF() )CORRUPTFILE
01001
01002
01003
01004 if( longsize == '#' ){
01005 ch = fgetc(fp);
01006 if( ch != '!' )CORRUPTFILE
01007 while( ch != EOF && ch != '\n' )ch = fgetc(fp);
01008 if( ch == '\n' )ch = fgetc(fp);
01009 ASSERTEOF
01010 longsize = ch;
01011 }
01012 if( longsize != sizeof(long)+0x30 )CORRUPTFILE
01013
01014 mc = build_MagicCode(NULL);
01015
01016 fread((void *)&sVersionInfo,1,sizeof(sVersionInfo),fp);
01017 if(
01018 sVersionInfo.Build != SCRIPTBASIC_BUILD ||
01019 sVersionInfo.MagicCode != MAGIC_CODE ||
01020 sVersionInfo.VersionHigh != VERSION_HIGH ||
01021 sVersionInfo.VersionLow != VERSION_LOW ||
01022 sVersionInfo.MyVersionHigh != MYVERSION_HIGH ||
01023 sVersionInfo.MyVersionLow != MYVERSION_LOW ||
01024 strncmp(sVersionInfo.Variation, VARIATION, 8)
01025 )CORRUPTFILE
01026
01027 fread((void *)&(pBuild->cGlobalVariables),sizeof(unsigned long),1,fp);
01028 ASSERTEOF
01029 fread((void *)&(pBuild->NodeCounter),sizeof(unsigned long),1,fp);
01030 ASSERTEOF
01031 fread((void *)&(pBuild->StartNode),sizeof(unsigned long),1,fp);
01032 ASSERTEOF
01033
01034 pBuild->CommandArray = alloc_Alloc(sizeof(cNODE) * pBuild->NodeCounter , pBuild->pMemorySegment );
01035 if( pBuild->CommandArray == NULL ){
01036 REPORT(szFileName,0L,BU_ERROR_MEMORY_LOW,NULL);
01037 return;
01038 }
01039
01040 fread((void *)&(pBuild->cbStringTable),1,sizeof(unsigned long),fp);
01041 ASSERTEOF
01042
01043 pBuild->StringTable = alloc_Alloc(pBuild->cbStringTable ? pBuild->cbStringTable : 1 ,pBuild->pMemorySegment);
01044 if( pBuild->StringTable == NULL ){
01045 REPORT(szFileName,0L,BU_ERROR_MEMORY_LOW,NULL);
01046 return;
01047 }
01048 fread((void *)pBuild->CommandArray,pBuild->NodeCounter,sizeof(cNODE),fp);
01049 ASSERTEOF
01050 if( pBuild->cbStringTable )
01051 fread((void *)pBuild->StringTable,pBuild->cbStringTable,sizeof(char),fp);
01052
01053
01054 if( feof(fp) )return;
01055
01056 fread((void *)&(pBuild->cbFTable),1,sizeof(unsigned long),fp);
01057 if( feof(fp) ){
01058 pBuild->cbFTable = 0;
01059 return;
01060 }
01061 if( pBuild->cbFTable ){
01062 pBuild->FTable = alloc_Alloc(pBuild->cbFTable,pBuild->pMemorySegment);
01063 if( pBuild->FTable == NULL ){
01064 REPORT(szFileName,0L,BU_ERROR_MEMORY_LOW,NULL);
01065 return;
01066 }
01067 longsize=fread((void *)pBuild->FTable,sizeof(char),pBuild->cbFTable,fp);
01068 if( longsize != pBuild->cbFTable )CORRUPTFILE
01069 if( feof(fp) )return;
01070 }else pBuild->FTable = NULL;
01071
01072 fread((void *)&(pBuild->cbVTable),1,sizeof(unsigned long),fp);
01073 if( pBuild->cbVTable ){
01074 if( feof(fp) )return;
01075 pBuild->VTable = alloc_Alloc(pBuild->cbVTable,pBuild->pMemorySegment);
01076 if( pBuild->VTable == NULL ){
01077 REPORT(szFileName,0L,BU_ERROR_MEMORY_LOW,NULL);
01078 return;
01079 }
01080 }else pBuild->VTable = NULL;
01081 if( fread((void *)pBuild->VTable,sizeof(char),pBuild->cbVTable,fp) != pBuild->cbVTable)CORRUPTFILE
01082
01083 }
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094 void build_LoadCodeWithOffset(pBuildObject pBuild,
01095 char *szFileName,
01096 long lOffset,
01097 long lEOFfset
01098 ){
01099
01100
01101 FILE *fp;
01102
01103 pBuild->pMemorySegment = alloc_InitSegment(pBuild->memory_allocating_function,
01104 pBuild->memory_releasing_function);
01105 if( pBuild->pMemorySegment == NULL ){
01106 REPORT(szFileName,0L,BU_ERROR_MEMORY_LOW,NULL);
01107 return;
01108 }
01109
01110 fp = file_fopen(szFileName,"rb");
01111
01112 if( NULL == fp ){
01113
01114 REPORT(szFileName,0L,READER_ERROR_FILE_OPEN,NULL);
01115 return;
01116 }
01117 fseek(fp,lOffset,SEEK_SET);
01118 if( fp == NULL )CORRUPTFILE
01119 build_LoadCore(pBuild,szFileName,fp,lEOFfset);
01120 file_fclose(fp);
01121 return;
01122 }
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 void build_LoadCode(pBuildObject pBuild,
01134 char *szFileName
01135 ){
01136
01137
01138 build_LoadCodeWithOffset(pBuild,szFileName,0L,0L);
01139 }
01140
01141
01142
01143
01144
01145
01146
01147
01148 int build_IsFileBinaryFormat(char *szFileName
01149 ){
01150
01151
01152 FILE *fp;
01153 unsigned long mc;
01154 int ret,ch;
01155 unsigned char longsize;
01156
01157 if( szFileName == NULL )return 0;
01158 ret = 1;
01159 fp = file_fopen(szFileName,"rb");
01160 if( fp == NULL )return 0;
01161
01162 longsize = fgetc(fp);
01163 if( longsize == '#' ){
01164 ch = fgetc(fp);
01165 if( ch != '!' )ret = 0; else {
01166 while( ch != EOF && ch != '\n' )ch = fgetc(fp);
01167 if( ch == '\n' )ch = fgetc(fp);
01168 if( ch == EOF )ret = 0;
01169 longsize = ch;
01170 }
01171 }
01172 if( longsize != sizeof(long)+0x30 )ret=0;
01173
01174 mc = build_MagicCode(NULL);
01175
01176 fread((void *)&sVersionInfo,1,sizeof(sVersionInfo),fp);
01177 if(
01178 sVersionInfo.Build != SCRIPTBASIC_BUILD ||
01179 sVersionInfo.MagicCode != MAGIC_CODE ||
01180 sVersionInfo.VersionHigh != VERSION_HIGH ||
01181 sVersionInfo.VersionLow != VERSION_LOW ||
01182 sVersionInfo.MyVersionHigh != MYVERSION_HIGH ||
01183 sVersionInfo.MyVersionLow != MYVERSION_LOW ||
01184 strncmp(sVersionInfo.Variation, VARIATION, 8)
01185 )ret = 0;
01186
01187 file_fclose(fp);
01188 return ret;
01189 }
01190
01191
01192
01193
01194
01195
01196
01197 void build_pprint(pBuildObject pBuild,
01198 FILE *f
01199 ){
01200
01201
01202 unsigned long lIndex;
01203 pcNODE pThis;
01204 int i;
01205 extern LexNASymbol CSYMBOLS[];
01206
01207 fprintf(f,"Start node is %d\n",pBuild->StartNode);
01208
01209 for( lIndex = 0 ; lIndex < pBuild->NodeCounter ; lIndex ++ ){
01210 pThis = pBuild->CommandArray+lIndex;
01211 fprintf(f,"%d ",lIndex+1 );
01212
01213 if( pThis->OpCode == eNTYPE_ARR ){
01214 fprintf(f,"Array access\n");
01215 continue;
01216 }
01217 if( pThis->OpCode == eNTYPE_SAR ){
01218 fprintf(f,"Associative array access\n");
01219 continue;
01220 }
01221
01222
01223 if( pThis->OpCode == eNTYPE_LST ){
01224 fprintf(f,"List node\n");
01225 fprintf(f," car=%ld\n",pThis->Parameter.NodeList.actualm);
01226 fprintf(f," cdr=%ld\n",pThis->Parameter.NodeList.rest);
01227 continue;
01228 }
01229
01230
01231 if( pThis->OpCode == eNTYPE_FUN ){
01232 fprintf(f,"User function\n");
01233 fprintf(f," Starts at node %ld\n",pThis->Parameter.UserFunction.NodeId);
01234 fprintf(f," Actual argument list root node %ld\n",pThis->Parameter.UserFunction.Argument);
01235 continue;
01236 }
01237
01238
01239 if( pThis->OpCode == eNTYPE_LVR || pThis->OpCode == eNTYPE_GVR ){
01240 fprintf(f,"%s variable serial=%d\n", (pThis->OpCode == eNTYPE_LVR ? "local" : "global"),pThis->Parameter.Variable.Serial);
01241 continue;
01242 }
01243
01244 for( i = 0 ; CSYMBOLS[i].Symbol ; i++ )
01245 if( CSYMBOLS[i].Code == pThis->OpCode )break;
01246 if( CSYMBOLS[i].Code == pThis->OpCode ){
01247 fprintf(f," %s\n",CSYMBOLS[i].Symbol);
01248 continue;
01249 }
01250 if( pThis->OpCode == eNTYPE_DBL ){
01251 fprintf(f," Double value %lf\n",pThis->Parameter.Constant.dValue);
01252 continue;
01253 }
01254
01255 if( pThis->OpCode == eNTYPE_LNG ){
01256 fprintf(f," Long value %ld\n",pThis->Parameter.Constant.lValue);
01257 continue;
01258 }
01259
01260 if( pThis->OpCode == eNTYPE_STR ){
01261 fprintf(f," Constant string node id=%d\n", pThis->Parameter.Constant.sValue);
01262 continue;
01263 }
01264
01265 switch( pThis->OpCode ){
01266 case eNTYPE_ARR: fprintf(f,", ARRAY ACCESS\n"); break;
01267 case eNTYPE_SAR: fprintf(f,", SARAY ACCESS\n"); break;
01268 case eNTYPE_FUN: fprintf(f,", FUNCTION CALL\n"); break;
01269 case eNTYPE_LVR: fprintf(f,", LOCAL VAR\n"); break;
01270 case eNTYPE_GVR: fprintf(f,", GLOBAL VAR\n"); break;
01271 case eNTYPE_DBL: fprintf(f,", DOUBLE\n"); break;
01272 case eNTYPE_LNG: fprintf(f,", LONG\n"); break;
01273 case eNTYPE_STR: fprintf(f,", STRING\n"); break;
01274 case eNTYPE_LST: fprintf(f,", LIST\n"); break;
01275 case eNTYPE_CRG: fprintf(f,", COMMAND ARG %ld -> %ld\n", pThis->Parameter.CommandArgument.Argument.pNode,pThis->Parameter.CommandArgument.next);
01276 break;
01277
01278 default:
01279 fprintf(f,", %d\n",pThis->OpCode);
01280 }
01281 }
01282 }
01283
01284
01285
01286
01287
01288 static long build_TableItemBytes(char *SymbolName){
01289 long len;
01290
01291
01292 len = strlen(SymbolName) + 1 + sizeof(long);
01293 if (len % sizeof(long)) len += sizeof(long) - (len % sizeof(long));
01294 return len;
01295 }
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305 static void build_CountSymbolBytes(char *SymbolName, void *SymbolValue, void *f){
01306 long *pL;
01307 pL = (long *)f;
01308 *pL += build_TableItemBytes(SymbolName);
01309 }
01310
01311
01312
01313
01314
01315
01316 static void build_PutFTableItem(char *SymbolName, void *SymbolValue, void *f){
01317 pSymbolUF pF;
01318 pSymbolLongTable pT;
01319 char **pC;
01320
01321 pC = (char **)f;
01322 pF = (pSymbolUF)SymbolValue;
01323 pT = (pSymbolLongTable)*pC;
01324 pT->value = pF->node;
01325 strcpy(pT->symbol,SymbolName);
01326 *pC += build_TableItemBytes(SymbolName);
01327 }
01328
01329
01330
01331
01332
01333
01334 static void build_PutVTableItem(char *SymbolName, void *SymbolValue, void *f){
01335 pSymbolVAR pV;
01336 pSymbolLongTable pT;
01337 char **pC;
01338
01339 pC = (char **)f;
01340 pV = (pSymbolVAR)SymbolValue;
01341 pT = (pSymbolLongTable)*pC;
01342 pT->value = pV->Serial;
01343 strcpy(pT->symbol,SymbolName);
01344 *pC += build_TableItemBytes(SymbolName);
01345 }
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378 int build_CreateFTable(pBuildObject pBuild
01379 ){
01380
01381
01382 char *p;
01383
01384 pBuild->cbFTable = 0;
01385 sym_TraverseSymbolTable(pBuild->pEx->UserFunctions,
01386 build_CountSymbolBytes,
01387 &(pBuild->cbFTable));
01388 if( pBuild->cbFTable == 0 ){
01389 pBuild->FTable = NULL;
01390 return BU_ERROR_SUCCESS;
01391 }
01392 pBuild->FTable = alloc_Alloc(pBuild->cbFTable,pBuild->pMemorySegment);
01393 if( pBuild->FTable == NULL ){
01394 pBuild->cbFTable = 0;
01395 return BU_ERROR_MEMORY_LOW;
01396 }
01397
01398 p = (char *)pBuild->FTable;
01399 sym_TraverseSymbolTable(pBuild->pEx->UserFunctions,
01400 build_PutFTableItem,
01401 &p);
01402
01403 return BU_ERROR_SUCCESS;
01404 }
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436 int build_CreateVTable(pBuildObject pBuild
01437 ){
01438
01439
01440 char *p;
01441
01442 pBuild->cbVTable = 0;
01443 sym_TraverseSymbolTable(pBuild->pEx->GlobalVariables,
01444 build_CountSymbolBytes,
01445 &(pBuild->cbVTable));
01446 if( pBuild->cbVTable == 0 ){
01447 pBuild->VTable = NULL;
01448 return BU_ERROR_SUCCESS;
01449 }
01450 pBuild->VTable = alloc_Alloc(pBuild->cbVTable,pBuild->pMemorySegment);
01451 if( pBuild->VTable == NULL ){
01452 pBuild->cbVTable = 0;
01453 return BU_ERROR_MEMORY_LOW;
01454 }
01455
01456 p = (char *)pBuild->VTable;
01457 sym_TraverseSymbolTable(pBuild->pEx->GlobalVariables,
01458 build_PutVTableItem,
01459 &p);
01460
01461 return BU_ERROR_SUCCESS;
01462 }
01463
01464
01465
01466
01467
01468
01469
01470 static long build_LookupFunctionOrVariable(pSymbolLongTable Table,
01471 unsigned long cbTable,
01472 char *s){
01473 char *p;
01474 char *SymbolName;
01475 long TableItemLen;
01476
01477 p = (char *)Table;
01478 while( cbTable ){
01479 SymbolName = p + sizeof(long);
01480 if( ! strcmp(s,SymbolName) ) return Table->value;
01481 TableItemLen = build_TableItemBytes(SymbolName);
01482 p += TableItemLen;
01483 cbTable -= TableItemLen;
01484 Table = (pSymbolLongTable)p;
01485 }
01486 return 0;
01487 }
01488
01489
01490
01491
01492 long build_LookupFunctionByName(pBuildObject pBuild,
01493 char *s
01494 ){
01495
01496
01497 return build_LookupFunctionOrVariable(pBuild->FTable,pBuild->cbFTable,s);
01498 }
01499
01500
01501
01502
01503 long build_LookupVariableByName(pBuildObject pBuild,
01504 char *s
01505 ){
01506
01507
01508 return build_LookupFunctionOrVariable(pBuild->VTable,pBuild->cbVTable,s);
01509 }