![]() |
Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members
Parser.cppGo to the documentation of this file.00001 #include <stdio.h> 00002 #include <string.h> 00003 #include <sys/types.h> 00004 #include <sys/stat.h> 00005 #include <unistd.h> 00006 #include <stdlib.h> 00007 #include <ctype.h> 00008 #include <stdarg.h> 00009 00010 #include "a.h" 00011 00012 #include "ParserIO.h" 00013 #include "Parser.h" 00014 00015 static 00016 char applesoft_tokens[][8]= 00017 { 00018 "END", "FOR", "NEXT", "DATA", "INPUT", "DEL", "DIM", "READ", 00019 "GR", "TEXT", "PR#", "IN#", "CALL", "PLOT", "HLIN", "VLIN", 00020 00021 "HGR2", "HGR", "HCOLOR=", "HPLOT", "DRAW", "XDRAW", "HTAB", "HOME", 00022 "ROT=", "SCALE=", "SHLOAD", "TRACE", "NOTRACE", "NORMAL", "INVERSE", "FLASH", 00023 00024 "COLOR=", "POP", "VTAB", "HIMEM:", "LOMEM:", "ONERR", "RESUME", "RECALL", 00025 "STORE", "SPEED=", "LET", "GOTO", "RUN", "IF", "RESTORE", "&", 00026 00027 "GOSUB", "RETURN", "REM", "STOP", "ON", "WAIT", "LOAD", "SAVE", 00028 "DEF", "POKE", "PRINT", "CONT", "LIST", "CLEAR", "GET", "NEW", 00029 00030 "TAB(", "TO", "FN", "SPC(", "THEN", "AT", "NOT", "STEP", 00031 "+", "-", "*", "/", "^", "AND", "OR", ">", 00032 "=", "<", "SGN", "INT", "ABS", "USR", "FRE", "SCRN(", 00033 "PDL", "POS", "SQR", "RND", "LOG", "EXP", "COS", "SIN", 00034 "TAN", "ATN", "PEEK", "LEN", "STR$", "VAL", "ASC", "CHR$", 00035 "LEFT$", "RIGHT$", "MID$", "", "", "", "", "", 00036 "", "", "", "", "", "", "", "", 00037 "", "", "", "", "", "(", "(", "(" 00038 }; 00039 00040 00041 Parser::Parser() 00042 :m_pclParserIO(NULL) 00043 ,m_fil(NULL) 00044 ,m_linebase(NULL) 00045 ,m_current_line(NULL) 00046 ,m_next_line(NULL) 00047 ,m_onerror(NULL) 00048 ,m_nextbase(NULL) 00049 ,m_database(NULL) 00050 ,m_current_data(NULL) 00051 ,m_subbase(NULL) 00052 ,m_funcbase(NULL) 00053 ,m_placeholder(NULL) 00054 ,m_running(0) 00055 ,m_the_ptr(0) 00056 ,m_file_read(0) 00057 ,m_file_write(0) 00058 ,m_tab_pos(0) 00059 ,m_dataptr(0) 00060 ,m_variablebase(NULL) 00061 ,m_openbase(NULL) 00062 ,m_obufptr(0) 00063 ,m_load_ok(1) 00064 { 00065 *m_run_program = 0; 00066 *m_the_str = 0; 00067 *m_programname = 0; 00068 *m_program_cwd = 0; 00069 *m_obuf = 0; 00070 } 00071 00072 00073 Parser::Parser(char *program) 00074 :m_pclParserIO(NULL) 00075 ,m_tab_pos(0) 00076 ,m_obufptr(0) 00077 { 00078 strcpy(m_run_program, program); 00079 } 00080 00081 00082 Parser::~Parser() 00083 { 00084 finish(); 00085 } 00086 00087 00088 void Parser::strupr(char *s) 00089 { 00090 int i; 00091 00092 for (i = 0; i < (int)strlen(s); i++) 00093 if (s[i] >= 'a' && s[i] <= 'z') 00094 s[i] -= 32; 00095 } 00096 00097 00098 void Parser::addlist(void *_base,void *_item) 00099 { 00100 LINE **base = (LINE **)_base; 00101 LINE *item = (LINE *)_item; 00102 LINE *q; 00103 00104 item -> next = NULL; 00105 q = *base; 00106 if (!q) 00107 *base = item; 00108 else 00109 { 00110 while (q -> next) 00111 q = q -> next; 00112 q -> next = item; 00113 } 00114 } 00115 00116 void Parser::removelist(void *_base,void *_item) 00117 { 00118 LINE **base = (LINE **)_base; 00119 LINE *item = (LINE *)_item; 00120 LINE *q,*prev = NULL; 00121 00122 if (item == *base) 00123 *base = item -> next; 00124 else 00125 { 00126 for (q = *base; q; q = q -> next) 00127 if (item == q) 00128 { 00129 prev -> next = item -> next; 00130 break; 00131 } 00132 else 00133 prev = q; 00134 } 00135 } 00136 00137 00138 void Parser::verify_filename(char *s) 00139 { 00140 int i; 00141 00142 if (s) 00143 { 00144 for (i = 0; i < (int)strlen(s); i++) 00145 { 00146 switch (s[i]) 00147 { 00148 case '/': 00149 s[i] = '_'; 00150 } 00151 } 00152 } 00153 } 00154 00155 00156 void Parser::read_file(char *filename) 00157 { 00158 FILE *fil; 00159 LINE *ln; 00160 int i,x; 00161 short size; 00162 short q; // quote 00163 short ifc; 00164 short data; 00165 short rem; 00166 short ok = 1; 00167 short uc = 0; 00168 unsigned char c_length; 00169 unsigned char c_eight; 00170 unsigned char c_line1; 00171 unsigned char c_line2; 00172 unsigned char c; 00173 char slask[1024]; 00174 char filename_uc[100]; 00175 00176 if (!strcasecmp(filename,"basefix")) 00177 return; 00178 00179 verify_filename( filename ); 00180 strcpy(filename_uc, filename); 00181 strupr(filename_uc); 00182 m_load_ok = 0; 00183 00184 if (*filename_uc < 'A' || *filename_uc > 'Z') 00185 { 00186 fprintf(stderr,"Illegal filename '%s'\n",filename); 00187 return; 00188 } 00189 00190 strcpy(m_programname,filename); 00191 getcwd(m_program_cwd,200); 00192 fprintf(stderr,"*** Current program: '%s' ***\n",m_programname); 00193 fprintf(stderr,"getcwd() == '%s'\n",m_program_cwd); 00194 00195 sprintf(slask,"%s.txt",filename); 00196 fil = fopen(slask,"rt"); 00197 if (!fil) 00198 { 00199 sprintf(slask,"%s.txt",filename_uc); 00200 fil = fopen(slask,"rt"); 00201 if (fil) 00202 uc++; 00203 } 00204 if (!fil) 00205 { 00206 sprintf(slask,"../ea.master/%s.txt",filename); 00207 fil = fopen(slask,"rt"); 00208 if (!fil) 00209 { 00210 sprintf(slask,"../ea.master/%s.txt",filename_uc); 00211 fil = fopen(slask,"rt"); 00212 if (fil) 00213 uc++; 00214 } 00215 if (fil) 00216 { 00217 fclose(fil); 00218 chdir("../ea.master"); 00219 sprintf(slask,"%s.txt",filename); 00220 fil = fopen(slask,"rt"); 00221 if (!fil) 00222 { 00223 sprintf(slask,"%s.txt",filename_uc); 00224 fil = fopen(slask,"rt"); 00225 if (fil) 00226 uc++; 00227 } 00228 } 00229 } 00230 if (uc) 00231 strcpy(m_programname,filename_uc); 00232 if (fil) // text file open ok 00233 { 00234 fprintf(stderr," ** loading text file '%s'\n",slask); 00235 fgets(slask,1024,fil); 00236 while (!feof(fil)) 00237 { 00238 slask[strlen(slask) - 1] = 0; 00239 i = 0; 00240 while (slask[i] && (slask[i] == ' ' || slask[i] == 9)) 00241 i++; 00242 00243 ln = new LINE; 00244 if (isdigit(slask[i])) 00245 { 00246 x = i; 00247 while (isdigit(slask[i])) 00248 i++; 00249 slask[i++] = 0; 00250 ln -> line = atoi(slask + x); 00251 while (slask[i] && (slask[i] == ' ' || slask[i] == 9)) 00252 i++; 00253 } 00254 else 00255 { 00256 ln -> line = -1; 00257 } 00258 ln -> the_str = new char[strlen(slask + i) + 1]; 00259 strcpy(ln -> the_str,slask + i); 00260 addlist(&m_linebase,ln); 00261 00262 if (!strncasecmp(ln -> the_str,"data ",5)) 00263 { 00264 strcpy(m_the_str,ln -> the_str); 00265 m_the_ptr = 0; 00266 m_current_line = ln; 00267 if (yyparse(this)) 00268 { 00269 m_next_line = NULL; 00270 ok = 0; 00271 } 00272 } 00273 00274 fgets(slask,1024,fil); 00275 } 00276 fclose(fil); 00277 m_load_ok = ok; 00278 } 00279 else 00280 { 00281 fil = fopen(filename,"rb"); 00282 if (!fil) 00283 { 00284 fil = fopen(filename_uc,"rb"); 00285 if (fil) 00286 uc++; 00287 } 00288 if (!fil) 00289 { 00290 sprintf(slask,"../ea.master/%s",filename); 00291 fil = fopen(slask,"rb"); 00292 if (!fil) 00293 { 00294 sprintf(slask,"../ea.master/%s",filename_uc); 00295 fil = fopen(slask,"rb"); 00296 if (fil) 00297 uc++; 00298 } 00299 if (fil) 00300 { 00301 fclose(fil); 00302 chdir("../ea.master"); // magic 00303 fil = fopen(filename,"rb"); 00304 if (!fil) 00305 { 00306 fil = fopen(filename_uc,"rb"); 00307 if (fil) 00308 uc++; 00309 } 00310 } 00311 } 00312 if (uc) 00313 strcpy(m_programname,filename_uc); 00314 if (fil) 00315 { 00316 fprintf(stderr," ** loading binary file '%s'\n",m_programname); 00317 // 2 bytes size 00318 fread(&size,1,2,fil); 00319 fprintf(stderr," size %d\n",size); 00320 while (!feof(fil)) 00321 { 00322 // 1 byte length, 1 byte == 8? 00323 fread(&c_length,1,1,fil); 00324 fread(&c_eight,1,1,fil); 00325 if (!c_eight) 00326 { 00327 break; 00328 } 00329 // 2 bytes line number 00330 fread(&c_line1,1,1,fil); 00331 fread(&c_line2,1,1,fil); 00332 ln = new LINE; //(LINE *)malloc(sizeof(LINE)); 00333 ln -> line = (((int)c_line2) << 8) + c_line1; 00334 *slask = 0; 00335 q = 0; 00336 ifc = 0; 00337 data = 0; 00338 rem = 0; 00339 00340 // line data 00341 fread(&c,1,1,fil); 00342 while (c && !feof(fil)) 00343 { 00344 if (c >= 0x80) 00345 { 00346 if (c == 0x83) // Data 00347 data = 1; 00348 if (c == 0xad) // If 00349 ifc = 1; 00350 if (c == 0xb2) // Rem 00351 rem = 1; 00352 if (ifc && *slask && (c == 0xc4 || c == 0xab)) // Then / Goto 00353 { 00354 ln -> the_str = new char[strlen(slask) + 1]; //(char *)malloc(strlen(slask) + 1); 00355 strcpy(ln -> the_str,slask); 00356 if (*slask) 00357 { 00358 addlist(&m_linebase,ln); 00359 } else 00360 delete ln; //free(ln); 00361 if (data && *slask) 00362 { 00363 strcpy(m_the_str,slask); 00364 m_the_ptr = 0; 00365 m_current_line = ln; 00366 if (yyparse(this)) 00367 { 00368 m_next_line = NULL; 00369 ok = 0; 00370 } 00371 } 00372 00373 ln = new LINE; //(LINE *)malloc(sizeof(LINE)); 00374 ln -> line = -1; 00375 *slask = 0; 00376 q = 0; 00377 ifc = 0; 00378 data = 0; 00379 } 00380 if (strlen(slask) + strlen(applesoft_tokens[c - 0x80]) < 1023) 00381 sprintf(slask + strlen(slask)," %s ",applesoft_tokens[c - 0x80]); 00382 } 00383 else 00384 if (c == ':' && !q && !rem) 00385 { 00386 ln -> the_str = new char[strlen(slask) + 1]; //(char *)malloc(strlen(slask) + 1); 00387 strcpy(ln -> the_str,slask); 00388 if (*slask) 00389 { 00390 addlist(&m_linebase,ln); 00391 } else 00392 delete ln; //free(ln); 00393 if (data && *slask) 00394 { 00395 strcpy(m_the_str,slask); 00396 m_the_ptr = 0; 00397 m_current_line = ln; 00398 if (yyparse(this)) 00399 { 00400 m_next_line = NULL; 00401 ok = 0; 00402 } 00403 } 00404 00405 ln = new LINE; //(LINE *)malloc(sizeof(LINE)); 00406 ln -> line = -1; 00407 *slask = 0; 00408 q = 0; 00409 ifc = 0; 00410 data = 0; 00411 } 00412 else 00413 { 00414 if (rem && (c == 13 || c == 10)) 00415 c = '_'; 00416 if (strlen(slask) + 1 < 1023) 00417 sprintf(slask + strlen(slask),"%c",c); 00418 if (c == 34) 00419 q = !q; 00420 } 00421 00422 fread(&c,1,1,fil); 00423 } // while (c && !feof(fil)) 00424 00425 ln -> the_str = new char[strlen(slask) + 1]; //(char *)malloc(strlen(slask) + 1); 00426 strcpy(ln -> the_str,slask); 00427 if (*slask) 00428 { 00429 addlist(&m_linebase,ln); 00430 } else 00431 delete ln; //free(ln); 00432 if (data && *slask) 00433 { 00434 strcpy(m_the_str,slask); 00435 m_the_ptr = 0; 00436 m_current_line = ln; 00437 if (yyparse(this)) 00438 { 00439 m_next_line = NULL; 00440 ok = 0; 00441 } 00442 } 00443 } // while (!feof(fil)) 00444 fclose(fil); 00445 m_load_ok = ok; 00446 00447 if (ok) 00448 write_file(); 00449 } 00450 else 00451 { 00452 fprintf(stderr,"Couldn't open '%s'...\n",filename); 00453 // exit(-1); 00454 } 00455 } 00456 } 00457 00458 void Parser::write_file() 00459 { 00460 FILE *fil; 00461 LINE *ln; 00462 char slask[200]; 00463 00464 if (!*m_programname) 00465 return; 00466 00467 if (!m_load_ok) 00468 return; 00469 00470 sprintf(slask,"%s.txt",m_programname); 00471 if ((fil = fopen(slask,"wt")) != NULL) 00472 { 00473 for (ln = m_linebase; ln; ln = ln -> next) 00474 { 00475 if (ln -> line > -1) 00476 fprintf(fil,"%5d %s\n",ln -> line,ln -> the_str); 00477 else 00478 fprintf(fil," %s\n",ln -> the_str); 00479 } 00480 fclose(fil); 00481 } 00482 } 00483 00484 VARIABLE *Parser::reg_variable(char *name,EXPRLIST *p) 00485 { 00486 VARIABLE *v; 00487 int i; 00488 char type[2]; 00489 00490 if (*name != '$') // not a function (def fn) 00491 { 00492 switch (name[strlen(name) - 1]) 00493 { 00494 case '$': 00495 strcpy(type,"$"); 00496 name[strlen(name) - 1] = 0; 00497 break; 00498 case '%': 00499 strcpy(type,"%"); 00500 name[strlen(name) - 1] = 0; 00501 break; 00502 default: 00503 *type = 0; 00504 } 00505 name[2] = 0; 00506 strcat(name,type); 00507 } 00508 00509 if (p) 00510 { 00511 strcat(name,"("); 00512 for (i = 0; i < p -> qty; i++) 00513 { 00514 if (i) 00515 strcat(name,","); 00516 sprintf(name + strlen(name),"%d",(int)(p -> values[i] + 0.01)); 00517 } 00518 strcat(name,")"); 00519 } 00520 00521 for (v = m_variablebase; v; v = v -> next) 00522 { 00523 if (!strcmp(v -> name,name)) 00524 break; 00525 } 00526 if (!v) 00527 { 00528 v = new VARIABLE; //(VARIABLE *)malloc(sizeof(VARIABLE)); 00529 if (!v) 00530 { 00531 fprintf(stderr,"malloc failed\n"); 00532 exit(-1); 00533 } 00534 strcpy(v -> name,name); 00535 v -> ivalue = 0; 00536 v -> value = v -> fnvalue = 0; 00537 *v -> svalue = 0; 00538 v -> next = m_variablebase; 00539 m_variablebase = v; 00540 } 00541 return v; 00542 } 00543 00544 00545 void Parser::text_output(char *s) 00546 { 00547 OPEN *o; 00548 char *cmd; 00549 char *arg; 00550 char *option; 00551 long offset; 00552 int i; 00553 short cmnum; 00554 short option_s; 00555 short option_d; 00556 short option_l; 00557 short option_r; 00558 char slask[1024]; 00559 00560 if (*s == 4) // CHR$(4) - dos command 00561 { 00562 if (s[strlen(s) - 1] == '\n'); 00563 s[strlen(s) - 1] = 0; 00564 m_file_read = 0; 00565 m_file_write = 0; 00566 m_fil = NULL; 00567 cmd = strtok(s + 1," "); 00568 if (!cmd) 00569 { 00570 #ifdef DEBUG 00571 fprintf(stderr," * Empty CHR$(4)\n"); 00572 #endif 00573 return; 00574 } 00575 arg = strtok(NULL,","); 00576 #ifdef DEBUG 00577 fprintf(stderr," * file command '%s' argument '%s'\n",cmd,arg); 00578 #endif 00579 if (!strcmp(cmd,"RUN")) 00580 cmnum = 1; 00581 else 00582 if (!strcmp(cmd,"OPEN")) 00583 cmnum = 2; 00584 else 00585 if (!strcmp(cmd,"CLOSE")) 00586 cmnum = 3; 00587 else 00588 if (!strcmp(cmd,"READ")) 00589 cmnum = 4; 00590 else 00591 if (!strcmp(cmd,"WRITE")) 00592 cmnum = 5; 00593 else 00594 if (!strcmp(cmd,"DELETE")) 00595 cmnum = 6; 00596 else 00597 { 00598 fprintf(stderr,"##############################################\n"); 00599 fprintf(stderr,"#### implement dos command\n"); 00600 fprintf(stderr,"#### cmd '%s' arg '%s'\n",cmd,arg); 00601 cmnum = 0; 00602 } 00603 00604 option = strtok(NULL,","); 00605 option_s = -1; 00606 option_d = -1; 00607 option_l = -1; 00608 option_r = -1; 00609 while (option) 00610 { 00611 #ifdef DEBUG 00612 fprintf(stderr," option '%s'\n",option); 00613 #endif 00614 if (!cmnum) 00615 { 00616 fprintf(stderr,"#### cmd '%s' arg '%s' option '%s'\n",cmd,arg,option); 00617 } 00618 else 00619 switch (*option) 00620 { 00621 case 'S': 00622 option_s = atoi(option + 1); 00623 break; 00624 case 'D': 00625 option_d = atoi(option + 1); 00626 break; 00627 case 'L': 00628 option_l = atoi(option + 1); 00629 break; 00630 case 'R': 00631 option_r = atoi(option + 1); 00632 break; 00633 default: 00634 fprintf(stderr,"#### cmd '%s' arg '%s' option '%s'\n",cmd,arg,option); 00635 fprintf(stderr,"##############################################\n"); 00636 } 00637 option = strtok(NULL,","); 00638 } // while (option) 00639 00640 if (!cmnum) 00641 { 00642 fprintf(stderr,"##############################################\n"); 00643 } 00644 00645 if (!m_running) 00646 return; 00647 00648 switch (cmnum) 00649 { 00650 case 1: // run 00651 verify_filename( arg ); 00652 fprintf(stderr," * RUN '%s'\n",arg); 00653 strcpy(m_run_program,arg); 00654 m_next_line = NULL; 00655 break; 00656 case 2: // open ,S ,D ,L 00657 verify_filename( arg ); 00658 for (o = m_openbase; o; o = o -> next) 00659 if (!strcmp(o -> name,arg)) 00660 break; 00661 if (o) 00662 { 00663 // fprintf(stderr," *** FILE already OPEN\n"); 00664 } 00665 else 00666 { 00667 o = new OPEN; //(OPEN *)malloc(sizeof(OPEN)); 00668 o -> fil = fopen(arg,"r+b"); 00669 if (!o -> fil) 00670 o -> fil = fopen(arg,"w+b"); 00671 if (!o -> fil) 00672 { 00673 fprintf(stderr," *** OPEN '%s' failed\n",arg); 00674 m_next_line = m_onerror; 00675 delete o; //free(o); 00676 } 00677 else 00678 { 00679 strcpy(o -> name,arg); 00680 stat(arg,&o -> file_stat); 00681 o -> option_s = option_s; 00682 o -> option_d = option_d; 00683 o -> option_l = option_l; 00684 o -> option_r = 0; 00685 addlist(&m_openbase,o); 00686 } 00687 } 00688 break; 00689 case 3: // close 00690 if (arg) 00691 { 00692 verify_filename( arg ); 00693 for (o = m_openbase; o; o = o -> next) 00694 if (!strcmp(o -> name,arg)) 00695 break; 00696 if (!o) 00697 fprintf(stderr," *** FILE not OPEN (CLOSE)\n"); 00698 else 00699 { 00700 fclose(o -> fil); 00701 removelist(&m_openbase,o); 00702 delete o; //free(o); 00703 } 00704 } 00705 else 00706 { 00707 while (m_openbase) 00708 { 00709 o = m_openbase; 00710 fclose(o -> fil); 00711 removelist(&m_openbase,o); 00712 delete o; //free(o); 00713 } 00714 } 00715 break; 00716 case 4: // read ,R 00717 verify_filename( arg ); 00718 for (o = m_openbase; o; o = o -> next) 00719 if (!strcmp(o -> name,arg)) 00720 break; 00721 if (!o) 00722 fprintf(stderr," *** FILE not OPEN (READ)\n"); 00723 else 00724 { 00725 if (option_r > -1) 00726 { 00727 o -> option_r = option_r; 00728 offset = (long)o -> option_l * (long)o -> option_r; 00729 if (offset > o -> file_stat.st_size) 00730 m_next_line = m_onerror; 00731 // fprintf(stderr," * READ '%s' ,L%d ,R%d Offset 0x%04lx\n",arg,o -> option_l,o -> option_r,offset); 00732 if (fseek(o -> fil,offset,SEEK_SET)) 00733 m_next_line = m_onerror; 00734 } 00735 m_file_read = 1; 00736 m_fil = o -> fil; 00737 } 00738 break; 00739 case 5: // write ,R 00740 verify_filename( arg ); 00741 for (o = m_openbase; o; o = o -> next) 00742 if (!strcmp(o -> name,arg)) 00743 break; 00744 if (!o) 00745 fprintf(stderr," *** FILE not OPEN (WRITE)\n"); 00746 else 00747 { 00748 #ifdef DEBUG 00749 fprintf(stderr," * Write to file '%s'\n",o -> name); 00750 #endif 00751 if (option_r > -1) 00752 { 00753 o -> option_r = option_r; 00754 offset = (long)o -> option_l * (long)o -> option_r; 00755 #ifdef DEBUG 00756 fprintf(stderr," * WRITE '%s' ,L%d ,R%d Offset 0x%04lx\n",arg,o -> option_l,o -> option_r,offset); 00757 #endif 00758 if (fseek(o -> fil,offset,SEEK_SET)) 00759 m_next_line = m_onerror; 00760 } 00761 m_file_write = 1; 00762 m_fil = o -> fil; 00763 #ifdef DEBUG 00764 fprintf(stderr," * ...\n"); 00765 #endif 00766 } 00767 break; 00768 case 6: // delete 00769 verify_filename( arg ); 00770 unlink(arg); 00771 break; 00772 00773 default: 00774 break; 00775 } // switch (cmnum) 00776 00777 } 00778 else 00779 { 00780 if (m_fil && m_file_write) 00781 { 00782 if (s[strlen(s) - 1] == 0x0a) 00783 s[strlen(s) - 1] = 0x8d; 00784 fwrite(s,strlen(s),1,m_fil); 00785 } 00786 else 00787 if (m_pclParserIO) // callbacks class 00788 { 00789 int l = strlen(s); 00790 00791 if (m_obufptr + l >= OBUFSIZE - 1) 00792 { 00793 flush_obuf(); 00794 } 00795 memmove(m_obuf + m_obufptr, s, l); 00796 m_obufptr += l; 00797 } 00798 else // stdout 00799 { 00800 fprintf(stderr,"#### USE PARSER IO FUNCTION ####\n"); 00801 exit(-1); 00802 00803 i = 0; 00804 while (s[i]) 00805 { 00806 if (strlen(s + i) > 40) 00807 { 00808 strncpy(slask,s + i,40); 00809 slask[40] = 0; 00810 printf("%s\n",slask); 00811 i += 40; 00812 } 00813 else 00814 { 00815 printf("%s",s + i); 00816 i += strlen(s + i); 00817 } 00818 fflush(stdout); 00819 } 00820 } 00821 } 00822 } 00823 00824 void Parser::pprintf(char *format, ...) 00825 { 00826 va_list vl; 00827 char buf[1024]; 00828 00829 va_start(vl, format); 00830 vsprintf(buf, format, vl); 00831 va_end(vl); 00832 00833 text_output( buf ); 00834 } 00835 00836 00837 void Parser::file_input(char *s,int l) 00838 { 00839 int i = 0; 00840 short q = 0; 00841 unsigned char c; 00842 00843 if (m_fil) 00844 fread(&c,1,1,m_fil); 00845 while (m_fil && !feof(m_fil) && c != 0x8d && (q || (c & 0x7f) != ',') && c) 00846 { 00847 if (i >= l - 1) 00848 { 00849 fprintf(stderr," ********* BUFFER OVERFLOW ********\n"); 00850 s[l - 1] = 0; 00851 fprintf(stderr,"%s\n",s); 00852 exit(-1); 00853 } 00854 s[i++] = c & 0x7f; 00855 if ( (c & 0x7f) == 34) 00856 q = !q; 00857 #ifdef DEBUG 00858 fprintf(stderr,"%c",c & 0x7f); 00859 #endif 00860 fread(&c,1,1,m_fil); 00861 } 00862 s[i] = 0; 00863 if (*s == 34 && s[strlen(s) - 1] == 34) 00864 { 00865 memmove(s,s + 1,strlen(s) + 1); 00866 s[strlen(s) - 1] = 0; 00867 } 00868 #ifdef DEBUG 00869 fprintf(stderr,"\n"); 00870 #endif 00871 } 00872 00873 00874 #define DC (m_current_data?m_current_data->data[m_dataptr]:0) 00875 00876 void Parser::get_data(char *s) 00877 { 00878 int x = 0; 00879 00880 while (DC == ' ' || DC == 9) 00881 m_dataptr++; 00882 if (!DC) 00883 { 00884 m_current_data = m_current_data ? m_current_data -> next : NULL; 00885 m_dataptr = 0; 00886 while (DC == ' ' || DC == 9) 00887 m_dataptr++; 00888 } 00889 if (DC) 00890 { 00891 while (DC && DC != ',') 00892 { 00893 s[x++] = DC; 00894 m_dataptr++; 00895 } 00896 if (DC == ',') 00897 m_dataptr++; 00898 } 00899 s[x] = 0; 00900 } 00901 00902 void Parser::read_data(VARLIST *vl) 00903 { 00904 int i; 00905 00906 for (i = 0; i < vl -> qty; i++) 00907 { 00908 get_data(vl -> var[i] -> svalue); 00909 vl -> var[i] -> value = atof(vl -> var[i] -> svalue); 00910 #ifdef DEBUGDATA 00911 fprintf(stderr,"Read Data; %s = '%s'\n",vl -> var[i] -> name,vl -> var[i] -> svalue); 00912 #endif 00913 } 00914 } 00915 00916 void Parser::SetParserIO(ParserIO *pclIO) 00917 { 00918 m_pclParserIO = pclIO; 00919 m_pclParserIO -> m_more = 0; 00920 } 00921 00922 void Parser::flush_obuf(void) 00923 { 00924 if (m_pclParserIO) 00925 { 00926 m_pclParserIO -> write_text(m_obuf, m_obufptr); 00927 m_obufptr = 0; 00928 } 00929 } 00930 00931 int Parser::inputstring(char *s,int l) 00932 { 00933 int ll = l; 00934 int i; 00935 00936 if (m_pclParserIO) 00937 { 00938 flush_obuf(); 00939 if (m_pclParserIO -> read_text(s,&ll) == -1) 00940 { 00941 perror("read_text() failed"); 00942 return -1; 00943 } 00944 s[ll] = 0; 00945 } 00946 else 00947 { 00948 fprintf(stderr,"#### USE PARSER IO FUNCTION ####\n"); 00949 exit(-1); 00950 00951 // gets(s); 00952 ll = read(0, s, l); 00953 s[ll] = 0; 00954 while (strlen(s) && (s[strlen(s) - 1] == 13 || s[strlen(s) - 1] == 10)) 00955 { 00956 s[strlen(s) - 1] = 0; 00957 } 00958 if (*s == '.') 00959 { 00960 if (chdir( s ) == -1) 00961 { 00962 perror("chdir() failed"); 00963 fprintf(stderr," ('%s') length %d\n",s,strlen(s)); 00964 } 00965 } 00966 for (i = 0; i < ll; i++) 00967 if (s[i] >= 'a' && s[i] <= 'z') 00968 s[i] -= 32; 00969 } 00970 return ll; 00971 } 00972 00973 void Parser::save_variables() 00974 { 00975 FILE *fil; 00976 VARIABLE *v; 00977 char slask[200]; 00978 00979 sprintf(slask,"%s/%s.lastrun",m_program_cwd,m_programname); 00980 if ((fil = fopen(slask,"wb")) != NULL) 00981 { 00982 for (v = m_variablebase; v; v = v -> next) 00983 { 00984 fwrite(v,1,sizeof(VARIABLE),fil); 00985 } 00986 fclose(fil); 00987 } 00988 } 00989 00990 void Parser::load_variables() 00991 { 00992 FILE *fil; 00993 VARIABLE *v; 00994 char slask[200]; 00995 00996 sprintf(slask,"%s.lastrun",m_programname); 00997 if ((fil = fopen(slask,"rb")) != NULL) 00998 { 00999 v = new VARIABLE; 01000 fread(v,1,sizeof(VARIABLE),fil); 01001 while (!feof(fil)) 01002 { 01003 addlist(&m_variablebase,v); 01004 01005 v = new VARIABLE; 01006 fread(v,1,sizeof(VARIABLE),fil); 01007 } 01008 delete v; 01009 fclose(fil); 01010 } 01011 } 01012 01013 VARIABLE *Parser::get_variable(char *name) 01014 { 01015 VARIABLE *v; 01016 01017 for (v = m_variablebase; v; v = v -> next) 01018 if (!strcmp(v -> name,name)) 01019 break; 01020 return v; 01021 } 01022 01023 int Parser::peek(int addr) 01024 { 01025 switch (addr) 01026 { 01027 default: 01028 return 0; //m_mem[addr]; 01029 } 01030 } 01031 01032 void Parser::poke(int a,int value) 01033 { 01034 int addr = a; 01035 01036 if (addr < 0) 01037 addr += 65536; 01038 // m_mem[addr] = value; 01039 #ifdef DEBUGMEM 01040 fprintf(stderr,"poke(%d,%d)\n",addr,value); 01041 #endif 01042 } 01043 01044 01045 void Parser::execute() 01046 { 01047 m_current_line = m_linebase; 01048 while (m_current_line) 01049 { 01050 m_next_line = m_current_line -> next; 01051 strcpy(m_the_str,m_current_line -> the_str); 01052 m_the_ptr = 0; 01053 #ifdef DEBUGEXPR 01054 fprintf(stderr," %4d %s\n",m_current_line -> line,m_current_line -> the_str); 01055 #endif 01056 m_placeholder = NULL; 01057 if (yyparse(this)) 01058 m_next_line = NULL; 01059 if (m_placeholder) 01060 m_placeholder -> value = m_placeholder -> fnvalue; 01061 m_current_line = m_next_line; 01062 } 01063 } 01064 01065 void Parser::finish() 01066 { 01067 LINE *ln; 01068 LINE *tmpln; 01069 VARIABLE *v; 01070 VARIABLE *tmpv; 01071 NEXT *nx; 01072 NEXT *tmpnx; 01073 SUB *sub; 01074 SUB *tmpsub; 01075 OPEN *o; 01076 OPEN *tmpo; 01077 DATA *d; 01078 DATA *tmpd; 01079 FUNC *f; 01080 FUNC *tmpf; 01081 01082 *m_programname = 0; 01083 m_current_line = NULL; 01084 m_load_ok = 1; 01085 for (ln = m_linebase; ln; ln = tmpln) 01086 { 01087 tmpln = ln -> next; 01088 delete ln -> the_str; //free(ln -> the_str); 01089 delete ln; //free(ln); 01090 } 01091 m_linebase = NULL; 01092 for (v = m_variablebase; v; v = tmpv) 01093 { 01094 tmpv = v -> next; 01095 delete v; //free(v); 01096 } 01097 m_variablebase = NULL; 01098 for (nx = m_nextbase; nx; nx = tmpnx) 01099 { 01100 tmpnx = nx -> next; 01101 delete nx; //free(nx); 01102 } 01103 m_nextbase = NULL; 01104 for (sub = m_subbase; sub; sub = tmpsub) 01105 { 01106 tmpsub = sub -> next; 01107 delete sub; //free(sub); 01108 } 01109 m_subbase = NULL; 01110 for (o = m_openbase; o; o = tmpo) 01111 { 01112 tmpo = o -> next; 01113 fclose(o -> fil); 01114 delete o; //free(o); 01115 } 01116 m_openbase = NULL; 01117 for (d = m_database; d; d = tmpd) 01118 { 01119 tmpd = d -> next; 01120 delete d -> data; //free(d -> data); 01121 delete d; //free(d); 01122 } 01123 m_database = NULL; 01124 for (f = m_funcbase; f; f = tmpf) 01125 { 01126 tmpf = f -> next; 01127 delete f; //free(f); 01128 } 01129 m_funcbase = NULL; 01130 } 01131 01132 01133 void Parser::cmd(char *in) 01134 { 01135 struct stat st; 01136 FILE *fil; 01137 LINE *ln; 01138 LINE *ln2; 01139 LINE *newln; 01140 char *cmd; 01141 char *arg; 01142 char *option; 01143 char *ptr; 01144 int cmnum; 01145 int i; 01146 int x = 0; 01147 int quit; 01148 int dir; 01149 char c; 01150 char slask[512]; 01151 char s[1024]; 01152 char s2[1024]; 01153 char tok[20]; 01154 char repl[200]; 01155 char with[200]; 01156 01157 strcpy(s, in); 01158 01159 while (s[strlen(s) - 1] == 13 || s[strlen(s) - 1] == 10) 01160 s[strlen(s) - 1] = 0; 01161 01162 cmd = strtok(s," "); 01163 if (!cmd) 01164 { 01165 #ifdef DEBUG 01166 fprintf(stderr," * Empty CHR$(4)\n"); 01167 #endif 01168 return; 01169 } 01170 arg = strtok(NULL,","); 01171 #ifdef DEBUG 01172 fprintf(stderr," * file command '%s' argument '%s'\n",cmd,arg); 01173 #endif 01174 if (!strcasecmp(cmd,"LOAD")) 01175 cmnum = 1; 01176 else 01177 if (!strcasecmp(cmd,"SAVE")) 01178 cmnum = 2; 01179 else 01180 if (!strcasecmp(cmd,"RUN")) 01181 cmnum = 3; 01182 else 01183 if (!strcasecmp(cmd,"LIST")) 01184 cmnum = 4; 01185 else 01186 if (!strcasecmp(cmd,"NEW")) 01187 cmnum = 5; 01188 else 01189 if (!strncasecmp(cmd,"cat",3)) 01190 cmnum = 6; 01191 else 01192 if (!strcasecmp(cmd,"edit")) 01193 cmnum = 7; 01194 else 01195 if (!strcasecmp(cmd,"info")) 01196 cmnum = 8; 01197 else 01198 if (!strcasecmp(cmd,"help")) 01199 cmnum = 9; 01200 else 01201 if (!strcasecmp(cmd,"disks")) 01202 cmnum = 10; 01203 else 01204 if (!strcasecmp(cmd,"cd")) 01205 cmnum = 11; 01206 else 01207 if (!strcasecmp(cmd,"type")) 01208 cmnum = 12; 01209 else 01210 if (!strcasecmp(cmd,"dump")) 01211 cmnum = 13; 01212 else 01213 { 01214 // fprintf(stderr,"##############################################\n"); 01215 fprintf(stderr,"#### implement dos command\n"); 01216 fprintf(stderr,"#### cmd '%s' arg '%s'\n",cmd,arg); 01217 cmnum = 0; 01218 } 01219 01220 option = strtok(NULL,","); 01221 while (option) 01222 { 01223 switch (*option) 01224 { 01225 default: 01226 fprintf(stderr,"#### cmd '%s' arg '%s' option '%s'\n",cmd,arg,option); 01227 // fprintf(stderr,"##############################################\n"); 01228 } 01229 option = strtok(NULL,","); 01230 } // while (option) 01231 01232 switch (cmnum) 01233 { 01234 case 1: // load 01235 if (!arg) 01236 { 01237 pprintf("LOAD what?\n"); 01238 break; 01239 } 01240 finish(); 01241 m_running = 0; 01242 read_file( arg ); 01243 if (!m_load_ok) 01244 { 01245 strupr( arg ); 01246 finish(); 01247 m_running = 0; 01248 read_file( arg ); 01249 } 01250 if (!m_load_ok) 01251 { 01252 finish(); 01253 } 01254 break; 01255 case 2: // save 01256 if (arg) 01257 { 01258 strupr( arg ); 01259 strcpy(m_programname, arg); 01260 verify_filename(m_programname); 01261 } 01262 if (*m_programname >= 'A' && *m_programname <= 'Z' && m_load_ok) 01263 { 01264 write_file(); 01265 } 01266 break; 01267 case 3: // run 01268 if (arg) 01269 { 01270 finish(); 01271 m_running = 0; 01272 read_file( arg ); 01273 if (!m_load_ok) 01274 { 01275 finish(); 01276 m_running = 0; 01277 strupr( arg ); 01278 read_file( arg ); 01279 } 01280 } 01281 if (!m_load_ok) 01282 { 01283 finish(); 01284 } 01285 do 01286 { 01287 // make optional 01288 // this -> load_variables(); 01289 01290 m_current_data = m_database; 01291 m_dataptr = 0; 01292 m_onerror = NULL; 01293 m_fil = NULL; 01294 01295 *m_run_program = 0; 01296 01297 m_running = 1; 01298 01299 this -> execute(); 01300 this -> flush_obuf(); 01301 // make optional 01302 // this -> save_variables(); 01303 01304 if (*m_run_program) 01305 { 01306 this -> finish(); 01307 m_running = 0; 01308 read_file( m_run_program ); 01309 } 01310 01311 } while (*m_run_program); 01312 break; 01313 case 4: // list 01314 m_running = 0; 01315 i = 0; 01316 for (ln = m_linebase; ln; ln = ln -> next) 01317 { 01318 m_current_line = ln; 01319 // generate source listing 01320 if (ln -> line > -1) 01321 pprintf(" %5d",ln -> line); 01322 else 01323 pprintf(" "); 01324 pprintf(" %s\n",ln -> the_str); 01325 01326 strcpy(m_the_str,ln -> the_str); 01327 m_the_ptr = 0; 01328 if (yyparse( this )) 01329 { 01330 break; 01331 } 01332 if (m_pclParserIO -> m_more && i++ > 20 && ln -> next) 01333 { 01334 pprintf("[More]"); 01335 inputstring(slask,200); 01336 if (*slask == 'q' || *slask == 'Q') 01337 break; 01338 i = 0; 01339 } 01340 } 01341 break; 01342 case 5: // new 01343 finish(); 01344 break; 01345 case 6: // cat(alog) 01346 if ((fil = popen("ls","r")) != NULL) 01347 { 01348 fgets(slask,200,fil); 01349 *s2 = 0; 01350 while (!feof(fil)) 01351 { 01352 slask[strlen(slask) - 1] = 0; 01353 x = 0; 01354 for (i = 0; i < (int)strlen(slask); i++) 01355 if (slask[i] >= 'a' && slask[i] <= 'z') 01356 x++; 01357 if (!strcmp(slask,s2)) 01358 x++; 01359 if (!x) 01360 { 01361 stat(slask, &st); 01362 i = 0; 01363 if (st.st_mode & 0100) // owner executable 01364 i |= 1; 01365 if (st.st_mode & 010) // group executable 01366 i |= 2; 01367 if (st.st_mode & 01) // all executable 01368 i |= 4; 01369 // bits 0 .. 7 = tiabsrab 01370 pprintf(" %c ","TIABSRAB"[i]); 01371 pprintf("%4d ",st.st_size / 1024); 01372 pprintf("%s\n",slask); 01373 } 01374 strcpy(s2,slask); 01375 fgets(slask,200,fil); 01376 } 01377 pclose(fil); 01378 } 01379 break; 01380 case 7: // edit (line) 01381 if (!arg) 01382 { 01383 ln = m_linebase; 01384 } 01385 else 01386 { 01387 i = atoi(arg); 01388 for (ln = m_linebase; ln; ln = ln -> next) 01389 if (ln -> line == i) 01390 break; 01391 if (!ln) 01392 { 01393 pprintf("Line %d does not exist\n",i); 01394 break; 01395 } 01396 } 01397 quit = 0; 01398 dir = 1; // riktning ner 01399 while (!quit) 01400 { 01401 if (!ln) 01402 pprintf("***** End of file.\n"); 01403 else 01404 { 01405 if (ln -> line > -1) 01406 pprintf("%5d %s\n",ln -> line,ln -> the_str); 01407 else 01408 pprintf(" %s\n",ln -> the_str); 01409 } 01410 // pprintf("ED(%c)> ",(dir == 1) ? '>' : '<'); 01411 pprintf("ED> "); 01412 inputstring(slask, 200); 01413 switch (*slask) 01414 { 01415 case '<': // upp 01416 dir = -1; 01417 if (ln == m_linebase) 01418 pprintf("Already at top.\n"); 01419 else 01420 { 01421 for (ln2 = m_linebase; ln2; ln2 = ln2 -> next) 01422 if (ln2 -> next == ln) 01423 break; 01424 ln = ln2; 01425 } 01426 break; 01427 case '>': // ner 01428 dir = 1; 01429 if (!ln) 01430 pprintf("Already at bottom.\n"); 01431 else 01432 ln = ln -> next; 01433 break; 01434 case 's': // byt ut 01435 case 'S': 01436 if (!ln) 01437 break; 01438 sprintf(tok,"%c",slask[1]); 01439 01440 ptr = strtok(slask + 2,tok); 01441 if (!ptr) 01442 break; 01443 strcpy(repl, ptr); // replace this 01444 01445 ptr = strtok(NULL,tok); 01446 if (!ptr) 01447 break; 01448 strcpy(with, ptr); // with this 01449 01450 strcpy(s2, ln -> the_str); 01451 ptr = strstr(s2, repl); 01452 if (!ptr) 01453 { 01454 pprintf("'%s' not found in line\n",repl); 01455 break; 01456 } 01457 *ptr = 0; 01458 { 01459 char temp[1024]; 01460 sprintf(temp,"%s%s%s", 01461 s2, 01462 with, 01463 ptr + strlen(repl)); 01464 if (strlen(temp) > strlen(ln -> the_str)) 01465 { 01466 delete ln -> the_str; 01467 ln -> the_str = new char[strlen(temp) + 1]; 01468 } 01469 strcpy(ln -> the_str,temp); 01470 } 01471 break; 01472 case 'd': // ta bort 01473 case 'D': 01474 if (!ln) 01475 break; 01476 if (ln -> next -> line == -1) 01477 ln -> next -> line = ln -> line; 01478 if (ln == m_linebase) 01479 { 01480 m_linebase = ln -> next; 01481 delete ln -> the_str; 01482 delete ln; 01483 ln = m_linebase; 01484 } 01485 else 01486 { 01487 for (ln2 = m_linebase; ln2; ln2 = ln2 -> next) 01488 if (ln2 -> next == ln) 01489 break; 01490 if (ln2) 01491 { 01492 ln2 -> next = ln -> next; 01493 delete ln -> the_str; 01494 delete ln; 01495 ln = ln2 -> next; 01496 } 01497 } 01498 break; 01499 case 'i': // insert 01500 case 'I': 01501 if (ln == m_linebase) 01502 ln2 = NULL; 01503 else 01504 for (ln2 = m_linebase; ln2; ln2 = ln2 -> next) 01505 if (ln2 -> next == ln) 01506 break; 01507 while (1) 01508 { 01509 pprintf(" ."); 01510 inputstring(slask,500); 01511 if (!*slask) 01512 break; 01513 else 01514 { 01515 strupr(slask); 01516 i = 0; 01517 if (isdigit(*slask)) 01518 { 01519 while (isdigit(slask[i])) 01520 i++; 01521 strncpy(s2,slask,i); 01522 s2[i] = 0; 01523 while (slask[i] == ' ' || slask[i] == 9) 01524 i++; 01525 } 01526 else 01527 *s2 = 0; 01528 newln = new LINE; 01529 newln -> next = ln; 01530 if (*s2) 01531 newln -> line = atoi(s2); 01532 else 01533 { 01534 newln -> line = ln ? ln -> line : -1; 01535 if (ln) 01536 ln -> line = -1; 01537 } 01538 newln -> the_str = new char[strlen(slask + i) + 1]; 01539 strcpy(newln -> the_str,slask + i); 01540 if (ln2) 01541 ln2 -> next = newln; 01542 else 01543 m_linebase = newln; 01544 ln2 = newln; 01545 } 01546 } 01547 break; 01548 case '.': // exit 01549 case 'q': 01550 case 'Q': 01551 quit++; 01552 break; 01553 01554 default: // help 01555 if (*slask) 01556 { 01557 pprintf("Edit Help\n"); 01558 pprintf(" i insert line before current line\n"); 01559 pprintf(" d delete current line\n"); 01560 pprintf(" < move up\n"); 01561 pprintf(" > move down\n"); 01562 pprintf("[enter] move\n"); 01563 pprintf(" s/x/y substitute x with y\n"); 01564 pprintf(" . or Q exits\n"); 01565 } 01566 else 01567 { 01568 if (dir < 0) 01569 { 01570 if (ln == m_linebase) 01571 pprintf("Already at top.\n"); 01572 else 01573 { 01574 for (ln2 = m_linebase; ln2; ln2 = ln2 -> next) 01575 if (ln2 -> next == ln) 01576 break; 01577 ln = ln2; 01578 } 01579 } 01580 else 01581 if (dir > 0) 01582 { 01583 if (!ln) 01584 pprintf("Already at bottom.\n"); 01585 else 01586 ln = ln -> next; 01587 } 01588 } 01589 break; 01590 } 01591 } 01592 break; 01593 case 8: // info 01594 getcwd(slask,200); 01595 ptr = strtok(slask,"/"); 01596 *s2 = 0; 01597 while (ptr) 01598 { 01599 strcpy(s2,ptr); 01600 ptr = strtok(NULL,"/"); 01601 } 01602 pprintf("Current disk: '%s'\n",s2); 01603 pprintf("Program name: '%s'\n",m_programname); 01604 break; 01605 case 9: // help 01606 pprintf("Online help:\n"); 01607 pprintf(" LOAD <program>\n"); 01608 pprintf(" SAVE [<program>]\n"); 01609 pprintf(" RUN [<program>]\n"); 01610 pprintf(" LIST - list loaded program\n"); 01611 pprintf(" EDIT [<line>]\n"); 01612 pprintf(" NEW - delete program in memory\n"); 01613 pprintf(" TYPE <file> - read a file\n"); 01614 pprintf(" DUMP <file> - hex dump a file\n"); 01615 pprintf(" CATALOG - lists files on current disk\n"); 01616 pprintf(" DISKS - show available disks\n"); 01617 pprintf(" CD <disk> - change disk\n"); 01618 pprintf(" INFO - show current disk and loaded program\n"); 01619 pprintf(" HELP\n"); 01620 pprintf(" QUIT\n"); 01621 pprintf("\n"); 01622 break; 01623 case 10: // disks 01624 if ((fil = popen("ls -F ..","r")) != NULL) 01625 { 01626 fgets(slask,200,fil); 01627 while (!feof(fil)) 01628 { 01629 slask[strlen(slask) - 1] = 0; 01630 if (slask[strlen(slask) - 1] == '/') 01631 { 01632 slask[strlen(slask) - 1] = 0; 01633 pprintf("%s\n",slask); 01634 } 01635 fgets(slask,200,fil); 01636 } 01637 pclose(fil); 01638 } 01639 break; 01640 case 11: // cd 01641 if (!arg) 01642 { 01643 pprintf("CD where?\n"); 01644 break; 01645 } 01646 ptr = strstr(arg,".."); 01647 if (ptr) 01648 *ptr = 0; 01649 ptr = strstr(arg,"/"); 01650 if (ptr) 01651 *ptr = 0; 01652 sprintf(slask,"../%s",arg); 01653 if (chdir(slask) == -1) 01654 pprintf("Failed.\n"); 01655 else 01656 pprintf("Ok.\n"); 01657 break; 01658 case 12: // type 01659 if (!arg) 01660 { 01661 pprintf("TYPE what?\n"); 01662 break; 01663 } 01664 verify_filename( arg ); 01665 fil = fopen(arg,"rb"); 01666 if (!fil) 01667 { 01668 strupr(arg); 01669 fil = fopen(arg,"rb"); 01670 } 01671 if (fil) 01672 { 01673 fread(&c,1,1,fil); 01674 i = 0; 01675 while (!feof(fil)) 01676 { 01677 c &= 127; 01678 if (c == 0x0d) 01679 { 01680 pprintf("\n"); 01681 x++; 01682 } else 01683 { 01684 pprintf("%c",isprint(c) ? c : '.'); 01685 x = 0; 01686 } 01687 fread(&c,1,1,fil); 01688 if (x) 01689 { 01690 if (m_pclParserIO -> m_more && i++ > 20 && !feof(fil)) 01691 { 01692 pprintf("[More]"); 01693 inputstring(slask,200); 01694 if (*slask == 'q' || *slask == 'Q') 01695 break; 01696 i = 0; 01697 } 01698 } 01699 } 01700 fclose(fil); 01701 if (!x) 01702 pprintf("\n"); 01703 } 01704 else 01705 pprintf("Couldn't open '%s'...\n",arg); 01706 break; 01707 case 13: // dump 01708 if (!arg) 01709 { 01710 pprintf("DUMP what?\n"); 01711 break; 01712 } 01713 verify_filename( arg ); 01714 fil = fopen(arg,"rb"); 01715 if (!fil) 01716 { 01717 strupr(arg); 01718 fil = fopen(arg,"rb"); 01719 } 01720 if (fil) 01721 { 01722 long addr = 0; 01723 01724 x = 0; 01725 while (!feof(fil)) 01726 { 01727 pprintf("%04lx %04lx ",addr / 65536L,addr % 65536L); 01728 *slask = 0; 01729 for (i = 0; i < 16; i++) 01730 { 01731 fread(&c,1,1,fil); 01732 pprintf(" %02x", (unsigned char)c); 01733 if (isprint(c & 0x7f)) 01734 sprintf(slask + strlen(slask),"%c",c & 0x7f); 01735 else 01736 strcat(slask,"."); 01737 if (i == 7) 01738 { 01739 pprintf(" "); 01740 strcat(slask," "); 01741 } 01742 } 01743 pprintf(" %s\n",slask); 01744 if (m_pclParserIO -> m_more && x++ > 20 && !feof(fil)) 01745 { 01746 pprintf("[More]"); 01747 inputstring(slask,200); 01748 if (*slask == 'q' || *slask == 'Q') 01749 break; 01750 x = 0; 01751 } 01752 addr += 16; 01753 } 01754 fclose(fil); 01755 } 01756 else 01757 pprintf("Couldn't open '%s'...\n",arg); 01758 break; 01759 01760 default: 01761 if (!this -> editcmd( in )) 01762 { 01763 strcpy(m_the_str, in); 01764 m_the_ptr = 0; 01765 strupr(m_the_str); // all uppercase 01766 m_current_line = m_linebase; // %! bug 01767 m_running = 1; 01768 if (yyparse( this )) 01769 fprintf(stderr," *** error\n"); 01770 } 01771 break; 01772 } 01773 flush_obuf(); 01774 } 01775 01776 int Parser::editcmd(char *in) 01777 { 01778 LINE *ln = m_current_line; 01779 01780 return 0; 01781 01782 if (*in >= 'a' && *in <= 'z') 01783 *in -= 32; 01784 if (isdigit(*in)) 01785 { 01786 01787 // # gå till rad nummer # 01788 01789 } 01790 else 01791 switch (*in) 01792 { 01793 case 'E': // E gå till slutet av texten 01794 break; 01795 case 'N': // B gå till början av texten 01796 break; 01797 case 'I': // I skjut in rader före aktuell rad, avsluta med tom rad 01798 break; 01799 case 'D': // D ta bort aktuell rad 01800 break; 01801 01802 // QU avsluta utan att spara 01803 // EX avsluta och spara 01804 // EC avsluta, spara, och kompilera 01805 01806 case 'S': // S/xx/yy byt ut xx mot yy på aktuell rad 01807 break; 01808 case '+': // // +x gå fram x rader 01809 break; 01810 case '-': // -x gå bak x rader 01811 break; 01812 case 'L': // L lista hela texten 01813 // L# lista texten från rad # 01814 break; 01815 01816 // > skjut in 2 mellanslag 01817 // < ta bort 2 mellanslag 01818 01819 case 'A': // A upprepa föregående kommando 01820 break; 01821 01822 default: 01823 return 0; 01824 } 01825 return 1; 01826 } |