00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef lint
00011 static char vcid[] = "$Id: sys.c,v 1.9 1996/01/17 00:33:09 duchier Exp $";
00012 #endif
00013 #ifndef OS2_PORT
00014 #include <unistd.h>
00015 #endif
00016 #include "extern.h"
00017 #include "trees.h"
00018 #include "login.h"
00019 #include "types.h"
00020 #include "parser.h"
00021 #include "copy.h"
00022 #include "token.h"
00023 #include "print.h"
00024 #include "lefun.h"
00025 #include "memory.h"
00026 #ifndef OS2_PORT
00027 #include "built_ins.h"
00028 #else
00029 #include "built_in.h"
00030 #endif
00031
00032 #include "error.h"
00033 #include "modules.h"
00034 #include "sys.h"
00035
00036 ptr_definition sys_bytedata;
00037 ptr_definition sys_bitvector;
00038 ptr_definition sys_regexp;
00039 ptr_definition sys_stream;
00040 ptr_definition sys_file_stream;
00041 ptr_definition sys_socket_stream;
00042
00043 long
00044 call_primitive(fun,num,argi,info)
00045 int num;
00046 psi_arg argi[];
00047 long (*fun)();
00048 void* info;
00049 {
00050 #define ARGNN 10
00051 ptr_psi_term funct,arg,result,argo[ARGNN];
00052 ptr_node n;
00053 int allargs=1,allvalues=1,i;
00054 funct=aim->a;
00055 deref_ptr(funct);
00056 result=aim->b;
00057 for (i=0;i<num;i++) {
00058 n=find(featcmp,argi[i].feature,funct->attr_list);
00059
00060 if (n) {
00061 arg = (ptr_psi_term) n->data;
00062
00063
00064
00065
00066 if (argi[i].options&UNEVALED) {
00067 deref_ptr(arg);
00068 argo[i]=arg;
00069 continue; }
00070
00071 deref(arg);
00072 argo[i]=arg;
00073
00074 if (argi[i].options&POLYTYPE) {
00075 ptr_definition *type = (ptr_definition *)argi[i].type;
00076 while (*type != NULL)
00077 if (overlap_type(arg->type,*type))
00078 goto admissible;
00079 else type++;
00080 }
00081 else {
00082 if (overlap_type(arg->type,argi[i].type))
00083 goto admissible;
00084 }
00085
00086 if (argi[i].options&JUSTFAIL) return FALSE;
00087 Errorline("Illegal argument in %P.\n",funct);
00088 return (c_abort());
00089
00090 admissible:
00091
00092 if (arg->value) {
00093 ptr_definition *type = (ptr_definition *)argi[i].type;
00094
00095 if (argi[i].options&POLYTYPE) {
00096 while (*type != NULL)
00097 if (sub_type(arg->type,*type))
00098 goto correct;
00099 else type++;
00100 }
00101 else {
00102 if (sub_type(arg->type,type)) goto correct;
00103 }
00104
00105 if (argi[i].options&JUSTFAIL) return FALSE;
00106 Errorline("Illegal argument in %P.\n",funct);
00107 return (c_abort());
00108
00109 correct:;
00110 }
00111
00112 else if (!(argi[i].options&NOVALUE)) allvalues=0;
00113 }
00114
00115 else {
00116 argo[i]=NULL;
00117 if (argi[i].options&MANDATORY) {
00118 Errorline("Missing argument '%s' in %P.\n",argi[i].feature,funct);
00119 return (c_abort());
00120 }
00121 else if (argi[i].options&REQUIRED) allargs=0;
00122 }
00123 }
00124 if (allargs)
00125 if (allvalues) {
00126 return fun(argo,result,funct,info);
00127 }
00128 else {
00129 for (i=0;i<num;i++) {
00130
00131 if (argo[i] && !(argi[i].options&UNEVALED) && !argo[i]->value)
00132 residuate(argo[i]);
00133 }
00134 }
00135 else curry();
00136 return TRUE;
00137 }
00138
00139
00140
00141
00142
00143
00144
00145 static ptr_psi_term
00146 make_bytedata(sort,bytes)
00147 ptr_definition sort;
00148 unsigned long bytes;
00149 {
00150 ptr_psi_term temp_result;
00151 char *b = (char *) heap_alloc(bytes+sizeof(bytes));
00152 *((long *) b) = bytes;
00153 bzero(b+sizeof(bytes),bytes);
00154 temp_result=stack_psi_term(0);
00155 temp_result->type=sort;
00156 temp_result->value=(GENERIC)b;
00157 return temp_result;
00158 }
00159
00160 #define BYTEDATA_SIZE(X) (*(unsigned long *)(X->value))
00161 #define BYTEDATA_DATA(X) ((char*)((char*)X->value + sizeof(unsigned long)))
00162
00163
00164
00165
00166
00167
00168
00169
00170 static long
00171 make_bitvector_internal(args,result,funct)
00172 ptr_psi_term args[],result,funct;
00173 {
00174 long bits = *(REAL *)args[0]->value;
00175 if (bits < 0) {
00176 Errorline("negative argument in %P.\n",funct);
00177 return FALSE; }
00178 else {
00179 unsigned long bytes = bits / sizeof(char);
00180 ptr_psi_term temp_result;
00181 if ((bits % sizeof(char)) != 0) bytes++;
00182 temp_result = make_bytedata(sys_bitvector,bytes);
00183 push_goal(unify,temp_result,result,NULL);
00184 return TRUE; }
00185 }
00186
00187 static long
00188 c_make_bitvector()
00189 {
00190 psi_arg args[1];
00191 SETARG(args,0, "1" , integer , REQUIRED );
00192 return call_primitive(make_bitvector_internal,NARGS(args),args,0);
00193 }
00194
00195 #define BV_AND 0
00196 #define BV_OR 1
00197 #define BV_XOR 2
00198
00199 static long
00200 bitvector_binop_code(bv1,bv2,result,op)
00201 unsigned long *bv1,*bv2;
00202 ptr_psi_term result;
00203 int op;
00204 {
00205 unsigned long size1 = *bv1;
00206 unsigned long size2 = *bv2;
00207 unsigned long size3 = (size1>size2)?size1:size2;
00208 ptr_psi_term temp_result = make_bytedata(sys_bitvector,size3);
00209 unsigned char *s1 = ((unsigned char*)bv1)+sizeof(size1);
00210 unsigned char *s2 = ((unsigned char*)bv2)+sizeof(size2);
00211 unsigned char *s3 = ((unsigned char *) temp_result->value) + sizeof(size3);
00212 unsigned long i;
00213 switch (op) {
00214 case BV_AND:
00215 for(i=0;i<size3;i++) s3[i] = s1[i] & s2[i];
00216 if (size1<size2) for(;i<size2;i++) s3[i] = 0;
00217 else for(;i<size1;i++) s3[i] = 0;
00218 break;
00219 case BV_OR:
00220 for(i=0;i<size3;i++) s3[i] = s1[i] | s2[i];
00221 if (size1<size2) for(;i<size2;i++) s3[i] = s2[i];
00222 else for(;i<size1;i++) s3[i] = s1[i];
00223 break;
00224 case BV_XOR:
00225 for(i=0;i<size3;i++) s3[i] = s1[i] ^ s2[i];
00226 if (size1<size2) for(;i<size2;i++) s3[i] = (unsigned char) 0 ^ s2[i];
00227 else for(;i<size1;i++) s3[i] = s1[i] ^ (unsigned char) 0;
00228 break;
00229 default: return (c_abort());
00230 }
00231 push_goal(unify,temp_result,result,NULL);
00232 return TRUE;
00233 }
00234
00235
00236
00237
00238 static long
00239 bitvector_binop_internal(args,result,funct,op)
00240 ptr_psi_term args[],result,funct;
00241 void* op;
00242 {
00243 return bitvector_binop_code((unsigned long *)args[0]->value,
00244 (unsigned long *)args[1]->value,
00245 result,(int)op);
00246 }
00247
00248 static long
00249 bitvector_binop(op)
00250 int op;
00251 {
00252 psi_arg args[2];
00253 SETARG(args,0, "1" , sys_bitvector , REQUIRED );
00254 SETARG(args,1, "2" , sys_bitvector , REQUIRED );
00255 return call_primitive(bitvector_binop_internal,NARGS(args),args,(void*)op);
00256 }
00257
00258 static long
00259 c_bitvector_and()
00260 {
00261 return bitvector_binop(BV_AND);
00262 }
00263
00264 static long
00265 c_bitvector_or()
00266 {
00267 return bitvector_binop(BV_OR);
00268 }
00269
00270 static long
00271 c_bitvector_xor()
00272 {
00273 return bitvector_binop(BV_XOR);
00274 }
00275
00276 #define BV_NOT 0
00277 #define BV_COUNT 1
00278
00279 static long
00280 bitvector_unop_code(bv1,result,op)
00281 unsigned long *bv1;
00282 ptr_psi_term result;
00283 int op;
00284 {
00285 unsigned long size1 = *bv1;
00286 unsigned char *s1 = ((unsigned char*)bv1)+sizeof(size1);
00287 unsigned long i;
00288 ptr_psi_term temp_result;
00289 unsigned char *s3;
00290 switch (op) {
00291 case BV_NOT:
00292 temp_result = make_bytedata(sys_bitvector,size1);
00293 s3 = ((unsigned char *) temp_result->value) + sizeof(size1);
00294 for(i=0;i<size1;i++) s3[i] = ~(s1[i]);
00295 break;
00296 case BV_COUNT:
00297 {
00298 int cnt = 0;
00299 register unsigned char c;
00300 for(i=0;i<size1;i++) {
00301 c=s1[i];
00302 if (c & 1<<0) cnt++;
00303 if (c & 1<<1) cnt++;
00304 if (c & 1<<2) cnt++;
00305 if (c & 1<<3) cnt++;
00306 if (c & 1<<4) cnt++;
00307 if (c & 1<<5) cnt++;
00308 if (c & 1<<6) cnt++;
00309 if (c & 1<<7) cnt++; }
00310 return unify_real_result(result,(REAL) cnt);
00311 }
00312 break;
00313 default: return (c_abort());
00314 }
00315 push_goal(unify,temp_result,result,NULL);
00316 return TRUE;
00317 }
00318
00319
00320
00321
00322 static long
00323 bitvector_unop_internal(args,result,funct,op)
00324 ptr_psi_term args[],result,funct;
00325 void* op;
00326 {
00327 return bitvector_unop_code((unsigned long *)args[0]->value,
00328 result,(int)op);
00329 }
00330
00331 static long
00332 bitvector_unop(op)
00333 int op;
00334 {
00335 psi_arg args[1];
00336 SETARG(args,0, "1" , sys_bitvector , REQUIRED );
00337 return call_primitive(bitvector_unop_internal,NARGS(args),args,(void*)op);
00338 }
00339
00340 static long
00341 c_bitvector_not()
00342 {
00343 return bitvector_unop(BV_NOT);
00344 }
00345
00346 static long
00347 c_bitvector_count()
00348 {
00349 return bitvector_unop(BV_COUNT);
00350 }
00351
00352 #define BV_GET 0
00353 #define BV_SET 1
00354 #define BV_CLEAR 2
00355
00356 static long
00357 bitvector_bit_code(bv1,idx,result,op,funct)
00358 unsigned long * bv1;
00359 long idx;
00360 ptr_psi_term result,funct;
00361 int op;
00362 {
00363 unsigned long size1 = *bv1;
00364 unsigned char *s1 = ((unsigned char*)bv1)+sizeof(size1);
00365 unsigned long i = idx / sizeof(char);
00366 int j = idx % sizeof(char);
00367 ptr_psi_term temp_result;
00368 unsigned char *s2;
00369 if (idx<0 || idx>=size1) {
00370 Errorline("Index out of bound in %P.\n",funct);
00371 return FALSE; }
00372 switch (op) {
00373 case BV_GET:
00374 return unify_real_result(result,(REAL)((s1[i] & (1<<j))?1:0));
00375 break;
00376 case BV_SET:
00377 temp_result = make_bytedata(sys_bitvector,size1);
00378 s2 = ((unsigned char *) temp_result->value) + sizeof(size1);
00379 bcopy(s1,s2,size1);
00380 s2[i] |= 1<<j;
00381 break;
00382 case BV_CLEAR:
00383 temp_result = make_bytedata(sys_bitvector,size1);
00384 s2 = ((unsigned char *) temp_result->value) + sizeof(size1);
00385 bcopy(s1,s2,size1);
00386 s2[i] &= ~ (1<<j);
00387 break;
00388 }
00389 push_goal(unify,temp_result,result,NULL);
00390 return TRUE;
00391 }
00392
00393 static long
00394 bitvector_bit_internal(args,result,funct,op)
00395 ptr_psi_term args[],result,funct;
00396 void* op;
00397 {
00398 return bitvector_bit_code((unsigned long *)args[0]->value,
00399 (long)*((REAL*)args[1]->value),
00400 result,(int)op,funct);
00401 }
00402
00403 static long
00404 bitvector_bit(op)
00405 int op;
00406 {
00407 psi_arg args[2];
00408 SETARG(args,0, "1" , sys_bitvector , REQUIRED );
00409 SETARG(args,1, "2" , integer , REQUIRED );
00410 return call_primitive(bitvector_bit_internal,NARGS(args),args,(void*)op);
00411 }
00412
00413 static long
00414 c_bitvector_get()
00415 {
00416 return bitvector_bit(BV_GET);
00417 }
00418
00419 static long
00420 c_bitvector_set()
00421 {
00422 return bitvector_bit(BV_SET);
00423 }
00424
00425 static long
00426 c_bitvector_clear()
00427 {
00428 return bitvector_bit(BV_CLEAR);
00429 }
00430
00431
00432
00433
00434 #include "regexp/regexp.h"
00435
00436 void
00437 regerror(s)
00438 char*s;
00439 {
00440 fprintf(stderr,"Regexp Error: %s\n",s);
00441 }
00442
00443
00444
00445
00446
00447 #ifndef OS2_PORT
00448 static long
00449 regexp_compile_internal(args,result,funct)
00450 ptr_psi_term args[],result,funct;
00451 {
00452 ptr_psi_term temp_result;
00453 regexp * re = regcomp(args[0]->value);
00454 long bytes;
00455 if (re == NULL) {
00456 Errorline("compilation of regular expression failed in %P.\n",funct);
00457 return (c_abort()); }
00458
00459
00460
00461
00462
00463
00464
00465
00466 bytes = last_regsize();
00467 temp_result = make_bytedata(sys_regexp,bytes);
00468
00469
00470
00471
00472
00473
00474
00475
00476 if (re->regmust != NULL)
00477 re->regmust = (char *) ((unsigned long) (re->regmust - (char *)re));
00478 bcopy((char*)re,((char*)temp_result->value)+sizeof(unsigned long),bytes);
00479 free(re);
00480
00481 push_goal(unify,temp_result,result,NULL);
00482 return TRUE;
00483 }
00484
00485 static long
00486 c_regexp_compile()
00487 {
00488 psi_arg args[1];
00489 SETARG(args,0, "1" , quoted_string , REQUIRED );
00490 return call_primitive(regexp_compile_internal,NARGS(args),args,0);
00491 }
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 static long
00503 regexp_execute_internal(args,result,funct)
00504 ptr_psi_term args[],result,funct;
00505 {
00506 regexp * re = (regexp*)(((char *)args[0]->value)+sizeof(unsigned long));
00507 char * must = re->regmust;
00508 long offset = 0;
00509 long success = TRUE;
00510
00511 if (args[3]) {
00512 offset = *(REAL*)args[3]->value;
00513 if (offset < 0 || offset > strlen((char*)args[1]->value)) {
00514 Errorline("Illegal offset in %P.\n",funct);
00515 return (c_abort()); }
00516 }
00517
00518 if (must != NULL)
00519 re->regmust = (char*)re+(unsigned long)must;
00520
00521 if (regexec(re,((char *)args[1]->value) + offset) == 0) {
00522 if (must != NULL) re->regmust = must;
00523 return FALSE;
00524 }
00525 else {
00526
00527 char **sp = re->startp;
00528 char **ep = re->endp;
00529 int i;
00530 char buffer[5];
00531 ptr_node n3;
00532 if (must != NULL) re->regmust = must;
00533 if (args[2]) {
00534
00535
00536 for (i=0;i<NSUBEXP;i++,sp++,ep++) {
00537 if (*sp==NULL) break;
00538 sprintf(buffer,"%d",i);
00539 n3=find(featcmp,buffer,args[2]->attr_list);
00540 if (n3) {
00541 ptr_psi_term psi = (ptr_psi_term) n3->data;
00542
00543
00544
00545 ptr_psi_term bounds = stack_pair(stack_int(*sp - (char *)args[1]->value + 1),
00546 stack_int(*ep - (char *)args[1]->value + 1));
00547 push_goal(unify,psi,bounds,NULL);
00548 }
00549 }
00550
00551 unify_bool_result(result,TRUE);
00552 }
00553 else {
00554
00555 ptr_psi_term psi = stack_psi_term(4);
00556 psi->type = top;
00557 for (i=0;i<NSUBEXP;i++,sp++,ep++) {
00558 if (*sp==NULL) break;
00559 sprintf(buffer,"%d",i);
00560 { ptr_psi_term bounds = stack_pair(stack_int(*sp - (char *)args[1]->value + 1),
00561 stack_int(*ep - (char *)args[1]->value + 1));
00562 stack_insert_copystr(buffer,&(psi->attr_list),bounds); }
00563 }
00564
00565 push_goal(unify,psi,result,NULL);
00566 }
00567 return TRUE;
00568 }
00569 }
00570
00571 static long
00572 c_regexp_execute()
00573 {
00574 psi_arg args[4];
00575 SETARG(args,0, "1" , sys_regexp , REQUIRED );
00576 SETARG(args,1, "2" , quoted_string , REQUIRED );
00577 SETARG(args,2, "3" , top , OPTIONAL|NOVALUE );
00578 SETARG(args,3, "offset" , integer , OPTIONAL );
00579 return call_primitive(regexp_execute_internal,NARGS(args),args,0);
00580 }
00581 #endif
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 #define FP_NONE 0
00593 #define FP_INPUT 1
00594 #define FP_OUTPUT 2
00595
00596 typedef struct a_stream {
00597 FILE *fp;
00598 int op;
00599 } *ptr_stream;
00600
00601 #define FP_PREPARE(s,OP) \
00602 if (s->op != OP && s->op != FP_NONE) fflush(s->fp); \
00603 s->op = OP;
00604
00605 ptr_psi_term
00606 fileptr2stream(fp,typ)
00607 FILE*fp;
00608 ptr_definition*typ;
00609 {
00610 ptr_psi_term result = make_bytedata(typ,sizeof(struct a_stream));
00611 ((ptr_stream)BYTEDATA_DATA(result))->fp = fp;
00612 ((ptr_stream)BYTEDATA_DATA(result))->op = FP_NONE;
00613 return result;
00614 }
00615
00616 static long
00617 int2stream_internal(args,result,funct)
00618 ptr_psi_term args[],result,funct;
00619 {
00620 FILE *fp = fdopen((int)*(REAL*)args[0]->value,
00621 (char*)args[1]->value);
00622 if (fp==NULL) return FALSE;
00623 else {
00624 push_goal(unify,fileptr2stream(fp,sys_stream),result,NULL);
00625
00626
00627
00628 return TRUE;
00629 }
00630 }
00631
00632 static long
00633 c_int2stream()
00634 {
00635 psi_arg args[2];
00636 SETARG(args,0,"1",integer,REQUIRED);
00637 SETARG(args,1,"2",quoted_string,REQUIRED);
00638 return call_primitive(int2stream_internal,NARGS(args),args,0);
00639 }
00640
00641 static long
00642 fopen_internal(args,result,funct)
00643 ptr_psi_term args[],result,funct;
00644 {
00645 FILE *fp = fopen((char*)args[0]->value,
00646 (char*)args[1]->value);
00647 if (fp==NULL) return FALSE;
00648 else {
00649
00650
00651
00652 push_goal(unify,fileptr2stream(fp,sys_file_stream),result,NULL);
00653 return TRUE;
00654 }
00655 }
00656
00657 static long
00658 c_fopen()
00659 {
00660 psi_arg args[2];
00661 SETARG(args,0, "1" , quoted_string , REQUIRED );
00662 SETARG(args,1, "2" , quoted_string , REQUIRED );
00663 return call_primitive(fopen_internal,NARGS(args),args,0);
00664 }
00665
00666 static long
00667 fclose_internal(args,result,funct)
00668 ptr_psi_term args[],result,funct;
00669 {
00670 if (fclose(((ptr_stream)BYTEDATA_DATA(args[0]))->fp) != 0)
00671 return FALSE;
00672 else
00673 return TRUE;
00674 }
00675
00676 static long
00677 c_fclose()
00678 {
00679 psi_arg args[1];
00680 SETARG(args,0, "1" , sys_stream , REQUIRED );
00681 return call_primitive(fclose_internal,NARGS(args),args,0);
00682 }
00683
00684 static long
00685 fwrite_internal(args,result,funct)
00686 ptr_psi_term args[],result,funct;
00687 {
00688 ptr_stream srm = (ptr_stream)BYTEDATA_DATA(args[0]);
00689
00690 char* txt = (char*)args[1]->value;
00691 FP_PREPARE(srm,FP_OUTPUT);
00692 if (txt && *txt!='\0' &&
00693 fwrite((void*)txt,sizeof(char),strlen(txt),srm->fp)<=0)
00694 return FALSE;
00695 return TRUE;
00696 }
00697
00698 static long
00699 c_fwrite()
00700 {
00701 psi_arg args[2];
00702 SETARG(args,0,"1",sys_stream,MANDATORY);
00703 SETARG(args,1,"2",quoted_string,MANDATORY);
00704 return call_primitive(fwrite_internal,NARGS(args),args,0);
00705 }
00706
00707 static long
00708 fflush_internal(args,result,funct)
00709 ptr_psi_term args[],result,funct;
00710 {
00711 ptr_stream srm = (ptr_stream)BYTEDATA_DATA(args[0]);
00712
00713 srm->op = FP_NONE;
00714 if (fflush(srm->fp)!=0) return FALSE;
00715 return TRUE;
00716 }
00717
00718 static long
00719 c_fflush()
00720 {
00721 psi_arg args[1];
00722 SETARG(args,0,"1",sys_stream,MANDATORY);
00723 return call_primitive(fflush_internal,NARGS(args),args,0);
00724 }
00725
00726 static long
00727 get_buffer_internal(args,result,funct)
00728 ptr_psi_term args[],result,funct;
00729 {
00730 ptr_stream srm = (ptr_stream)BYTEDATA_DATA(args[0]);
00731
00732 long size = *(REAL*)args[1]->value;
00733 ptr_psi_term t = stack_psi_term(4);
00734 t->type = quoted_string;
00735 t->value=(GENERIC)heap_alloc(size+1);
00736 bzero((char*)t->value,size+1);
00737 FP_PREPARE(srm,FP_INPUT);
00738 if (fread((void*)t->value,sizeof(char),size,srm->fp) <= 0)
00739 return FALSE;
00740 push_goal(unify,t,result,NULL);
00741 return TRUE;
00742 }
00743
00744 static long
00745 c_get_buffer()
00746 {
00747 psi_arg args[2];
00748 SETARG(args,0,"1",sys_stream,REQUIRED);
00749 SETARG(args,1,"2",integer,REQUIRED);
00750 return call_primitive(get_buffer_internal,NARGS(args),args,0);
00751 }
00752
00753 #define TEXTBUFSIZE 5000
00754
00755 struct text_buffer {
00756 struct text_buffer *next;
00757 int top;
00758 char data[TEXTBUFSIZE];
00759 };
00760
00761
00762
00763
00764
00765 int
00766 text_buffer_next(buf,idx,c,rbuf,ridx)
00767 struct text_buffer *buf,**rbuf;
00768 char c;
00769 int idx,*ridx;
00770 {
00771 while (buf) {
00772 while (idx<buf->top)
00773 if (buf->data[idx] == c) {
00774 *rbuf=buf;
00775 *ridx=idx;
00776 return 1;
00777 }
00778 else idx++;
00779 buf=buf->next;
00780 idx=0;
00781 }
00782 return 0;
00783 }
00784
00785
00786
00787
00788
00789 char*
00790 text_buffer_cmp(buf,idx,str)
00791 struct text_buffer *buf;
00792 int idx;
00793 char *str;
00794 {
00795 while (buf) {
00796 while (idx<buf->top)
00797 if (!*str || buf->data[idx] != *str)
00798 return 0;
00799 else { idx++; str++; }
00800 if (!*str && !buf->next) return str;
00801 else {
00802 buf=buf->next;
00803 idx=0;
00804 }
00805 }
00806 return 0;
00807 }
00808
00809
00810
00811
00812
00813
00814 void
00815 text_buffer_push(buf,c)
00816 struct text_buffer **buf;
00817 char c;
00818 {
00819 if ((*buf)->top < TEXTBUFSIZE)
00820 (*buf)->data[(*buf)->top++] = c;
00821 else {
00822 (*buf)->next = (struct text_buffer *)
00823 malloc(sizeof(struct text_buffer));
00824 if (!(*buf)->next) {
00825 fprintf(stderr,"Fatal error: malloc failed in text_buffer_push\n");
00826 exit(-1);
00827 }
00828 bzero((char*)(*buf)->next,sizeof(struct text_buffer));
00829 *buf = (*buf)->next;
00830 (*buf)->top = 1;
00831 (*buf)->data[0]=c;
00832 }
00833 }
00834
00835
00836 void
00837 text_buffer_free(buf)
00838 struct text_buffer *buf;
00839 {
00840 struct text_buffer *next;
00841 while (buf) {
00842 next = buf->next;
00843 free(buf);
00844 buf=next;
00845 }
00846 }
00847
00848 static long
00849 get_record_internal(args,result,funct)
00850 ptr_psi_term args[],result,funct;
00851 {
00852 struct text_buffer rootbuf;
00853 struct text_buffer *curbuf = &rootbuf;
00854 struct text_buffer *lastbuf = &rootbuf;
00855 int lastidx = 0,size;
00856 ptr_stream srm = (ptr_stream)BYTEDATA_DATA(args[0]);
00857 FILE *fp = srm->fp;
00858 char *sep = (char*)args[1]->value;
00859 int c;
00860 ptr_psi_term t;
00861 char *cursep = sep;
00862
00863 FP_PREPARE(srm,FP_INPUT);
00864 bzero((char*)&rootbuf,sizeof(rootbuf));
00865 if (!sep || !*sep) {
00866
00867 while ((c=getc(fp)) != EOF)
00868 text_buffer_push(&curbuf,(char)c);
00869 goto PackUpAndLeave;
00870 }
00871
00872 if (sep[1]=='\0') {
00873
00874 while ((c=getc(fp)) != EOF) {
00875 text_buffer_push(&curbuf,(char)c);
00876 if (c==*sep) break;
00877 }
00878 goto PackUpAndLeave;
00879 }
00880
00881
00882
00883 WaitForStart:
00884 if ((c=getc(fp)) == EOF) goto PackUpAndLeave;
00885 text_buffer_push(&curbuf,(char)c);
00886 if (c==*sep) {
00887 cursep = sep+1;
00888 lastbuf=curbuf;
00889 lastidx=curbuf->top - 1;
00890 goto MatchNext;
00891 }
00892 else goto WaitForStart;
00893
00894 MatchNext:
00895 if (!*cursep || (c=getc(fp))==EOF) goto PackUpAndLeave;
00896 text_buffer_push(&curbuf,(char)c);
00897 if (c!=*cursep) goto TryAgain;
00898 cursep++;
00899 goto MatchNext;
00900
00901 TryAgain:
00902 if (!text_buffer_next(lastbuf,lastidx+1,*sep,&lastbuf,&lastidx))
00903 goto WaitForStart;
00904 if (!(cursep=text_buffer_cmp(lastbuf,lastidx,sep)))
00905 goto TryAgain;
00906 goto MatchNext;
00907
00908 PackUpAndLeave:
00909
00910 for(lastbuf=&rootbuf,size=0;lastbuf!=NULL;lastbuf=lastbuf->next)
00911 size += lastbuf->top;
00912 t=stack_psi_term(0);
00913 t->type=quoted_string;
00914 t->value=(GENERIC)heap_alloc(size+1);
00915 for(lastbuf=&rootbuf,sep=(char*)t->value;
00916 lastbuf!=NULL;sep+=lastbuf->top,lastbuf=lastbuf->next)
00917 bcopy(lastbuf->data,sep,lastbuf->top);
00918 ((char*)t->value)[size]='\0';
00919 text_buffer_free(rootbuf.next);
00920 push_goal(unify,t,result,NULL);
00921 return TRUE;
00922 }
00923
00924 static long
00925 c_get_record()
00926 {
00927 psi_arg args[2];
00928 SETARG(args,0,"1",sys_stream,REQUIRED);
00929 SETARG(args,1,"2",quoted_string,REQUIRED);
00930 return call_primitive(get_record_internal,NARGS(args),args,0);
00931 }
00932
00933 static long
00934 get_code_internal(args,result,funct)
00935 ptr_psi_term args[],result,funct;
00936 {
00937 ptr_stream srm = (ptr_stream)BYTEDATA_DATA(args[0]);
00938 int c;
00939 FP_PREPARE(srm,FP_INPUT);
00940 if ((c=getc(srm->fp)) == EOF) return FALSE;
00941 else return unify_real_result(result,(REAL)c);
00942 }
00943
00944 static long
00945 c_get_code()
00946 {
00947 psi_arg args[1];
00948 SETARG(args,0,"1",sys_stream,REQUIRED);
00949 return call_primitive(get_code_internal,NARGS(args),args,0);
00950 }
00951
00952 static long
00953 ftell_internal(args,result,funct)
00954 ptr_psi_term args[],result,funct;
00955 {
00956 ptr_stream srm = (ptr_stream)BYTEDATA_DATA(args[0]);
00957 if (srm->op != FP_NONE || srm->op != FP_INPUT) {
00958 fflush(srm->fp);
00959 srm->op = FP_NONE;
00960 }
00961 return unify_real_result(result,(REAL)ftell(srm->fp));
00962
00963 }
00964
00965 static long
00966 c_ftell()
00967 {
00968 psi_arg args[1];
00969 SETARG(args,0,"1",sys_file_stream,REQUIRED);
00970 return call_primitive(ftell_internal,NARGS(args),args,0);
00971 }
00972
00973 #ifndef SEEK_SET
00974 #define SEEK_SET 0
00975 #endif
00976 #ifndef SEEK_CUR
00977 #define SEEK_CUR 1
00978 #endif
00979 #ifndef SEEK_END
00980 #define SEEK_END 2
00981 #endif
00982
00983 static long
00984 fseek_internal(args,result,funct)
00985 ptr_psi_term args[],result,funct;
00986 {
00987 ptr_stream srm = (ptr_stream)BYTEDATA_DATA(args[0]);
00988 srm->op = FP_NONE;
00989 return
00990 (fseek(srm->fp ,
00991 (long)*(REAL*)args[1]->value,
00992 args[2]?(long)*(REAL*)args[2]->value:SEEK_SET) < 0)
00993 ?FALSE:TRUE;
00994 }
00995
00996 static long
00997 c_fseek()
00998 {
00999 psi_arg args[3];
01000 SETARG(args,0,"1",sys_file_stream,MANDATORY);
01001 SETARG(args,1,"2",integer,MANDATORY);
01002 SETARG(args,2,"3",integer,OPTIONAL);
01003 return call_primitive(fseek_internal,NARGS(args),args,0);
01004 }
01005
01006 static long
01007 stream2sys_stream_internal(args,result,funct)
01008 ptr_psi_term args[],result,funct;
01009 {
01010 push_goal(unify,fileptr2stream((FILE*)args[0]->value,sys_stream),
01011 result,NULL);
01012 return TRUE;
01013 }
01014
01015 static long
01016 c_stream2sys_stream()
01017 {
01018 psi_arg args[1];
01019 SETARG(args,0,"1",stream,REQUIRED);
01020 return call_primitive(stream2sys_stream_internal,NARGS(args),args,0);
01021 }
01022
01023 static long
01024 sys_stream2stream_internal(args,result,funct)
01025 ptr_psi_term args[],result,funct;
01026 {
01027 ptr_psi_term tmp;
01028 tmp=stack_psi_term(4);
01029 tmp->type=stream;
01030 tmp->value=(GENERIC)((ptr_stream)BYTEDATA_DATA(args[0]))->fp;
01031 push_goal(unify,tmp,result,NULL);
01032 return TRUE;
01033 }
01034
01035 static long
01036 c_sys_stream2stream()
01037 {
01038 psi_arg args[1];
01039 SETARG(args,0,"1",sys_stream,REQUIRED);
01040 return call_primitive(sys_stream2stream_internal,NARGS(args),args,0);
01041 }
01042
01043
01044
01045 #ifndef OS2_PORT
01046 #include <sys/socket.h>
01047 #include <netinet/in.h>
01048 #include <sys/un.h>
01049 #include <netdb.h>
01050 #include <arpa/inet.h>
01051 #include <ctype.h>
01052
01053 static long
01054 socket_internal(args,result,funct)
01055 ptr_psi_term args[],result,funct;
01056 {
01057 int addr_family=AF_INET,type=SOCK_STREAM,protocol=0;
01058 char *s;
01059 int fd;
01060
01061 if (args[0]) {
01062 s=(char*)args[0]->value;
01063 if (!strcmp(s,"AF_UNIX")) addr_family=AF_UNIX;
01064 else if (!strcmp(s,"AF_INET")) addr_family=AF_INET;
01065 else {
01066 Errorline("Unknown address family in %P.\n",funct);
01067 return FALSE; }
01068 }
01069
01070 if (args[1]) {
01071 s=(char*)args[1]->value;
01072 if (!strcmp(s,"SOCK_STREAM")) type=SOCK_STREAM;
01073 else if (!strcmp(s,"SOCK_DGRAM" )) type=SOCK_DGRAM;
01074 else if (!strcmp(s,"SOCK_RAW" )) {
01075 Errorline("SOCK_RAW not supported in %P.\n",funct);
01076 return FALSE; }
01077 else {
01078 Errorline("Unknown socket type in %P.\n",funct);
01079 return FALSE; }
01080 }
01081
01082 if ((fd=socket(addr_family,type,protocol))<0)
01083 return FALSE;
01084
01085 { FILE*fp = fdopen(fd,"r+");
01086 ptr_psi_term t;
01087
01088 if (fp==NULL) {
01089 Errorline("fdopen failed on socket in %P.\n",funct);
01090 return FALSE;
01091 }
01092
01093
01094
01095 push_goal(unify,fileptr2stream(fp,sys_socket_stream),result,NULL);
01096 }
01097 return TRUE;
01098 }
01099
01100 static long
01101 c_socket()
01102 {
01103 psi_arg args[2];
01104 SETARG(args,0,"1",quoted_string,OPTIONAL);
01105 SETARG(args,1,"2",quoted_string,OPTIONAL);
01106 return call_primitive(socket_internal,NARGS(args),args,0);
01107 }
01108
01109 int
01110 is_ipaddr(s)
01111 char*s;
01112 {
01113 if (s==NULL) return 0;
01114 while (*s)
01115 if (!isdigit(*s) && *s!='.') return 0;
01116 else s++;
01117 return 1;
01118 }
01119
01120 static long
01121 bind_or_connect_internal(args,result,funct,info)
01122 ptr_psi_term args[],result,funct;
01123 void*info;
01124 {
01125 int fd = fileno(((ptr_stream)BYTEDATA_DATA(args[0]))->fp);
01126 int do_bind = info==NULL;
01127
01128 if (args[1] || args[2]) {
01129
01130 struct sockaddr_in name;
01131 char* hostname = args[1]?(char*)args[1]->value:NULL;
01132 int port;
01133 if (!args[2]) {
01134 Errorline("Missing port number in %P.\n",funct);
01135 return FALSE;
01136 }
01137
01138 bzero((char*)&name,sizeof(name));
01139 name.sin_family = AF_INET;
01140 name.sin_port = htons((unsigned short)*(REAL*)args[2]->value);
01141
01142 if (!hostname || *hostname=='\0' || !strcasecmp(hostname,"localhost"))
01143 name.sin_addr.s_addr = INADDR_ANY;
01144 else {
01145 struct hostent * h;
01146 int ipaddr;
01147 if ((ipaddr=is_ipaddr(hostname))) {
01148 int i = inet_addr(hostname);
01149 h = gethostbyaddr((char*)&i,sizeof(i),AF_INET);
01150 } else h = gethostbyname(hostname);
01151 if (h==NULL) {
01152 Errorline("%s failed for %P.\n",
01153 ipaddr?"gethostbyaddr":"gethostbyname",funct);
01154 return FALSE;
01155 }
01156 bcopy(h->h_addr,(char*)&(name.sin_addr.s_addr),h->h_length);
01157 }
01158 if ((do_bind?
01159 bind(fd,(struct sockaddr *)&name,sizeof(name)):
01160 connect(fd,(struct sockaddr *)&name,sizeof(name))) < 0) {
01161 Errorline("%s failed in %P.\n",do_bind?"bind":"connect",funct);
01162 return FALSE;
01163 }
01164 }
01165 else if (args[3]) {
01166
01167 struct sockaddr_un name;
01168 char* path = (char*)args[3]->value;
01169
01170 name.sun_family = AF_UNIX;
01171 strcpy(name.sun_path,path);
01172
01173 if ((do_bind?
01174 bind(fd,(struct sockaddr *)&name,sizeof(name)):
01175 connect(fd,(struct sockaddr *)&name,sizeof(name))) < 0) {
01176 Errorline("%s failed in %P.\n",do_bind?"bind":"connect",funct);
01177 return FALSE;
01178 }
01179 }
01180 else {
01181 Errorline("Too few arguments in %P.\n",funct);
01182 return FALSE;
01183 }
01184 return TRUE;
01185 }
01186
01187 static long
01188 c_bind()
01189 {
01190 psi_arg args[4];
01191 SETARG(args,0,"1",sys_socket_stream,MANDATORY);
01192 SETARG(args,1,"host",quoted_string,OPTIONAL);
01193 SETARG(args,2,"port",integer,OPTIONAL);
01194 SETARG(args,3,"path",quoted_string,OPTIONAL);
01195 return call_primitive(bind_or_connect_internal,NARGS(args),args,NULL);
01196 }
01197
01198 static long
01199 c_connect()
01200 {
01201 psi_arg args[4];
01202 SETARG(args,0,"1",sys_socket_stream,MANDATORY);
01203 SETARG(args,1,"host",quoted_string,OPTIONAL);
01204 SETARG(args,2,"port",integer,OPTIONAL);
01205 SETARG(args,3,"path",quoted_string,OPTIONAL);
01206 return call_primitive(bind_or_connect_internal,NARGS(args),args,(void*)1);
01207 }
01208
01209 static long
01210 listen_internal(args,result,funct)
01211 ptr_psi_term args[],result,funct;
01212 {
01213 int fd = fileno(((ptr_stream)BYTEDATA_DATA(args[0]))->fp);
01214 int n = *(REAL*)args[1]->value;
01215
01216 if (listen(fd,n) < 0) return FALSE;
01217 return TRUE;
01218 }
01219
01220 static long
01221 c_listen()
01222 {
01223 psi_arg args[2];
01224 SETARG(args,0,"1",sys_socket_stream,MANDATORY);
01225 SETARG(args,1,"2",integer,MANDATORY);
01226 return call_primitive(listen_internal,NARGS(args),args,0);
01227 }
01228
01229 static long
01230 accept_internal(args,result,funct)
01231 ptr_psi_term args[],result,funct;
01232 {
01233 int fd = fileno(((ptr_stream)BYTEDATA_DATA(args[0]))->fp);
01234 int s;
01235
01236 if ((s=accept(fd,NULL,NULL)) < 0) return FALSE;
01237 else {
01238 FILE * fp = fdopen(s,"r+");
01239 ptr_psi_term t;
01240
01241 if (fp==NULL) {
01242 Errorline("fdopen failed on socket in %P.\n",funct);
01243 return FALSE;
01244 }
01245
01246
01247
01248 push_goal(unify,fileptr2stream(fp,sys_socket_stream),result,NULL);
01249 return TRUE;
01250 }
01251 }
01252
01253 static long
01254 c_accept()
01255 {
01256 psi_arg args[1];
01257 SETARG(args,0,"1",sys_socket_stream,REQUIRED);
01258 return call_primitive(accept_internal,NARGS(args),args,0);
01259 }
01260 #endif
01261
01262
01263
01264 static long
01265 errno_internal(args,result,funct)
01266 ptr_psi_term args[],result,funct;
01267 {
01268 push_goal(unify,stack_int(errno),result,NULL);
01269 return TRUE;
01270 }
01271
01272 static long
01273 c_errno()
01274 {
01275 return call_primitive(errno_internal,0,NULL,0);
01276 }
01277
01278
01279 #ifndef OS2_PORT
01280 extern char *sys_errlist[];
01281 extern int sys_nerr;
01282
01283 static long
01284 errmsg_internal(args,result,funct)
01285 ptr_psi_term args[],result,funct;
01286 {
01287 long n = args[0]?(long)*(REAL*)args[0]->value:errno;
01288 if (n<0 || n>=sys_nerr) return FALSE;
01289 else {
01290 push_goal(unify,stack_string(sys_errlist[n]),result,NULL);
01291 return TRUE;
01292 }
01293 }
01294
01295 static long
01296 c_errmsg()
01297 {
01298 psi_arg args[1];
01299 SETARG(args,0, "1" , integer , OPTIONAL );
01300 return call_primitive(errmsg_internal,NARGS(args),args,0);
01301 }
01302 #endif
01303
01304
01305
01306
01307
01308
01309
01310
01311 static long
01312 import_symbol_internal(args,result,funct)
01313 ptr_psi_term args[],result,funct;
01314 {
01315 ptr_keyword key;
01316
01317 if (args[1])
01318 key=args[1]->type->keyword;
01319 else
01320 key=hash_lookup(current_module->symbol_table,
01321 args[0]->type->keyword->symbol);
01322
01323 if (key)
01324 if (key->definition->type != undef) {
01325 Errorline("symbol %s already defined in %P.",key->combined_name,funct);
01326 return FALSE;
01327 }
01328 else key->definition=args[0]->type;
01329 else {
01330
01331
01332 key=HEAP_ALLOC(struct wl_keyword);
01333 key->module=current_module;
01334
01335 key->symbol=args[0]->type->keyword->symbol;
01336 key->combined_name=
01337 heap_copy_string(make_module_token(current_module,key->symbol));
01338 key->public=FALSE;
01339 key->private_feature=FALSE;
01340 key->definition=args[0]->type;
01341
01342 hash_insert(current_module->symbol_table,key->symbol,key);
01343 }
01344 return TRUE;
01345 }
01346
01347 static long
01348 c_import_symbol()
01349 {
01350 psi_arg args[2];
01351 SETARG(args,0,"1",top,MANDATORY|UNEVALED);
01352 SETARG(args,1,"as",top,OPTIONAL|NOVALUE|UNEVALED);
01353 return call_primitive(import_symbol_internal,NARGS(args),args,0);
01354 }
01355
01356
01357
01358 #ifndef OS2_PORT
01359 static long
01360 fork_internal(args,result,funct)
01361 ptr_psi_term args[],result,funct;
01362 {
01363 pid_t id = fork();
01364 if (id < 0) return FALSE;
01365 else return unify_real_result(result,(REAL)id);
01366 }
01367
01368 static long
01369 c_fork()
01370 {
01371 return call_primitive(fork_internal,0,NULL,0);
01372 }
01373
01374 typedef struct {
01375 char * name;
01376 ptr_psi_term value;
01377 } psi_feature;
01378
01379 #define SETFEATURE(lst,n,nam,val) ((lst[n].name=nam),(lst[n].value=val))
01380
01381 static long
01382 unify_pterm_result(t,sym,lst,n)
01383 ptr_psi_term t;
01384 ptr_definition sym;
01385 psi_feature lst[];
01386 int n;
01387 {
01388 ptr_psi_term u;
01389 int i;
01390 if (n<0) {
01391 fprintf(stderr,"unify_pterm_result called with n<0: n=%d\n",n);
01392 exit(-1);
01393 }
01394 u=stack_psi_term(4);
01395 u->type=sym;
01396 for(i=0;i<n;i++)
01397 stack_insert(featcmp,lst[i].name,&(u->attr_list),lst[i].value);
01398 push_goal(unify,t,u,NULL);
01399 return TRUE;
01400 }
01401 #endif
01402 char *
01403 get_numeric_feature(n)
01404 long n;
01405 {
01406 if (n==1) return one;
01407 else if (n==2) return two;
01408 else if (n==3) return three;
01409 else {
01410 char buf[100];
01411 sprintf(buf,"%d",n);
01412 return heap_copy_string(buf);
01413 }
01414 }
01415 #ifndef OS2_PORT
01416 #ifndef WIFEXITED
01417 #include <sys/wait.h>
01418 #endif
01419
01420 ptr_definition sys_process_no_children;
01421 ptr_definition sys_process_exited;
01422 ptr_definition sys_process_signaled;
01423 ptr_definition sys_process_stopped;
01424 ptr_definition sys_process_continued;
01425
01426 static long
01427 unify_wait_result(result,id,status)
01428 ptr_psi_term result;
01429 pid_t id;
01430 int status;
01431 {
01432 int n=2;
01433 ptr_definition sym;
01434 psi_feature lst[2];
01435 SETFEATURE(lst,0,one,stack_int(id));
01436 if (id == -1 || status == -1) {
01437 if (errno==ECHILD) {
01438 sym = sys_process_no_children;
01439 n=0;
01440 }
01441 else return FALSE;
01442 }
01443 else if (WIFEXITED(status)) {
01444 SETFEATURE(lst,1,two,stack_int(WEXITSTATUS(status)));
01445 sym = sys_process_exited;
01446 }
01447 else if (WIFSIGNALED(status)) {
01448 SETFEATURE(lst,1,two,stack_int(WTERMSIG(status)));
01449 sym = sys_process_signaled;
01450 }
01451 else if (WIFSTOPPED(status)) {
01452 SETFEATURE(lst,1,two,stack_int(WSTOPSIG(status)));
01453 sym = sys_process_stopped;
01454 }
01455 #ifdef WIFCONTINUED
01456 else if (WIFCONTINUED(status)) {
01457 sym = sys_process_continued;
01458 n=1;
01459 }
01460 #endif
01461 else {
01462 Errorline("Unexpected wait status: %d",status);
01463 return FALSE;
01464 }
01465 return unify_pterm_result(result,sym,lst,n);
01466 }
01467
01468 static long
01469 wait_internal(args,result,funct)
01470 ptr_psi_term args[],result,funct;
01471 {
01472 int status;
01473 pid_t id = wait(&status);
01474 return unify_wait_result(result,id,status);
01475 }
01476
01477 static long
01478 c_wait()
01479 {
01480 return call_primitive(wait_internal,0,NULL,0);
01481 }
01482
01483 static long
01484 waitpid_internal(args,result,funct)
01485 ptr_psi_term args[],result,funct;
01486 {
01487 int status;
01488 pid_t id = waitpid((pid_t)(long)*(REAL*)args[0]->value,&status,
01489 args[1]?(int)(long)*(REAL*)args[1]->value:0);
01490 return unify_wait_result(result,id,status);
01491 }
01492
01493 static long
01494 c_waitpid()
01495 {
01496 psi_arg args[2];
01497 SETARG(args,0,"1",integer,REQUIRED);
01498 SETARG(args,1,"2",integer,OPTIONAL);
01499 return call_primitive(waitpid_internal,NARGS(args),args,0);
01500 }
01501
01502 static long
01503 kill_internal(args,result,funct)
01504 ptr_psi_term args[],result,funct;
01505 {
01506 return (kill((pid_t)*(REAL*)args[0]->value,
01507 (int)*(REAL*)args[1]->value)==0)?TRUE:FALSE;
01508 }
01509
01510 static long
01511 c_kill()
01512 {
01513 psi_arg args[2];
01514 SETARG(args,0,"1",integer,MANDATORY);
01515 SETARG(args,1,"2",integer,MANDATORY);
01516 return call_primitive(kill_internal,NARGS(args),args,0);
01517 }
01518 #endif
01519
01520
01521 #ifndef OS2_PORT
01522 static long
01523 cuserid_internal(args,result,funct)
01524 ptr_psi_term args[],result,funct;
01525 {
01526 char name[L_cuserid+1];
01527 if (*cuserid(name) == '\0') return FALSE;
01528 else {
01529 push_goal(unify,result,stack_string(name),NULL);
01530 return TRUE;
01531 }
01532 }
01533
01534 static long
01535 c_cuserid()
01536 {
01537 return call_primitive(cuserid_internal,0,NULL,0);
01538 }
01539
01540 #ifndef MAXHOSTNAMELEN
01541 #include <sys/param.h>
01542 #endif
01543
01544 static long
01545 gethostname_internal(args,result,funct)
01546 ptr_psi_term args[],result,funct;
01547 {
01548 char name[MAXHOSTNAMELEN+1];
01549 if (gethostname(name,MAXHOSTNAMELEN+1) == 0) {
01550 push_goal(unify,result,stack_string(name),NULL);
01551 return TRUE;
01552 }
01553 else return FALSE;
01554 }
01555
01556 static long
01557 c_gethostname()
01558 {
01559 return call_primitive(gethostname_internal,0,NULL,0);
01560 }
01561 #endif
01562
01563
01564
01565 static long
01566 lazy_project_internal(args,result,funct)
01567 ptr_psi_term args[],result,funct;
01568 {
01569 ptr_node n;
01570 char buffer[100];
01571 if (args[1]->type == top) {
01572 residuate(args[0]);
01573 residuate(args[1]);
01574 return TRUE;
01575 }
01576 if (sub_type(args[1]->type,integer) && args[1]->value)
01577 sprintf(buffer,"%d",(long)*(REAL*)args[1]->value);
01578 else if (sub_type(args[1]->type,quoted_string) && args[1]->value)
01579 strcpy(buffer,(char*)args[1]->value);
01580 else
01581 strcpy(buffer,args[1]->type->keyword->symbol);
01582 n=find(featcmp,buffer,args[0]->attr_list);
01583 if (n) push_goal(unify,n->data,result,NULL);
01584
01585
01586
01587
01588 else residuate(args[0]);
01589 return TRUE;
01590 }
01591
01592 static long
01593 c_lazy_project()
01594 {
01595 psi_arg args[2];
01596 SETARG(args,0,"1",top,REQUIRED|NOVALUE);
01597 SETARG(args,1,"2",top,REQUIRED|NOVALUE);
01598 return call_primitive(lazy_project_internal,NARGS(args),args,0);
01599 }
01600
01601
01602
01603
01604 static long
01605 wait_on_feature_internal(args,result,funct)
01606 ptr_psi_term args[],result,funct;
01607 {
01608 char buffer[100];
01609 if (args[1]->type == top) {
01610 residuate(args[0]);
01611 residuate(args[1]);
01612 return TRUE;
01613 }
01614 if (sub_type(args[1]->type,integer) && args[1]->value)
01615 sprintf(buffer,"%d",(long)*(REAL*)args[1]->value);
01616 else if (sub_type(args[1]->type,quoted_string) && args[1]->value)
01617 strcpy(buffer,(char*)args[1]->value);
01618 else
01619 strcpy(buffer,args[1]->type->keyword->symbol);
01620 if (find(featcmp,buffer,args[0]->attr_list))
01621 push_goal(prove,args[2],DEFRULES,NULL);
01622
01623
01624
01625
01626 else residuate(args[0]);
01627 return TRUE;
01628 }
01629
01630 static long
01631 c_wait_on_feature()
01632 {
01633 psi_arg args[3];
01634 SETARG(args,0,"1",top,MANDATORY|NOVALUE);
01635 SETARG(args,1,"2",top,MANDATORY|NOVALUE);
01636 SETARG(args,2,"3",top,MANDATORY|NOVALUE|UNEVALED);
01637 return call_primitive(wait_on_feature_internal,NARGS(args),args,0);
01638 }
01639
01640 static long
01641 my_wait_on_feature_internal(args,result,funct)
01642 ptr_psi_term args[],result,funct;
01643 {
01644 char buffer[100];
01645 if (args[1]->type == top) {
01646 residuate(args[0]);
01647 residuate(args[1]);
01648 return TRUE;
01649 }
01650 if (sub_type(args[1]->type,integer) && args[1]->value)
01651 sprintf(buffer,"%d",(long)*(REAL*)args[1]->value);
01652 else if (sub_type(args[1]->type,quoted_string) && args[1]->value)
01653 strcpy(buffer,(char*)args[1]->value);
01654 else
01655 strcpy(buffer,args[1]->type->keyword->symbol);
01656 if (find(featcmp,buffer,args[0]->attr_list)) {
01657 unify_bool_result(result,TRUE);
01658 push_goal(prove,args[2],DEFRULES,NULL);
01659 }
01660
01661
01662
01663
01664 else residuate(args[0]);
01665 return TRUE;
01666 }
01667
01668 static long
01669 c_my_wait_on_feature()
01670 {
01671 psi_arg args[3];
01672 SETARG(args,0,"1",top,MANDATORY|NOVALUE);
01673 SETARG(args,1,"2",top,MANDATORY|NOVALUE);
01674 SETARG(args,2,"3",top,MANDATORY|NOVALUE|UNEVALED);
01675 return call_primitive(my_wait_on_feature_internal,NARGS(args),args,0);
01676 }
01677
01678
01679
01680
01681
01682
01683
01684 static long
01685 call_once_internal(args,result,funct)
01686 ptr_psi_term args[],result,funct;
01687 {
01688 ptr_psi_term value;
01689 ptr_choice_point cutpt = choice_stack;
01690 resid_aim=NULL;
01691 value = stack_psi_term(4);
01692 value->type = false;
01693 push_choice_point(unify,result,value,NULL);
01694 value = stack_psi_term(4);
01695 value->type = true;
01696 push_goal(unify,result,value,NULL);
01697 push_goal(general_cut,cutpt,NULL,NULL);
01698 push_goal(prove,args[0],DEFRULES,NULL);
01699 return TRUE;
01700 }
01701
01702 static long
01703 c_call_once()
01704 {
01705 psi_arg args[1];
01706 SETARG(args,0,"1",top,MANDATORY|NOVALUE|UNEVALED);
01707 return call_primitive(call_once_internal,NARGS(args),args,0);
01708 }
01709
01710 static long
01711 apply1_internal(args,result,funct)
01712 ptr_psi_term args[],result,funct;
01713 {
01714 long success=TRUE;
01715 if (args[0]->type==top) residuate(args[0]);
01716 else if (args[0]->type->type!=function) {
01717 Errorline("1st arg not a function in %P.\n",funct);
01718 success=FALSE;
01719 }
01720 else {
01721 char buffer[1000];
01722 char * feat;
01723 ptr_psi_term fun;
01724 if (sub_type(args[1]->type,integer) && args[1]->value)
01725 feat = get_numeric_feature((long)*(REAL*)args[1]->value);
01726 else if (sub_type(args[1]->type,quoted_string) && args[1]->value)
01727 feat = (char*)args[1]->value;
01728 else
01729 feat = heap_copy_string(args[1]->type->keyword->symbol);
01730 clear_copy();
01731 fun=distinct_copy(args[0]);
01732 stack_insert(featcmp,feat,&(fun->attr_list),args[2]);
01733 push_goal(eval,fun,result,fun->type->rule);
01734 }
01735 return success;
01736 }
01737
01738 static long
01739 c_apply1()
01740 {
01741 psi_arg args[3];
01742 SETARG(args,0,"1",top,REQUIRED|NOVALUE);
01743 SETARG(args,1,"2",top,REQUIRED|NOVALUE);
01744 SETARG(args,2,"3",top,REQUIRED|NOVALUE);
01745 return call_primitive(apply1_internal,NARGS(args),args,0);
01746 }
01747 #ifndef OS2_PORT
01748 static long
01749 getpid_internal(args,result,funct)
01750 ptr_psi_term args[],result,funct;
01751 {
01752 return unify_real_result(result,(REAL)getpid());
01753 }
01754
01755 static long
01756 c_getpid()
01757 {
01758 return call_primitive(getpid_internal,0,0,0);
01759 }
01760 #endif
01761
01762
01763
01764
01765 #ifdef LIFE_NDBM
01766 extern void make_ndbm_type_links();
01767 #endif
01768
01769 void
01770 make_sys_type_links()
01771 {
01772 #ifdef LIFE_NDBM
01773 make_ndbm_type_links();
01774 #endif
01775 make_type_link(sys_bitvector ,sys_bytedata);
01776 make_type_link(sys_regexp ,sys_bytedata);
01777 make_type_link(sys_stream ,sys_bytedata);
01778 make_type_link(sys_file_stream ,sys_stream);
01779 make_type_link(sys_socket_stream,sys_stream);
01780 make_type_link(sys_bytedata ,built_in);
01781 }
01782
01783 #ifdef LIFE_NDBM
01784 extern void check_ndbm_definitions();
01785 #endif
01786
01787 void
01788 check_sys_definitions()
01789 {
01790 check_definition(&sys_bytedata);
01791 check_definition(&sys_bitvector);
01792 check_definition(&sys_regexp);
01793 check_definition(&sys_stream);
01794 check_definition(&sys_file_stream);
01795 #ifndef OS2_PORT
01796 check_definition(&sys_socket_stream);
01797 check_definition(&sys_process_no_children);
01798 check_definition(&sys_process_exited);
01799 check_definition(&sys_process_signaled);
01800 check_definition(&sys_process_stopped);
01801 check_definition(&sys_process_continued);
01802 #endif
01803 #ifdef LIFE_NDBM
01804 check_ndbm_definitions();
01805 #endif
01806 }
01807
01808 #ifdef LIFE_DBM
01809 extern void insert_dbm_builtins();
01810 #endif
01811 #ifdef LIFE_NDBM
01812 extern void insert_ndbm_builtins();
01813 #endif
01814
01815 void
01816 insert_sys_builtins()
01817 {
01818 ptr_module curmod = current_module;
01819 set_current_module(sys_module);
01820
01821 sys_bytedata =update_symbol(sys_module,"bytedata");
01822 sys_bitvector =update_symbol(sys_module,"bitvector");
01823 sys_regexp =update_symbol(sys_module,"regexp");
01824 sys_stream =update_symbol(sys_module,"stream");
01825 sys_file_stream =update_symbol(sys_module,"file_stream");
01826 #ifndef OS2_PORT
01827 sys_socket_stream =update_symbol(sys_module,"socket_stream");
01828 sys_process_no_children=update_symbol(sys_module,"process_no_children");
01829 sys_process_exited =update_symbol(sys_module,"process_exited");
01830 sys_process_signaled =update_symbol(sys_module,"process_signaled");
01831 sys_process_stopped =update_symbol(sys_module,"process_stopped");
01832 sys_process_continued =update_symbol(sys_module,"process_continued");
01833 #endif
01834
01835
01836
01837
01838
01839 new_built_in(sys_module,"make_bitvector" ,function ,c_make_bitvector);
01840 new_built_in(sys_module,"bitvector_and" ,function ,c_bitvector_and);
01841 new_built_in(sys_module,"bitvector_or" ,function ,c_bitvector_or);
01842 new_built_in(sys_module,"bitvector_xor" ,function ,c_bitvector_xor);
01843 new_built_in(sys_module,"bitvector_not" ,function ,c_bitvector_not);
01844 new_built_in(sys_module,"bitvector_count" ,function ,c_bitvector_count);
01845 new_built_in(sys_module,"bitvector_get" ,function ,c_bitvector_get);
01846 new_built_in(sys_module,"bitvector_set" ,function ,c_bitvector_set);
01847 new_built_in(sys_module,"bitvector_clear" ,function ,c_bitvector_clear);
01848 #ifndef OS2_PORT
01849 new_built_in(sys_module,"regexp_compile" ,function ,c_regexp_compile);
01850 new_built_in(sys_module,"regexp_execute" ,function ,c_regexp_execute);
01851 #endif
01852 new_built_in(sys_module,"int2stream" ,function ,c_int2stream);
01853 new_built_in(sys_module,"fopen" ,function ,c_fopen);
01854 new_built_in(sys_module,"fclose" ,function ,c_fclose);
01855 new_built_in(sys_module,"get_buffer" ,function ,c_get_buffer);
01856 new_built_in(sys_module,"get_record" ,function ,c_get_record);
01857 new_built_in(sys_module,"get_code" ,function ,c_get_code);
01858 new_built_in(sys_module,"ftell" ,function ,c_ftell);
01859 new_built_in(sys_module,"fseek" ,predicate,c_fseek);
01860 #ifndef OS2_PORT
01861 new_built_in(sys_module,"socket" ,function ,c_socket);
01862 new_built_in(sys_module,"bind" ,predicate,c_bind);
01863 new_built_in(sys_module,"connect" ,predicate,c_connect);
01864 #endif
01865 new_built_in(sys_module,"fwrite" ,predicate,c_fwrite);
01866 new_built_in(sys_module,"fflush" ,predicate,c_fflush);
01867 #ifndef OS2_PORT
01868 new_built_in(sys_module,"listen" ,predicate,c_listen);
01869 new_built_in(sys_module,"accept" ,function ,c_accept);
01870 #endif
01871 new_built_in(sys_module,"errno" ,function ,c_errno);
01872 #ifndef OS2_PORT
01873 new_built_in(sys_module,"errmsg" ,function ,c_errmsg);
01874 #endif
01875 new_built_in(sys_module,"import_symbol" ,predicate,c_import_symbol);
01876 #ifndef OS2_PORT
01877 new_built_in(sys_module,"fork" ,function ,c_fork);
01878 new_built_in(sys_module,"wait" ,function ,c_wait);
01879 new_built_in(sys_module,"waitpid" ,function ,c_waitpid);
01880 new_built_in(sys_module,"kill" ,predicate,c_kill);
01881 new_built_in(sys_module,"cuserid" ,function ,c_cuserid);
01882 new_built_in(sys_module,"gethostname" ,function ,c_gethostname);
01883 #endif
01884
01885 new_built_in(sys_module,"lazy_project" ,function ,c_lazy_project);
01886 new_built_in(sys_module,"wait_on_feature" ,predicate,c_wait_on_feature);
01887 new_built_in(sys_module,"my_wait_on_feature" ,function ,c_my_wait_on_feature);
01888 new_built_in(sys_module,"apply1" ,function ,c_apply1);
01889 #ifndef OS2_PORT
01890 new_built_in(sys_module,"getpid" ,function ,c_getpid);
01891 #endif
01892 new_built_in(sys_module,"stream2sys_stream" ,function ,c_stream2sys_stream);
01893 new_built_in(sys_module,"sys_stream2stream" ,function ,c_sys_stream2stream);
01894 #ifdef LIFE_DBM
01895 insert_dbm_builtins();
01896 #endif
01897 #ifdef LIFE_NDBM
01898 insert_ndbm_builtins();
01899 #endif
01900 set_current_module(bi_module);
01901 new_built_in(bi_module ,"call_once" ,function ,c_call_once);
01902 set_current_module(curmod);
01903 }