0001
0002
0003 #include <stdio.h>
0004 #include <stdlib.h>
0005 #include <string.h>
0006 #include <stdarg.h>
0007
0008 #if defined(_MSC_VER) && defined(_DEBUG)
0009 #include <crtdbg.h>
0010 #include <conio.h>
0011 #endif
0012 #include <pscript.h>
0013 #include <psstdblob.h>
0014 #include <psstdsystem.h>
0015 #include <psstdio.h>
0016 #include <psstdmath.h>
0017 #include <psstdstring.h>
0018 #include <psstdaux.h>
0019 #include <psstdexutil.h>
0020
0021 #ifdef PSUNICODE
0022 #define scfprintf fwprintf
0023 #define scvprintf vfwprintf
0024 #else
0025 #define scfprintf fprintf
0026 #define scvprintf vfprintf
0027 #endif
0028
0029
0030 void PrintVersionInfos();
0031
0032 #if defined(_MSC_VER) && defined(_DEBUG)
0033 int MemAllocHook( int allocType, void *userData, size_t size, int blockType,
0034 long requestNumber, const unsigned char *filename, int lineNumber)
0035 {
0036
0037 return 1;
0038 }
0039 #endif
0040
0041
0042 PSInteger quit(HPSCRIPTVM v)
0043 {
0044 int *done;
0045 ps_getuserpointer(v,-1,(PSUserPointer*)&done);
0046 *done=1;
0047 return 0;
0048 }
0049
0050 void printfunc(HPSCRIPTVM PS_UNUSED_ARG(v),const PSChar *s,...)
0051 {
0052 va_list vl;
0053 va_start(vl, s);
0054 scvprintf(stdout, s, vl);
0055 va_end(vl);
0056 (void)v;
0057 }
0058
0059 void errorfunc(HPSCRIPTVM PS_UNUSED_ARG(v),const PSChar *s,...)
0060 {
0061 va_list vl;
0062 va_start(vl, s);
0063 scvprintf(stderr, s, vl);
0064 va_end(vl);
0065 }
0066
0067 void PrintVersionInfos()
0068 {
0069 scfprintf(stdout,_SC("%s %s (%d bits)\n"),PSCRIPT_VERSION,PSCRIPT_COPYRIGHT,((int)(sizeof(PSInteger)*8)));
0070 }
0071
0072 void PrintUsage()
0073 {
0074 scfprintf(stderr,_SC("usage: ps <options> <scriptpath [args]>.\n")
0075 _SC("Available options are:\n")
0076 _SC(" -c compiles the file to bytecode(default output 'out.cnut')\n")
0077 _SC(" -o specifies output file for the -c option\n")
0078 _SC(" -c compiles only\n")
0079 _SC(" -d generates debug infos\n")
0080 _SC(" -v displays version infos\n")
0081 _SC(" -h prints help\n"));
0082 }
0083
0084 #define _INTERACTIVE 0
0085 #define _DONE 2
0086 #define _ERROR 3
0087
0088 int getargs(HPSCRIPTVM v,int argc, char* argv[],PSInteger *retval)
0089 {
0090 int i;
0091 int compiles_only = 0;
0092 #ifdef PSUNICODE
0093 static PSChar temp[500];
0094 #endif
0095 char * output = NULL;
0096 *retval = 0;
0097 if(argc>1)
0098 {
0099 int arg=1,exitloop=0;
0100
0101 while(arg < argc && !exitloop)
0102 {
0103
0104 if(argv[arg][0]=='-')
0105 {
0106 switch(argv[arg][1])
0107 {
0108 case 'd':
0109 ps_enabledebuginfo(v,1);
0110 break;
0111 case 'c':
0112 compiles_only = 1;
0113 break;
0114 case 'o':
0115 if(arg < argc) {
0116 arg++;
0117 output = argv[arg];
0118 }
0119 break;
0120 case 'v':
0121 PrintVersionInfos();
0122 return _DONE;
0123
0124 case 'h':
0125 PrintVersionInfos();
0126 PrintUsage();
0127 return _DONE;
0128 default:
0129 PrintVersionInfos();
0130 scprintf(_SC("unknown prameter '-%c'\n"),argv[arg][1]);
0131 PrintUsage();
0132 *retval = -1;
0133 return _ERROR;
0134 }
0135 }else break;
0136 arg++;
0137 }
0138
0139
0140
0141 if(arg<argc) {
0142 const PSChar *filename=NULL;
0143 #ifdef PSUNICODE
0144 mbstowcs(temp,argv[arg],strlen(argv[arg]));
0145 filename=temp;
0146 #else
0147 filename=argv[arg];
0148 #endif
0149
0150 arg++;
0151
0152
0153
0154
0155
0156
0157 if(compiles_only) {
0158 if(PS_SUCCEEDED(psstd_loadfile(v,filename,PSTrue))){
0159 const PSChar *outfile = _SC("out.cnut");
0160 if(output) {
0161 #ifdef PSUNICODE
0162 int len = (int)(strlen(output)+1);
0163 mbstowcs(ps_getscratchpad(v,len*sizeof(PSChar)),output,len);
0164 outfile = ps_getscratchpad(v,-1);
0165 #else
0166 outfile = output;
0167 #endif
0168 }
0169 if(PS_SUCCEEDED(psstd_writeclosuretofile(v,outfile)))
0170 return _DONE;
0171 }
0172 }
0173 else {
0174
0175
0176
0177 if(PS_SUCCEEDED(psstd_loadfile(v,filename,PSTrue))) {
0178 int callargs = 1;
0179 ps_pushroottable(v);
0180 for(i=arg;i<argc;i++)
0181 {
0182 const PSChar *a;
0183 #ifdef PSUNICODE
0184 int alen=(int)strlen(argv[i]);
0185 a=ps_getscratchpad(v,(int)(alen*sizeof(PSChar)));
0186 mbstowcs(ps_getscratchpad(v,-1),argv[i],alen);
0187 ps_getscratchpad(v,-1)[alen] = _SC('\0');
0188 #else
0189 a=argv[i];
0190 #endif
0191 ps_pushstring(v,a,-1);
0192 callargs++;
0193
0194 }
0195 if(PS_SUCCEEDED(ps_call(v,callargs,PSTrue,PSTrue))) {
0196 PSObjectType type = ps_gettype(v,-1);
0197 if(type == OT_INTEGER) {
0198 *retval = type;
0199 ps_getinteger(v,-1,retval);
0200 }
0201 return _DONE;
0202 }
0203 else{
0204 return _ERROR;
0205 }
0206
0207 }
0208 }
0209
0210 {
0211 const PSChar *err;
0212 ps_getlasterror(v);
0213 if(PS_SUCCEEDED(ps_getstring(v,-1,&err))) {
0214 scprintf(_SC("Error [%s]\n"),err);
0215 *retval = -2;
0216 return _ERROR;
0217 }
0218 }
0219
0220 }
0221 }
0222
0223 return _INTERACTIVE;
0224 }
0225
0226 void Interactive(HPSCRIPTVM v)
0227 {
0228
0229 #define MAXINPUT 1024
0230 PSChar buffer[MAXINPUT];
0231 PSInteger blocks =0;
0232 PSInteger string=0;
0233 PSInteger retval=0;
0234 PSInteger done=0;
0235 PrintVersionInfos();
0236
0237 ps_pushroottable(v);
0238 ps_pushstring(v,_SC("quit"),-1);
0239 ps_pushuserpointer(v,&done);
0240 ps_newclosure(v,quit,1);
0241 ps_setparamscheck(v,1,NULL);
0242 ps_newslot(v,-3,PSFalse);
0243 ps_pop(v,1);
0244
0245 while (!done)
0246 {
0247 PSInteger i = 0;
0248 scprintf(_SC("\nps>"));
0249 for(;;) {
0250 int c;
0251 if(done)return;
0252 c = getchar();
0253 if (c == _SC('\n')) {
0254 if (i>0 && buffer[i-1] == _SC('\\'))
0255 {
0256 buffer[i-1] = _SC('\n');
0257 }
0258 else if(blocks==0)break;
0259 buffer[i++] = _SC('\n');
0260 }
0261 else if (c==_SC('}')) {blocks--; buffer[i++] = (PSChar)c;}
0262 else if(c==_SC('{') && !string){
0263 blocks++;
0264 buffer[i++] = (PSChar)c;
0265 }
0266 else if(c==_SC('"') || c==_SC('\'')){
0267 string=!string;
0268 buffer[i++] = (PSChar)c;
0269 }
0270 else if (i >= MAXINPUT-1) {
0271 scfprintf(stderr, _SC("ps : input line too long\n"));
0272 break;
0273 }
0274 else{
0275 buffer[i++] = (PSChar)c;
0276 }
0277 }
0278 buffer[i] = _SC('\0');
0279
0280 if(buffer[0]==_SC('=')){
0281 scsprintf(ps_getscratchpad(v,MAXINPUT),(size_t)MAXINPUT,_SC("return (%s)"),&buffer[1]);
0282 memcpy(buffer,ps_getscratchpad(v,-1),(scstrlen(ps_getscratchpad(v,-1))+1)*sizeof(PSChar));
0283 retval=1;
0284 }
0285 i=scstrlen(buffer);
0286 if(i>0){
0287 PSInteger oldtop=ps_gettop(v);
0288 if(PS_SUCCEEDED(ps_compilebuffer(v,buffer,i,_SC("interactive console"),PSTrue))){
0289 ps_pushroottable(v);
0290 if(PS_SUCCEEDED(ps_call(v,1,retval,PSTrue)) && retval){
0291 scprintf(_SC("\n"));
0292 ps_pushroottable(v);
0293 ps_pushstring(v,_SC("print"),-1);
0294 ps_get(v,-2);
0295 ps_pushroottable(v);
0296 ps_push(v,-4);
0297 ps_call(v,2,PSFalse,PSTrue);
0298 retval=0;
0299 scprintf(_SC("\n"));
0300 }
0301 }
0302
0303 ps_settop(v,oldtop);
0304 }
0305 }
0306 }
0307
0308 int main(int argc, char* argv[])
0309 {
0310 HPSCRIPTVM v;
0311 PSInteger retval = 0;
0312 #if defined(_MSC_VER) && defined(_DEBUG)
0313 _CrtSetAllocHook(MemAllocHook);
0314 #endif
0315
0316 v=ps_open(1024);
0317 ps_setprintfunc(v,printfunc,errorfunc);
0318
0319 ps_pushroottable(v);
0320
0321 psstd_register_bloblib(v);
0322 psstd_register_iolib(v);
0323 psstd_register_systemlib(v);
0324 psstd_register_mathlib(v);
0325 psstd_register_stringlib(v);
0326 psstd_register_exutillib(v);
0327
0328
0329
0330 psstd_seterrorhandlers(v);
0331
0332
0333 switch(getargs(v,argc,argv,&retval))
0334 {
0335 case _INTERACTIVE:
0336 Interactive(v);
0337 break;
0338 case _DONE:
0339 case _ERROR:
0340 default:
0341 break;
0342 }
0343
0344 ps_close(v);
0345
0346 #if defined(_MSC_VER) && defined(_DEBUG)
0347 _getch();
0348 _CrtMemDumpAllObjectsSince( NULL );
0349 #endif
0350 return retval;
0351 }
0352