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 #define _IOFUN_SOURCE_
00041
00042 #include "setup.h"
00043
00044 #if IO_FUNCTIONS
00045 #include <locale.h>
00046 #include <stdlib.h>
00047 #include <ctype.h>
00048 #endif
00049
00050 #include <stdio.h>
00051 #define _STDIO_INCLUDED_
00052 #include <string.h>
00053
00054 #include "envrnmnt.h"
00055 #include "router.h"
00056 #include "strngrtr.h"
00057 #include "filertr.h"
00058 #include "argacces.h"
00059 #include "extnfunc.h"
00060 #include "scanner.h"
00061 #include "constant.h"
00062 #include "memalloc.h"
00063 #include "commline.h"
00064 #include "sysdep.h"
00065 #include "utility.h"
00066
00067 #include "iofun.h"
00068
00069
00070
00071
00072
00073 #define FORMAT_MAX 512
00074 #define FLAG_MAX 80
00075
00076
00077
00078
00079
00080 #define IO_FUNCTION_DATA 64
00081
00082 struct IOFunctionData
00083 {
00084 void *locale;
00085 intBool useFullCRLF;
00086 };
00087
00088 #define IOFunctionData(theEnv) ((struct IOFunctionData *) GetEnvironmentData(theEnv,IO_FUNCTION_DATA))
00089
00090
00091
00092
00093
00094 #if IO_FUNCTIONS
00095 static void ReadTokenFromStdin(void *,struct token *);
00096 static char *ControlStringCheck(void *,int);
00097 static char FindFormatFlag(char *,size_t *,char *,size_t);
00098 static char *PrintFormatFlag(void *,char *,int,int);
00099 static char *FillBuffer(void *,char *,size_t *,size_t *);
00100 static void ReadNumber(void *,char *,struct token *,int);
00101 #endif
00102
00103
00104
00105
00106
00107 globle void IOFunctionDefinitions(
00108 void *theEnv)
00109 {
00110 AllocateEnvironmentData(theEnv,IO_FUNCTION_DATA,sizeof(struct IOFunctionData),NULL);
00111
00112 #if IO_FUNCTIONS
00113 IOFunctionData(theEnv)->useFullCRLF = FALSE;
00114 IOFunctionData(theEnv)->locale = (SYMBOL_HN *) EnvAddSymbol(theEnv,setlocale(LC_ALL,NULL));
00115 IncrementSymbolCount(IOFunctionData(theEnv)->locale);
00116 #endif
00117
00118 #if ! RUN_TIME
00119 #if IO_FUNCTIONS
00120 EnvDefineFunction2(theEnv,"printout", 'v', PTIEF PrintoutFunction, "PrintoutFunction", "1*");
00121 EnvDefineFunction2(theEnv,"read", 'u', PTIEF ReadFunction, "ReadFunction", "*1");
00122 EnvDefineFunction2(theEnv,"open", 'b', OpenFunction, "OpenFunction", "23*k");
00123 EnvDefineFunction2(theEnv,"close", 'b', CloseFunction, "CloseFunction", "*1");
00124 EnvDefineFunction2(theEnv,"get-char", 'i', GetCharFunction, "GetCharFunction", "*1");
00125 EnvDefineFunction2(theEnv,"put-char", 'v', PTIEF PutCharFunction, "PutCharFunction", "12");
00126 EnvDefineFunction2(theEnv,"remove", 'b', RemoveFunction, "RemoveFunction", "11k");
00127 EnvDefineFunction2(theEnv,"rename", 'b', RenameFunction, "RenameFunction", "22k");
00128 EnvDefineFunction2(theEnv,"format", 's', PTIEF FormatFunction, "FormatFunction", "2**us");
00129 EnvDefineFunction2(theEnv,"readline", 'k', PTIEF ReadlineFunction, "ReadlineFunction", "*1");
00130 EnvDefineFunction2(theEnv,"set-locale", 'u', PTIEF SetLocaleFunction, "SetLocaleFunction", "*1");
00131 EnvDefineFunction2(theEnv,"read-number", 'u', PTIEF ReadNumberFunction, "ReadNumberFunction", "*1");
00132 #endif
00133 #else
00134 #if MAC_MCW || WIN_MCW || MAC_XCD
00135 #pragma unused(theEnv)
00136 #endif
00137 #endif
00138 }
00139
00140 #if IO_FUNCTIONS
00141
00142
00143
00144
00145
00146 globle void PrintoutFunction(
00147 void *theEnv)
00148 {
00149 char *dummyid;
00150 int i, argCount;
00151 DATA_OBJECT theArgument;
00152
00153
00154
00155
00156
00157 if ((argCount = EnvArgCountCheck(theEnv,"printout",AT_LEAST,1)) == -1) return;
00158
00159
00160
00161
00162
00163 dummyid = GetLogicalName(theEnv,1,"stdout");
00164 if (dummyid == NULL)
00165 {
00166 IllegalLogicalNameMessage(theEnv,"printout");
00167 SetHaltExecution(theEnv,TRUE);
00168 SetEvaluationError(theEnv,TRUE);
00169 return;
00170 }
00171
00172
00173
00174
00175
00176 if (strcmp(dummyid,"nil") == 0)
00177 { return; }
00178 else if (QueryRouters(theEnv,dummyid) == FALSE)
00179 {
00180 UnrecognizedRouterMessage(theEnv,dummyid);
00181 return;
00182 }
00183
00184
00185
00186
00187
00188 for (i = 2; i <= argCount; i++)
00189 {
00190 EnvRtnUnknown(theEnv,i,&theArgument);
00191 if (EvaluationData(theEnv)->HaltExecution) break;
00192
00193 switch(GetType(theArgument))
00194 {
00195 case SYMBOL:
00196 if (strcmp(DOToString(theArgument),"crlf") == 0)
00197 {
00198 if (IOFunctionData(theEnv)->useFullCRLF)
00199 { EnvPrintRouter(theEnv,dummyid,"\r\n"); }
00200 else
00201 { EnvPrintRouter(theEnv,dummyid,"\n"); }
00202 }
00203 else if (strcmp(DOToString(theArgument),"tab") == 0)
00204 { EnvPrintRouter(theEnv,dummyid,"\t"); }
00205 else if (strcmp(DOToString(theArgument),"vtab") == 0)
00206 { EnvPrintRouter(theEnv,dummyid,"\v"); }
00207 else if (strcmp(DOToString(theArgument),"ff") == 0)
00208 { EnvPrintRouter(theEnv,dummyid,"\f"); }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 else
00219 { EnvPrintRouter(theEnv,dummyid,DOToString(theArgument)); }
00220 break;
00221
00222 case STRING:
00223 EnvPrintRouter(theEnv,dummyid,DOToString(theArgument));
00224 break;
00225
00226 default:
00227 PrintDataObject(theEnv,dummyid,&theArgument);
00228 break;
00229 }
00230 }
00231 }
00232
00233
00234
00235
00236
00237 globle intBool SetFullCRLF(
00238 void *theEnv,
00239 intBool value)
00240 {
00241 intBool oldValue = IOFunctionData(theEnv)->useFullCRLF;
00242
00243 IOFunctionData(theEnv)->useFullCRLF = value;
00244
00245 return(oldValue);
00246 }
00247
00248
00249
00250
00251 globle void ReadFunction(
00252 void *theEnv,
00253 DATA_OBJECT_PTR returnValue)
00254 {
00255 struct token theToken;
00256 int numberOfArguments;
00257 char *logicalName = NULL;
00258
00259
00260
00261
00262
00263 if ((numberOfArguments = EnvArgCountCheck(theEnv,"read",NO_MORE_THAN,1)) == -1)
00264 {
00265 returnValue->type = STRING;
00266 returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
00267 return;
00268 }
00269
00270
00271
00272
00273
00274 if (numberOfArguments == 0)
00275 { logicalName = "stdin"; }
00276 else if (numberOfArguments == 1)
00277 {
00278 logicalName = GetLogicalName(theEnv,1,"stdin");
00279 if (logicalName == NULL)
00280 {
00281 IllegalLogicalNameMessage(theEnv,"read");
00282 SetHaltExecution(theEnv,TRUE);
00283 SetEvaluationError(theEnv,TRUE);
00284 returnValue->type = STRING;
00285 returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
00286 return;
00287 }
00288 }
00289
00290
00291
00292
00293
00294 if (QueryRouters(theEnv,logicalName) == FALSE)
00295 {
00296 UnrecognizedRouterMessage(theEnv,logicalName);
00297 SetHaltExecution(theEnv,TRUE);
00298 SetEvaluationError(theEnv,TRUE);
00299 returnValue->type = STRING;
00300 returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
00301 return;
00302 }
00303
00304
00305
00306
00307
00308
00309 if (strcmp(logicalName,"stdin") == 0)
00310 { ReadTokenFromStdin(theEnv,&theToken); }
00311 else
00312 { GetToken(theEnv,logicalName,&theToken); }
00313
00314 RouterData(theEnv)->CommandBufferInputCount = 0;
00315 RouterData(theEnv)->AwaitingInput = FALSE;
00316
00317
00318
00319
00320
00321 returnValue->type = theToken.type;
00322 if ((theToken.type == FLOAT) || (theToken.type == STRING) ||
00323 #if OBJECT_SYSTEM
00324 (theToken.type == INSTANCE_NAME) ||
00325 #endif
00326 (theToken.type == SYMBOL) || (theToken.type == INTEGER))
00327 { returnValue->value = theToken.value; }
00328 else if (theToken.type == STOP)
00329 {
00330 returnValue->type = SYMBOL;
00331 returnValue->value = (void *) EnvAddSymbol(theEnv,"EOF");
00332 }
00333 else if (theToken.type == UNKNOWN_VALUE)
00334 {
00335 returnValue->type = STRING;
00336 returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
00337 }
00338 else
00339 {
00340 returnValue->type = STRING;
00341 returnValue->value = (void *) EnvAddSymbol(theEnv,theToken.printForm);
00342 }
00343
00344 return;
00345 }
00346
00347
00348
00349
00350
00351 static void ReadTokenFromStdin(
00352 void *theEnv,
00353 struct token *theToken)
00354 {
00355 char *inputString;
00356 size_t inputStringSize;
00357 int inchar;
00358
00359
00360
00361
00362
00363 theToken->type = STOP;
00364 while (theToken->type == STOP)
00365 {
00366
00367
00368
00369
00370
00371 inputString = NULL;
00372 RouterData(theEnv)->CommandBufferInputCount = 0;
00373 RouterData(theEnv)->AwaitingInput = TRUE;
00374 inputStringSize = 0;
00375 inchar = EnvGetcRouter(theEnv,"stdin");
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 while ((inchar != '\n') && (inchar != '\r') && (inchar != EOF) &&
00386 (! GetHaltExecution(theEnv)))
00387 {
00388 inputString = ExpandStringWithChar(theEnv,inchar,inputString,&RouterData(theEnv)->CommandBufferInputCount,
00389 &inputStringSize,inputStringSize + 80);
00390 inchar = EnvGetcRouter(theEnv,"stdin");
00391 }
00392
00393
00394
00395
00396
00397
00398
00399 OpenStringSource(theEnv,"read",inputString,0);
00400 GetToken(theEnv,"read",theToken);
00401 CloseStringSource(theEnv,"read");
00402 if (inputStringSize > 0) rm(theEnv,inputString,inputStringSize);
00403
00404
00405
00406
00407
00408
00409 if (GetHaltExecution(theEnv))
00410 {
00411 theToken->type = STRING;
00412 theToken->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422 if ((theToken->type == STOP) && (inchar == EOF))
00423 {
00424 theToken->type = SYMBOL;
00425 theToken->value = (void *) EnvAddSymbol(theEnv,"EOF");
00426 }
00427 }
00428 }
00429
00430
00431
00432
00433 globle int OpenFunction(
00434 void *theEnv)
00435 {
00436 int numberOfArguments;
00437 char *fileName, *logicalName, *accessMode = NULL;
00438 DATA_OBJECT theArgument;
00439
00440
00441
00442
00443
00444 if ((numberOfArguments = EnvArgRangeCheck(theEnv,"open",2,3)) == -1) return(0);
00445
00446
00447
00448
00449
00450 if ((fileName = GetFileName(theEnv,"open",1)) == NULL) return(0);
00451
00452
00453
00454
00455
00456
00457 logicalName = GetLogicalName(theEnv,2,NULL);
00458 if (logicalName == NULL)
00459 {
00460 SetHaltExecution(theEnv,TRUE);
00461 SetEvaluationError(theEnv,TRUE);
00462 IllegalLogicalNameMessage(theEnv,"open");
00463 return(0);
00464 }
00465
00466
00467
00468
00469
00470
00471 if (FindFile(theEnv,logicalName))
00472 {
00473 SetHaltExecution(theEnv,TRUE);
00474 SetEvaluationError(theEnv,TRUE);
00475 PrintErrorID(theEnv,"IOFUN",2,FALSE);
00476 EnvPrintRouter(theEnv,WERROR,"Logical name ");
00477 EnvPrintRouter(theEnv,WERROR,logicalName);
00478 EnvPrintRouter(theEnv,WERROR," already in use.\n");
00479 return(0);
00480 }
00481
00482
00483
00484
00485
00486 if (numberOfArguments == 2)
00487 { accessMode = "r"; }
00488 else if (numberOfArguments == 3)
00489 {
00490 if (EnvArgTypeCheck(theEnv,"open",3,STRING,&theArgument) == FALSE) return(0);
00491 accessMode = DOToString(theArgument);
00492 }
00493
00494
00495
00496
00497
00498 if ((strcmp(accessMode,"r") != 0) &&
00499 (strcmp(accessMode,"w") != 0) &&
00500 (strcmp(accessMode,"a") != 0) &&
00501 (strcmp(accessMode,"r+") != 0) &&
00502 (strcmp(accessMode,"w+") != 0) &&
00503 (strcmp(accessMode,"a+") != 0) &&
00504 (strcmp(accessMode,"rb") != 0) &&
00505 (strcmp(accessMode,"wb") != 0) &&
00506 (strcmp(accessMode,"ab") != 0) &&
00507 (strcmp(accessMode,"r+b") != 0) &&
00508 (strcmp(accessMode,"w+b") != 0) &&
00509 (strcmp(accessMode,"a+b") != 0))
00510 {
00511 SetHaltExecution(theEnv,TRUE);
00512 SetEvaluationError(theEnv,TRUE);
00513 ExpectedTypeError1(theEnv,"open",3,"string with value \"r\", \"w\", \"a\", \"r+\", \"w+\", \"rb\", \"wb\", \"ab\", \"r+b\", or \"w+b\"");
00514 return(0);
00515 }
00516
00517
00518
00519
00520
00521
00522
00523 return(OpenAFile(theEnv,fileName,accessMode,logicalName));
00524 }
00525
00526
00527
00528
00529 globle int CloseFunction(
00530 void *theEnv)
00531 {
00532 int numberOfArguments;
00533 char *logicalName;
00534
00535
00536
00537
00538
00539 if ((numberOfArguments = EnvArgCountCheck(theEnv,"close",NO_MORE_THAN,1)) == -1) return(0);
00540
00541
00542
00543
00544
00545
00546
00547 if (numberOfArguments == 0) return(CloseAllFiles(theEnv));
00548
00549
00550
00551
00552
00553 logicalName = GetLogicalName(theEnv,1,NULL);
00554 if (logicalName == NULL)
00555 {
00556 IllegalLogicalNameMessage(theEnv,"close");
00557 SetHaltExecution(theEnv,TRUE);
00558 SetEvaluationError(theEnv,TRUE);
00559 return(0);
00560 }
00561
00562
00563
00564
00565
00566
00567
00568 return(CloseFile(theEnv,logicalName));
00569 }
00570
00571
00572
00573
00574
00575 globle int GetCharFunction(
00576 void *theEnv)
00577 {
00578 int numberOfArguments;
00579 char *logicalName;
00580
00581 if ((numberOfArguments = EnvArgCountCheck(theEnv,"get-char",NO_MORE_THAN,1)) == -1)
00582 { return(-1); }
00583
00584 if (numberOfArguments == 0 )
00585 { logicalName = "stdin"; }
00586 else
00587 {
00588 logicalName = GetLogicalName(theEnv,1,"stdin");
00589 if (logicalName == NULL)
00590 {
00591 IllegalLogicalNameMessage(theEnv,"get-char");
00592 SetHaltExecution(theEnv,TRUE);
00593 SetEvaluationError(theEnv,TRUE);
00594 return(-1);
00595 }
00596 }
00597
00598 if (QueryRouters(theEnv,logicalName) == FALSE)
00599 {
00600 UnrecognizedRouterMessage(theEnv,logicalName);
00601 SetHaltExecution(theEnv,TRUE);
00602 SetEvaluationError(theEnv,TRUE);
00603 return(-1);
00604 }
00605
00606 return(EnvGetcRouter(theEnv,logicalName));
00607 }
00608
00609
00610
00611
00612
00613 globle void PutCharFunction(
00614 void *theEnv)
00615 {
00616 int numberOfArguments;
00617 char *logicalName;
00618 DATA_OBJECT theValue;
00619 long long theChar;
00620 FILE *theFile;
00621
00622 if ((numberOfArguments = EnvArgRangeCheck(theEnv,"put-char",1,2)) == -1)
00623 { return; }
00624
00625
00626
00627
00628
00629 if (numberOfArguments == 1)
00630 { logicalName = "stdout"; }
00631 else
00632 {
00633 logicalName = GetLogicalName(theEnv,1,"stdout");
00634 if (logicalName == NULL)
00635 {
00636 IllegalLogicalNameMessage(theEnv,"put-char");
00637 SetHaltExecution(theEnv,TRUE);
00638 SetEvaluationError(theEnv,TRUE);
00639 return;
00640 }
00641 }
00642
00643 if (QueryRouters(theEnv,logicalName) == FALSE)
00644 {
00645 UnrecognizedRouterMessage(theEnv,logicalName);
00646 SetHaltExecution(theEnv,TRUE);
00647 SetEvaluationError(theEnv,TRUE);
00648 return;
00649 }
00650
00651
00652
00653
00654
00655 if (numberOfArguments == 1)
00656 { if (EnvArgTypeCheck(theEnv,"put-char",1,INTEGER,&theValue) == FALSE) return; }
00657 else
00658 { if (EnvArgTypeCheck(theEnv,"put-char",2,INTEGER,&theValue) == FALSE) return; }
00659
00660 theChar = DOToLong(theValue);
00661
00662
00663
00664
00665
00666
00667
00668
00669 theFile = FindFptr(theEnv,logicalName);
00670 if (theFile != NULL)
00671 { putc((int) theChar,theFile); }
00672 }
00673
00674
00675
00676
00677
00678 globle int RemoveFunction(
00679 void *theEnv)
00680 {
00681 char *theFileName;
00682
00683
00684
00685
00686
00687 if (EnvArgCountCheck(theEnv,"remove",EXACTLY,1) == -1) return(FALSE);
00688
00689
00690
00691
00692
00693 if ((theFileName = GetFileName(theEnv,"remove",1)) == NULL) return(FALSE);
00694
00695
00696
00697
00698
00699
00700 return(genremove(theFileName));
00701 }
00702
00703
00704
00705
00706
00707 globle int RenameFunction(
00708 void *theEnv)
00709 {
00710 char *oldFileName, *newFileName;
00711
00712
00713
00714
00715
00716 if (EnvArgCountCheck(theEnv,"rename",EXACTLY,2) == -1) return(FALSE);
00717
00718
00719
00720
00721
00722 if ((oldFileName = GetFileName(theEnv,"rename",1)) == NULL) return(FALSE);
00723 if ((newFileName = GetFileName(theEnv,"rename",2)) == NULL) return(FALSE);
00724
00725
00726
00727
00728
00729
00730 return(genrename(oldFileName,newFileName));
00731 }
00732
00733
00734
00735
00736
00737 globle void *FormatFunction(
00738 void *theEnv)
00739 {
00740 int argCount;
00741 size_t start_pos;
00742 char *formatString, *logicalName;
00743 char formatFlagType;
00744 int f_cur_arg = 3;
00745 size_t form_pos = 0;
00746 char percentBuffer[FLAG_MAX];
00747 char *fstr = NULL;
00748 size_t fmaxm = 0;
00749 size_t fpos = 0;
00750 void *hptr;
00751 char *theString;
00752
00753
00754
00755
00756
00757 hptr = EnvAddSymbol(theEnv,"");
00758
00759
00760
00761
00762
00763
00764 if ((argCount = EnvArgCountCheck(theEnv,"format",AT_LEAST,2)) == -1)
00765 { return(hptr); }
00766
00767
00768
00769
00770
00771 if ((logicalName = GetLogicalName(theEnv,1,"stdout")) == NULL)
00772 {
00773 IllegalLogicalNameMessage(theEnv,"format");
00774 SetHaltExecution(theEnv,TRUE);
00775 SetEvaluationError(theEnv,TRUE);
00776 return(hptr);
00777 }
00778
00779 if (strcmp(logicalName,"nil") == 0)
00780 { }
00781 else if (QueryRouters(theEnv,logicalName) == FALSE)
00782 {
00783 UnrecognizedRouterMessage(theEnv,logicalName);
00784 return(hptr);
00785 }
00786
00787
00788
00789
00790
00791
00792
00793 if ((formatString = ControlStringCheck(theEnv,argCount)) == NULL)
00794 { return (hptr); }
00795
00796
00797
00798
00799
00800
00801 while (formatString[form_pos] != '\0')
00802 {
00803 if (formatString[form_pos] != '%')
00804 {
00805 start_pos = form_pos;
00806 while ((formatString[form_pos] != '%') &&
00807 (formatString[form_pos] != '\0'))
00808 { form_pos++; }
00809 fstr = AppendNToString(theEnv,&formatString[start_pos],fstr,form_pos-start_pos,&fpos,&fmaxm);
00810 }
00811 else
00812 {
00813 form_pos++;
00814 formatFlagType = FindFormatFlag(formatString,&form_pos,percentBuffer,FLAG_MAX);
00815 if (formatFlagType != ' ')
00816 {
00817 if ((theString = PrintFormatFlag(theEnv,percentBuffer,f_cur_arg,formatFlagType)) == NULL)
00818 {
00819 if (fstr != NULL) rm(theEnv,fstr,fmaxm);
00820 return (hptr);
00821 }
00822 fstr = AppendToString(theEnv,theString,fstr,&fpos,&fmaxm);
00823 if (fstr == NULL) return(hptr);
00824 f_cur_arg++;
00825 }
00826 else
00827 {
00828 fstr = AppendToString(theEnv,percentBuffer,fstr,&fpos,&fmaxm);
00829 if (fstr == NULL) return(hptr);
00830 }
00831 }
00832 }
00833
00834 if (fstr != NULL)
00835 {
00836 hptr = EnvAddSymbol(theEnv,fstr);
00837 if (strcmp(logicalName,"nil") != 0) EnvPrintRouter(theEnv,logicalName,fstr);
00838 rm(theEnv,fstr,fmaxm);
00839 }
00840 else
00841 { hptr = EnvAddSymbol(theEnv,""); }
00842
00843 return(hptr);
00844 }
00845
00846
00847
00848
00849
00850 static char *ControlStringCheck(
00851 void *theEnv,
00852 int argCount)
00853 {
00854 DATA_OBJECT t_ptr;
00855 char *str_array;
00856 char print_buff[FLAG_MAX];
00857 size_t i;
00858 int per_count;
00859 char formatFlag;
00860
00861 if (EnvArgTypeCheck(theEnv,"format",2,STRING,&t_ptr) == FALSE) return(NULL);
00862
00863 per_count = 0;
00864 str_array = ValueToString(t_ptr.value);
00865 for (i= 0 ; str_array[i] != '\0' ; )
00866 {
00867 if (str_array[i] == '%')
00868 {
00869 i++;
00870 formatFlag = FindFormatFlag(str_array,&i,print_buff,FLAG_MAX);
00871 if (formatFlag == '-')
00872 {
00873 PrintErrorID(theEnv,"IOFUN",3,FALSE);
00874 EnvPrintRouter(theEnv,WERROR,"Invalid format flag \"");
00875 EnvPrintRouter(theEnv,WERROR,print_buff);
00876 EnvPrintRouter(theEnv,WERROR,"\" specified in format function.\n");
00877 SetEvaluationError(theEnv,TRUE);
00878 return (NULL);
00879 }
00880 else if (formatFlag != ' ')
00881 { per_count++; }
00882 }
00883 else
00884 { i++; }
00885 }
00886
00887 if (per_count != (argCount - 2))
00888 {
00889 ExpectedCountError(theEnv,"format",EXACTLY,per_count+2);
00890 SetEvaluationError(theEnv,TRUE);
00891 return (NULL);
00892 }
00893
00894 return(str_array);
00895 }
00896
00897
00898
00899
00900
00901 static char FindFormatFlag(
00902 char *formatString,
00903 size_t *a,
00904 char *formatBuffer,
00905 size_t bufferMax)
00906 {
00907 char inchar, formatFlagType;
00908 size_t copy_pos = 0;
00909
00910
00911
00912
00913
00914
00915
00916 formatFlagType = ' ';
00917
00918
00919
00920
00921
00922
00923
00924 if (formatString[*a] == 'n')
00925 {
00926 gensprintf(formatBuffer,"\n");
00927 (*a)++;
00928 return(formatFlagType);
00929 }
00930 else if (formatString[*a] == 'r')
00931 {
00932 gensprintf(formatBuffer,"\r");
00933 (*a)++;
00934 return(formatFlagType);
00935 }
00936 else if (formatString[*a] == 't')
00937 {
00938 gensprintf(formatBuffer,"\t");
00939 (*a)++;
00940 return(formatFlagType);
00941 }
00942 else if (formatString[*a] == 'v')
00943 {
00944 gensprintf(formatBuffer,"\v");
00945 (*a)++;
00946 return(formatFlagType);
00947 }
00948 else if (formatString[*a] == '%')
00949 {
00950 gensprintf(formatBuffer,"%%");
00951 (*a)++;
00952 return(formatFlagType);
00953 }
00954
00955
00956
00957
00958
00959 formatBuffer[copy_pos++] = '%';
00960 formatBuffer[copy_pos] = '\0';
00961 while ((formatString[*a] != '%') &&
00962 (formatString[*a] != '\0') &&
00963 (copy_pos < (bufferMax - 5)))
00964 {
00965 inchar = formatString[*a];
00966 (*a)++;
00967
00968 if ( (inchar == 'd') ||
00969 (inchar == 'o') ||
00970 (inchar == 'x') ||
00971 (inchar == 'u'))
00972 {
00973 formatFlagType = inchar;
00974 formatBuffer[copy_pos++] = 'l';
00975 formatBuffer[copy_pos++] = 'l';
00976 formatBuffer[copy_pos++] = inchar;
00977 formatBuffer[copy_pos] = '\0';
00978 return(formatFlagType);
00979 }
00980 else if ( (inchar == 'c') ||
00981 (inchar == 's') ||
00982 (inchar == 'e') ||
00983 (inchar == 'f') ||
00984 (inchar == 'g') )
00985 {
00986 formatBuffer[copy_pos++] = inchar;
00987 formatBuffer[copy_pos] = '\0';
00988 formatFlagType = inchar;
00989 return(formatFlagType);
00990 }
00991
00992
00993
00994
00995
00996
00997
00998 if ( (! isdigit(inchar)) &&
00999 (inchar != '.') &&
01000 (inchar != '-') )
01001 {
01002 formatBuffer[copy_pos++] = inchar;
01003 formatBuffer[copy_pos] = '\0';
01004 return('-');
01005 }
01006
01007 formatBuffer[copy_pos++] = inchar;
01008 formatBuffer[copy_pos] = '\0';
01009 }
01010
01011 return(formatFlagType);
01012 }
01013
01014
01015
01016
01017
01018 static char *PrintFormatFlag(
01019 void *theEnv,
01020 char *formatString,
01021 int whichArg,
01022 int formatType)
01023 {
01024 DATA_OBJECT theResult;
01025 char *theString, *printBuffer;
01026 size_t theLength;
01027 void *oldLocale;
01028
01029
01030
01031
01032
01033 switch (formatType)
01034 {
01035 case 's':
01036 if (EnvArgTypeCheck(theEnv,"format",whichArg,SYMBOL_OR_STRING,&theResult) == FALSE) return(NULL);
01037 theLength = strlen(formatString) + strlen(ValueToString(theResult.value)) + 200;
01038 printBuffer = (char *) gm2(theEnv,(sizeof(char) * theLength));
01039 gensprintf(printBuffer,formatString,ValueToString(theResult.value));
01040 break;
01041
01042 case 'c':
01043 EnvRtnUnknown(theEnv,whichArg,&theResult);
01044 if ((GetType(theResult) == STRING) ||
01045 (GetType(theResult) == SYMBOL))
01046 {
01047 theLength = strlen(formatString) + 200;
01048 printBuffer = (char *) gm2(theEnv,(sizeof(char) * theLength));
01049 gensprintf(printBuffer,formatString,(ValueToString(theResult.value))[0]);
01050 }
01051 else if (GetType(theResult) == INTEGER)
01052 {
01053 theLength = strlen(formatString) + 200;
01054 printBuffer = (char *) gm2(theEnv,(sizeof(char) * theLength));
01055 gensprintf(printBuffer,formatString,(char) DOToLong(theResult));
01056 }
01057 else
01058 {
01059 ExpectedTypeError1(theEnv,"format",whichArg,"symbol, string, or integer");
01060 return(NULL);
01061 }
01062 break;
01063
01064 case 'd':
01065 case 'x':
01066 case 'o':
01067 case 'u':
01068 if (EnvArgTypeCheck(theEnv,"format",whichArg,INTEGER_OR_FLOAT,&theResult) == FALSE) return(NULL);
01069 theLength = strlen(formatString) + 200;
01070 printBuffer = (char *) gm2(theEnv,(sizeof(char) * theLength));
01071
01072 oldLocale = EnvAddSymbol(theEnv,setlocale(LC_NUMERIC,NULL));
01073 setlocale(LC_NUMERIC,ValueToString(IOFunctionData(theEnv)->locale));
01074
01075 if (GetType(theResult) == FLOAT)
01076 { gensprintf(printBuffer,formatString,(long long) ValueToDouble(theResult.value)); }
01077 else
01078 { gensprintf(printBuffer,formatString,(long long) ValueToLong(theResult.value)); }
01079
01080 setlocale(LC_NUMERIC,ValueToString(oldLocale));
01081 break;
01082
01083 case 'f':
01084 case 'g':
01085 case 'e':
01086 if (EnvArgTypeCheck(theEnv,"format",whichArg,INTEGER_OR_FLOAT,&theResult) == FALSE) return(NULL);
01087 theLength = strlen(formatString) + 200;
01088 printBuffer = (char *) gm2(theEnv,(sizeof(char) * theLength));
01089
01090 oldLocale = EnvAddSymbol(theEnv,setlocale(LC_NUMERIC,NULL));
01091
01092 setlocale(LC_NUMERIC,ValueToString(IOFunctionData(theEnv)->locale));
01093
01094 if (GetType(theResult) == FLOAT)
01095 { gensprintf(printBuffer,formatString,ValueToDouble(theResult.value)); }
01096 else
01097 { gensprintf(printBuffer,formatString,(double) ValueToLong(theResult.value)); }
01098
01099 setlocale(LC_NUMERIC,ValueToString(oldLocale));
01100
01101 break;
01102
01103 default:
01104 EnvPrintRouter(theEnv,WERROR," Error in format, the conversion character");
01105 EnvPrintRouter(theEnv,WERROR," for formatted output is not valid\n");
01106 return(FALSE);
01107 }
01108
01109 theString = ValueToString(EnvAddSymbol(theEnv,printBuffer));
01110 rm(theEnv,printBuffer,sizeof(char) * theLength);
01111 return(theString);
01112 }
01113
01114
01115
01116
01117
01118 globle void ReadlineFunction(
01119 void *theEnv,
01120 DATA_OBJECT_PTR returnValue)
01121 {
01122 char *buffer;
01123 size_t line_max = 0;
01124 int numberOfArguments;
01125 char *logicalName;
01126
01127 returnValue->type = STRING;
01128
01129 if ((numberOfArguments = EnvArgCountCheck(theEnv,"readline",NO_MORE_THAN,1)) == -1)
01130 {
01131 returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
01132 return;
01133 }
01134
01135 if (numberOfArguments == 0 )
01136 { logicalName = "stdin"; }
01137 else
01138 {
01139 logicalName = GetLogicalName(theEnv,1,"stdin");
01140 if (logicalName == NULL)
01141 {
01142 IllegalLogicalNameMessage(theEnv,"readline");
01143 SetHaltExecution(theEnv,TRUE);
01144 SetEvaluationError(theEnv,TRUE);
01145 returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
01146 return;
01147 }
01148 }
01149
01150 if (QueryRouters(theEnv,logicalName) == FALSE)
01151 {
01152 UnrecognizedRouterMessage(theEnv,logicalName);
01153 SetHaltExecution(theEnv,TRUE);
01154 SetEvaluationError(theEnv,TRUE);
01155 returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
01156 return;
01157 }
01158
01159 RouterData(theEnv)->CommandBufferInputCount = 0;
01160 RouterData(theEnv)->AwaitingInput = TRUE;
01161 buffer = FillBuffer(theEnv,logicalName,&RouterData(theEnv)->CommandBufferInputCount,&line_max);
01162 RouterData(theEnv)->CommandBufferInputCount = 0;
01163 RouterData(theEnv)->AwaitingInput = FALSE;
01164
01165 if (GetHaltExecution(theEnv))
01166 {
01167 returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
01168 if (buffer != NULL) rm(theEnv,buffer,(int) sizeof (char) * line_max);
01169 return;
01170 }
01171
01172 if (buffer == NULL)
01173 {
01174 returnValue->value = (void *) EnvAddSymbol(theEnv,"EOF");
01175 returnValue->type = SYMBOL;
01176 return;
01177 }
01178
01179 returnValue->value = (void *) EnvAddSymbol(theEnv,buffer);
01180 rm(theEnv,buffer,(int) sizeof (char) * line_max);
01181 return;
01182 }
01183
01184
01185
01186
01187
01188
01189 static char *FillBuffer(
01190 void *theEnv,
01191 char *logicalName,
01192 size_t *currentPosition,
01193 size_t *maximumSize)
01194 {
01195 int c;
01196 char *buf = NULL;
01197
01198
01199
01200
01201
01202 c = EnvGetcRouter(theEnv,logicalName);
01203
01204 if (c == EOF)
01205 { return(NULL); }
01206
01207
01208
01209
01210
01211 while ((c != '\n') && (c != '\r') && (c != EOF) &&
01212 (! GetHaltExecution(theEnv)))
01213 {
01214 buf = ExpandStringWithChar(theEnv,c,buf,currentPosition,maximumSize,*maximumSize+80);
01215 c = EnvGetcRouter(theEnv,logicalName);
01216 }
01217
01218
01219
01220
01221
01222 buf = ExpandStringWithChar(theEnv,EOS,buf,currentPosition,maximumSize,*maximumSize+80);
01223 return (buf);
01224 }
01225
01226
01227
01228
01229
01230 globle void SetLocaleFunction(
01231 void *theEnv,
01232 DATA_OBJECT_PTR returnValue)
01233 {
01234 DATA_OBJECT theResult;
01235 int numArgs;
01236
01237
01238
01239
01240
01241 if ((numArgs = EnvArgCountCheck(theEnv,"set-locale",NO_MORE_THAN,1)) == -1)
01242 {
01243 returnValue->type = SYMBOL;
01244 returnValue->value = EnvFalseSymbol(theEnv);
01245 return;
01246 }
01247
01248
01249
01250
01251
01252
01253 if (numArgs == 0)
01254 {
01255 returnValue->type = STRING;
01256 returnValue->value = IOFunctionData(theEnv)->locale;
01257 return;
01258 }
01259
01260
01261
01262
01263
01264 if (EnvArgTypeCheck(theEnv,"set-locale",1,STRING,&theResult) == FALSE)
01265 {
01266 returnValue->type = SYMBOL;
01267 returnValue->value = EnvFalseSymbol(theEnv);
01268 return;
01269 }
01270
01271
01272
01273
01274
01275 returnValue->type = STRING;
01276 returnValue->value = IOFunctionData(theEnv)->locale;
01277
01278
01279
01280
01281
01282 DecrementSymbolCount(theEnv,(struct symbolHashNode *) IOFunctionData(theEnv)->locale);
01283 IOFunctionData(theEnv)->locale = DOToPointer(theResult);
01284 IncrementSymbolCount(IOFunctionData(theEnv)->locale);
01285 }
01286
01287
01288
01289
01290
01291 globle void ReadNumberFunction(
01292 void *theEnv,
01293 DATA_OBJECT_PTR returnValue)
01294 {
01295 struct token theToken;
01296 int numberOfArguments;
01297 char *logicalName = NULL;
01298
01299
01300
01301
01302
01303 if ((numberOfArguments = EnvArgCountCheck(theEnv,"read",NO_MORE_THAN,1)) == -1)
01304 {
01305 returnValue->type = STRING;
01306 returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
01307 return;
01308 }
01309
01310
01311
01312
01313
01314 if (numberOfArguments == 0)
01315 { logicalName = "stdin"; }
01316 else if (numberOfArguments == 1)
01317 {
01318 logicalName = GetLogicalName(theEnv,1,"stdin");
01319 if (logicalName == NULL)
01320 {
01321 IllegalLogicalNameMessage(theEnv,"read");
01322 SetHaltExecution(theEnv,TRUE);
01323 SetEvaluationError(theEnv,TRUE);
01324 returnValue->type = STRING;
01325 returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
01326 return;
01327 }
01328 }
01329
01330
01331
01332
01333
01334 if (QueryRouters(theEnv,logicalName) == FALSE)
01335 {
01336 UnrecognizedRouterMessage(theEnv,logicalName);
01337 SetHaltExecution(theEnv,TRUE);
01338 SetEvaluationError(theEnv,TRUE);
01339 returnValue->type = STRING;
01340 returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
01341 return;
01342 }
01343
01344
01345
01346
01347
01348
01349 if (strcmp(logicalName,"stdin") == 0)
01350 { ReadNumber(theEnv,logicalName,&theToken,TRUE); }
01351 else
01352 { ReadNumber(theEnv,logicalName,&theToken,FALSE); }
01353
01354 RouterData(theEnv)->CommandBufferInputCount = 0;
01355 RouterData(theEnv)->AwaitingInput = FALSE;
01356
01357
01358
01359
01360
01361 returnValue->type = theToken.type;
01362 if ((theToken.type == FLOAT) || (theToken.type == STRING) ||
01363 #if OBJECT_SYSTEM
01364 (theToken.type == INSTANCE_NAME) ||
01365 #endif
01366 (theToken.type == SYMBOL) || (theToken.type == INTEGER))
01367 { returnValue->value = theToken.value; }
01368 else if (theToken.type == STOP)
01369 {
01370 returnValue->type = SYMBOL;
01371 returnValue->value = (void *) EnvAddSymbol(theEnv,"EOF");
01372 }
01373 else if (theToken.type == UNKNOWN_VALUE)
01374 {
01375 returnValue->type = STRING;
01376 returnValue->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
01377 }
01378 else
01379 {
01380 returnValue->type = STRING;
01381 returnValue->value = (void *) EnvAddSymbol(theEnv,theToken.printForm);
01382 }
01383
01384 return;
01385 }
01386
01387
01388
01389
01390
01391 static void ReadNumber(
01392 void *theEnv,
01393 char *logicalName,
01394 struct token *theToken,
01395 int isStdin)
01396 {
01397 char *inputString;
01398 char *charPtr = NULL;
01399 size_t inputStringSize;
01400 int inchar;
01401 long long theLong;
01402 double theDouble;
01403 void *oldLocale;
01404
01405 theToken->type = STOP;
01406
01407
01408
01409
01410
01411
01412 inputString = NULL;
01413 RouterData(theEnv)->CommandBufferInputCount = 0;
01414 RouterData(theEnv)->AwaitingInput = TRUE;
01415 inputStringSize = 0;
01416 inchar = EnvGetcRouter(theEnv,logicalName);
01417
01418
01419
01420
01421
01422 while (isspace(inchar) && (inchar != EOF) &&
01423 (! GetHaltExecution(theEnv)))
01424 { inchar = EnvGetcRouter(theEnv,logicalName); }
01425
01426
01427
01428
01429
01430
01431 while ((((! isStdin) && (! isspace(inchar))) ||
01432 (isStdin && (inchar != '\n') && (inchar != '\r'))) &&
01433 (inchar != EOF) &&
01434 (! GetHaltExecution(theEnv)))
01435 {
01436 inputString = ExpandStringWithChar(theEnv,inchar,inputString,&RouterData(theEnv)->CommandBufferInputCount,
01437 &inputStringSize,inputStringSize + 80);
01438 inchar = EnvGetcRouter(theEnv,logicalName);
01439 }
01440
01441
01442
01443
01444
01445
01446 if (GetHaltExecution(theEnv))
01447 {
01448 theToken->type = STRING;
01449 theToken->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
01450 if (inputStringSize > 0) rm(theEnv,inputString,inputStringSize);
01451 return;
01452 }
01453
01454
01455
01456
01457
01458
01459
01460
01461 if (inchar == EOF)
01462 {
01463 theToken->type = SYMBOL;
01464 theToken->value = (void *) EnvAddSymbol(theEnv,"EOF");
01465 if (inputStringSize > 0) rm(theEnv,inputString,inputStringSize);
01466 return;
01467 }
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480 oldLocale = EnvAddSymbol(theEnv,setlocale(LC_NUMERIC,NULL));
01481 setlocale(LC_NUMERIC,ValueToString(IOFunctionData(theEnv)->locale));
01482
01483
01484
01485
01486
01487
01488
01489 #if WIN_MVC
01490 theLong = _strtoi64(inputString,&charPtr,10);
01491 #else
01492 theLong = strtoll(inputString,&charPtr,10);
01493 #endif
01494
01495 if ((charPtr != inputString) &&
01496 (isspace(*charPtr) || (*charPtr == '\0')))
01497 {
01498 theToken->type = INTEGER;
01499 theToken->value = (void *) EnvAddLong(theEnv,theLong);
01500 if (inputStringSize > 0) rm(theEnv,inputString,inputStringSize);
01501 setlocale(LC_NUMERIC,ValueToString(oldLocale));
01502 return;
01503 }
01504
01505
01506
01507
01508
01509
01510
01511 theDouble = strtod(inputString,&charPtr);
01512 if ((charPtr != inputString) &&
01513 (isspace(*charPtr) || (*charPtr == '\0')))
01514 {
01515 theToken->type = FLOAT;
01516 theToken->value = (void *) EnvAddDouble(theEnv,theDouble);
01517 if (inputStringSize > 0) rm(theEnv,inputString,inputStringSize);
01518 setlocale(LC_NUMERIC,ValueToString(oldLocale));
01519 return;
01520 }
01521
01522
01523
01524
01525
01526
01527 setlocale(LC_NUMERIC,ValueToString(oldLocale));
01528
01529
01530
01531
01532
01533
01534 theToken->type = STRING;
01535 theToken->value = (void *) EnvAddSymbol(theEnv,"*** READ ERROR ***");
01536 }
01537
01538 #endif
01539