|
|
1.1 ! root 1: .so tmac.tr ! 2: .DA "August 22, 1984" ! 3: .TR 84-14 ! 4: .Gr ! 5: .TL ! 6: Personalized Interpreters for Icon ! 7: .AU ! 8: Ralph E. Griswold ! 9: .AU ! 10: Robert K. McConeghy ! 11: .AU ! 12: William H. Mitchell ! 13: .AE ! 14: .tr *\(** ! 15: .NH ! 16: Introduction ! 17: .PP ! 18: Despite the fact that the Icon programming language has a large repertoire ! 19: of functions and operations for string and list manipulation, as ! 20: well as for more conventional computations [1], users frequently ! 21: need to extend that repertoire. While many extensions can be ! 22: written as procedures that build on the existing repertoire, there ! 23: are some kinds of extensions for which this approach is unacceptably ! 24: inefficient, inconvenient, or simply impractical. ! 25: .PP ! 26: Icon itself is written primarily in C [2] and its built-in functions ! 27: are written as corresponding C functions. Thus the natural way to ! 28: extend Icon's computational repertoire is to add new C functions to it. ! 29: .PP ! 30: The Icon system is organized so that this is comparatively easy to do. ! 31: Adding a new function ! 32: does not require changes to the Icon translator, ! 33: since all functions have a common syntactic form. An entry must be made in ! 34: a table that is used by the linker and the run-time system in order to ! 35: identify built-in functions and connect references to them to the ! 36: code itself. ! 37: .PP ! 38: The problem arises in incorporating the C code in the Icon run-time ! 39: system. Prior to Version 5.9 of Icon, there were two separate but ! 40: similar implementations of Icon: a compiler [3] and an interpreter [4]. ! 41: The primary difference between the two systems is that the linker for ! 42: the compiler generates assembly-language code, while the linker ! 43: for the interpreter generates code that is ready to be interpreted. ! 44: The interpreter ! 45: uses a ! 46: preconstructed run-time ! 47: system, so that the assembly and loading phases of the compiler implementation ! 48: is not needed. ! 49: .PP ! 50: The loading phase in the compiler is quite slow, so that when the ! 51: compiler implementation of Icon is used, there is a substantial delay ! 52: before getting into execution. This is a significant problem during ! 53: program debugging. Furthermore, a compiled Icon program runs only ! 54: slightly faster than an interpreted Icon program. This is due in large part ! 55: to the fact that most programs spend only a small percentage ! 56: of their time in ! 57: code generated for the program itself; most of the time is spent ! 58: executing code in the run-time system, which is essentially the ! 59: same in the two implementations. ! 60: .PP ! 61: The primary advantage of the compiler is that it is possible to ! 62: add new functions during the loading phase. In order to communicate ! 63: the names of new functions to the linker, it is necessary to ! 64: include ``external'' declarations in the Icon source programs that ! 65: use these functions. There is no way to do this in the interpreter ! 66: implementation, since the run-time system is preconstructed, rather ! 67: than being built when ! 68: the source-language program is processed. ! 69: .PP ! 70: One disadvantage of the external function approach is that every source ! 71: program that uses an external function must contain a declaration for ! 72: that function. In addition to the necessity for having to remember ! 73: these declarations, external functions are, by their nature, ! 74: not logically part of Icon proper. This results in problems of documentation ! 75: and distribution of such functions to other users. ! 76: .PP ! 77: An alternative method of adding new functions to either the ! 78: compiler or the interpreter implementation of Icon is to ! 79: add the corresponding C functions to the Icon system itself ! 80: and to rebuild the entire system. This approach is impractical ! 81: for many applications. If the extensions are not of general ! 82: interest, it is inappropriate to include them in the public ! 83: version of Icon. On the other hand, Icon is a large and complicated system, ! 84: and having many private versions may create serious problems of ! 85: maintenance and disk usage. Furthermore, rebuilding the Icon system ! 86: is slow, cumbersome, and comparatively complicated. This approach therefore ! 87: is impractical in a situation ! 88: such as a class in which students implement their own versions ! 89: of an extension. ! 90: .PP ! 91: To remedy these problems, a mechanism for building ``personalized ! 92: interpreters'' has been added to Version 5.9 of Icon. This mechanism ! 93: allows a user to add C functions and to build a corresponding ! 94: interpreter quickly, easily, and without the necessity to have ! 95: a copy of the source code for the entire Icon system. ! 96: .PP ! 97: To construct a personalized interpreter, the user must perform ! 98: a one-time set up that copies relevant source files to a ! 99: directory specified by the user and builds the nucleus of a run-time system. Once this is ! 100: done, the user can add and modify C functions and include them ! 101: in the personalized run-time system with little effort. ! 102: .PP ! 103: Since the linker must know the names of built-in functions, ! 104: a personalized linker is constructed. In order to run ! 105: Icon programs with the personalized run-time system, a ! 106: personalized command processor, which knows the location of ! 107: the personalized linker and run-time system, is provided also. ! 108: .PP ! 109: The modifications that can be made to Icon via a personalized ! 110: interpreter essentially are limited to the run-time system: the ! 111: addition of new functions, modifications to existing functions ! 112: and operations, and modifications and additions to support routines. There ! 113: is no provision for changing the syntax of Icon, incorporating ! 114: new operators, keyword, or control structures. ! 115: .NH ! 116: Building and Using a Personalized Interpreter ! 117: .NH 2 ! 118: Setting Up a Personalized Interpreter System ! 119: .PP ! 120: To set up a personalized interpreter, a new directory should ! 121: be created solely for the use of the interpreter; otherwise ! 122: files may be accidentally destroyed by the set-up process. ! 123: For the purpose of example, suppose this directory is ! 124: named \*Mmyicon\fR. The set-up process consists of ! 125: .Ds ! 126: mkdir myicon ! 127: cd myicon ! 128: icon\-pi ! 129: .De ! 130: Note that \*Micon\-pi\fR must be run in the area in which the personalized ! 131: interpreter is to be built. ! 132: The ! 133: location of \*Micon\-pi\fR may vary from site to site [5]. ! 134: .PP ! 135: The shell script \*Micon\-pi\fR constructs three subdirectories: ! 136: \*Mh\fR, \*Mstd\fR, and \*Mpi\fR. The subdirectory \*Mh\fR ! 137: contains header files that are needed in C routines. The subdirectory ! 138: \*Mstd\fR contains the portions of the Icon system that are needed ! 139: to build a personalized interpreter. The subdirectory \*Mpi\fR ! 140: contains a \*MMakefile\fR for building a personalized interpreter ! 141: and also is the place where source code for new C functions normally ! 142: resides. Thus work on the personalized interpreter is done in ! 143: \*Mmyicon/pi\fR. ! 144: .PP ! 145: The \*MMakefile\fR that is constructed by \*Micon\-pi\fR ! 146: contains two definitions to facilitate building personalized ! 147: interpreters: ! 148: .IP \*MOBJS\fR .5i ! 149: a list of object modules that are to be added to or replaced ! 150: in the run-time system. \*MOBJS\fR initially is empty. ! 151: .IP \*MLIB\fR ! 152: a list of library options that are used when the run-time system ! 153: is built. \*MLIB\fR initially is empty. ! 154: .LP ! 155: See the listing of a generic version of this \*MMakefile\fR in ! 156: Appendix A. ! 157: .NH 2 ! 158: Building a Personalized Interpreter ! 159: .PP ! 160: Performing a \fImake\fR in \*Mmyicon/pi\fR creates three files ! 161: in \*Mmyicon\fR: ! 162: .Ds ! 163: .ta 1i ! 164: picont \fRcommand processor\*M ! 165: pilink \fRlinker\*M ! 166: piconx \fRrun-time system\*M ! 167: .De ! 168: A link to \*Mpicont\fR also is constructed in \*Mmyicon/pi\fR so that ! 169: the new personalized interpreter can be tested in the directory in ! 170: which it is made. ! 171: .PP ! 172: The file \*Mpicont\fR normally is built only on the first \fImake\fR. The ! 173: file \*Mpilink\fR is built on the first \fImake\fR and is ! 174: rebuilt whenever the repertoire of built-in functions is changed. ! 175: The file \*Mpiconx\fR is rebuilt whenever the source code in the ! 176: run-time system is changed. ! 177: .PP ! 178: The user of the personalized interpreter uses \*Mpicont\fR in ! 179: the same fashion that the standard \*Micont\fR is used [4]. ! 180: (Note that the accidental use of \*Micont\fR in place of ! 181: \*Mpicont\fR may produce mysterious results.) ! 182: In turn, \*Mpicont\fR translates a source program using the ! 183: standard Icon translator and links it using \*Mpilink\fR. ! 184: The resulting icode file uses \*Mpiconx\fR. ! 185: .PP ! 186: The relocation bits and symbol tables in \*Mpicont\fR, \*Mpilink\fR, ! 187: and \*Mpiconx\fR can be removed by ! 188: .Ds ! 189: make Strip ! 190: .De ! 191: in \*Mmyicon/pi\fR. This reduces the sizes of these files substantially ! 192: but may interfere with debugging. ! 193: .PP ! 194: If a \fImake\fR is performed in \*Mmyicon/pi\fR before any ! 195: run-time files are added or modified, the resulting personalized ! 196: interpreter is identical to the standard one. Such a \fImake\fR can ! 197: be performed to verify that the personalized interpreter system ! 198: is performing properly. ! 199: .PP ! 200: Note that a personalized interpreter inherits the parameters and ! 201: configuration of the locally installed version of Icon in \*Mv5g\fR, including ! 202: optional language extensions [6]. ! 203: The file \*Mmyicon/h/config.h\fR contains configuration information. ! 204: The definitions in this file should not be changed. ! 205: .NH 2 ! 206: Adding a New Function ! 207: .PP ! 208: To add a new function to the personalized interpreter, it is first ! 209: necessary to provide the C code, adhering to the conventions and ! 210: data structures used throughout Icon. See [2]. Some examples of ! 211: C functions taken from the Icon program library [7] are included in Appendix B ! 212: of this report. The source code for these functions is contained in ! 213: \*Mv5g/pifunc\fR, where \*Mv5g\fR is the root of the Icon system. ! 214: The location of \*Mv5g\fR varies from site to site [5]. ! 215: The directory ! 216: \*Mv5g/functions\fR contains the source code for the standard built-in ! 217: functions, which also can be used as models for new ones. ! 218: .PP ! 219: Suppose that \*Mgetenv\fR from the Icon program library is to be ! 220: added to a personalized interpreter. The source code can be obtained by ! 221: .Ds ! 222: cp v5g/pifuncs/getenv.c myicon/pi ! 223: .De ! 224: (Note that the actual paths will be different, depending on the ! 225: local hierarchy.) ! 226: .PP ! 227: Three things now need to be done to ! 228: incorporate this function in the personalized interpreter: ! 229: .IP 1. ! 230: Add a line consisting of ! 231: .Ds ! 232: PDEF(getenv) ! 233: .De ! 234: to \*Mmyicon/h/pdef.h\fR in proper alphabetical order. ! 235: This causes the linker and the run-time system to know about the new function. ! 236: .IP 2. ! 237: Add \*Mgetenv.o\fR to the definition of \*MOBJS\fR in ! 238: \*Mmyicon/pi/Makefile\fR. ! 239: This causes \*Mgetenv.c\fR to be compiled and the resulting ! 240: object file to be loaded with the run-time system when a \fImake\fR is performed. ! 241: .IP 3. ! 242: Perform a \fImake\fR in \*Mmyicon/pi\fR. The result is ! 243: new versions of \*Mpilink\fR and \*Mpiconx\fR in \*Mmyicon\fR. ! 244: .LP ! 245: The function \*Mgetenv\fR now can be used like any other built-in ! 246: function. ! 247: .PP ! 248: More than one function can be included in a single source file. ! 249: See \*Mmath.c\fR in Appendix B. Note that \*Mmath.c\fR uses the ! 250: math library. To add this module to the run-time system of ! 251: a personalized interpreter, \*MPDEF\fR entries should be ! 252: made for each function in \*Mmath.c\fR, \*Mmath.o\fR should be added to ! 253: \*MOBJS\fR, and \*M\-lm\fR should be added to \*MLIB\fR in ! 254: the \*MMakefile\fR. ! 255: .NH 2 ! 256: Modifying the Existing Run-Time System ! 257: .PP ! 258: The use of personalized interpreters is not limited to the addition ! 259: of new functions. Any module in the standard run-time system can ! 260: be modified as well. The run-time system is divided into five ! 261: parts: ! 262: .RS ! 263: .IP \*Mv5g/functions\fR 1.2i ! 264: built-in functions ! 265: .IP \*Mv5g/operators\fR ! 266: built-in operators ! 267: .IP \*Mv5g/rt\fR ! 268: run-time support routines ! 269: .IP \*Mv5g/lib\fR ! 270: routines called by the interpreter ! 271: .IP \*Mv5g/iconx\fR ! 272: the interpreter and start-up routines ! 273: .RE ! 274: .LP ! 275: For example, storage allocation routines are contained in \*Mv5g/rt/alc.c\fR. ! 276: .PP ! 277: To modify an existing portion of the Icon run-time system, ! 278: copy the source code file from the standard system to \*Mmyicon/pi\fR. ! 279: (Source code for a few run-time routines is placed in \*Mmyicon/std\fR ! 280: when a personalized interpreter is set up. Check this directory ! 281: first and use that file, if appropriate, rather than making ! 282: another copy in \*Mmyicon/pi\fR.) When a source-code file in ! 283: \*Mmyicon/pi\fR has been modified, place it in the \*MOBJS\fR ! 284: list just like a new file and perform a \fImake\fR. Note that ! 285: an entire module must be replaced, even if a change is made to ! 286: only one routine. ! 287: Any module that is replaced must contain all the global variables in ! 288: the original module to prevent \fIld(1)\fR from also loading the ! 289: original module. There is no way to delete routines from the run-time ! 290: system. ! 291: .PP ! 292: The directory \*Mmyicon/h\fR contains header files that are included ! 293: in various source-code files. For example, error message text for ! 294: a new run-time error can be provided by adding it to \*Mmyicon/h/err.h\fR. ! 295: The file \*Mmyicon/h/rt.h\fR contains declarations and definitions that ! 296: are used throughout the run-time system. This is where the declaration ! 297: for the structure of a new type of data object would be placed. ! 298: .PP ! 299: Care ! 300: must be taken when modifying header files not to make changes that ! 301: would produce inconsistencies between previously compiled components ! 302: of the Icon run-time system and new ones. ! 303: .SH ! 304: References ! 305: .IP 1. ! 306: Griswold, Ralph E. and Griswold, Madge T. \fIThe Icon Programming ! 307: Language\fR. Prentice-Hall, Inc., Englewood Cliffs, New Jersey. 1983. ! 308: .IP 2. ! 309: Griswold, Ralph E., Robert K. McConeghy, and William H. Mitchell. ! 310: \fIA Tour Through the C Implementation of Icon; Version 5.9\fR. ! 311: Technical Report TR 84-11, Department of Computer Science, ! 312: The University of Arizona. August 1984. ! 313: .IP 3. ! 314: Griswold, Ralph E. and William H. Mitchell. \fIICONC(1)\fR, ! 315: manual page for \fIUNIX Programmer's Manual\fR, Department of ! 316: Computer Science, The University of Arizona. July 1983. ! 317: .IP 4. ! 318: Griswold, Ralph E. and William H. Mitchell. \fIICONT(1)\fR, ! 319: manual page for \fIUNIX Programmer's Manual\fR, Department of ! 320: Computer Science, The University of Arizona. August 1984. ! 321: .IP 5. ! 322: Griswold, Ralph E. and William H. Mitchell. ! 323: \fIInstallation and Maintenance Guide for Version 5.9 of Icon\fR. ! 324: Technical Report TR 84-13, Department of Computer Science, The ! 325: University of Arizona, Tucson, Arizona. August 1984. ! 326: .IP 6. ! 327: Griswold, Ralph E., Robert K. McConeghy, and William H. Mitchell. ! 328: \fIExtensions to Version 5 of the Icon Programming Language\fR. ! 329: Technical Report TR 84-10a, Department of Computer Science, ! 330: The University of Arizona. August 1984. ! 331: .IP 7. ! 332: Griswold, Ralph E. \fIThe Icon Program Library\fR, Technical Report ! 333: TR 84-12, Department of Computer Science, The University of ! 334: Arizona. August 1984. ! 335: .am Ds ! 336: .ps 8 ! 337: .vs 9 ! 338: .. ! 339: .am De ! 340: .ps 10 ! 341: .vs 12 ! 342: .. ! 343: .de Ta ! 344: .ta .8i +.8i +.8i +.8i +.8i +.8i +.8i +.8i ! 345: .. ! 346: .Ap "Appendix A \(em Makefile for Personalized Interpreters" ! 347: .sp ! 348: .PP ! 349: The ``generic'' \*MMakefile\fR for personalized interpreters follows. ! 350: The values of \*MPATH\fR and \*MDIR\fR are filled in when \*MPimake\fR is run. ! 351: .Ds ! 352: CFLAGS= ! 353: LDFLAGS= ! 354: LIB= ! 355: iroot=PATH ! 356: V5GBIN=$(iroot)/bin ! 357: DIR= ! 358: .Dd ! 359: # ! 360: # To add or replace object files, add their names to the OBJS list below. ! 361: # For example, to add foo.o and bar.o, use: ! 362: # ! 363: # OBJS=foo.o bar.o (this is a sample line) ! 364: # ! 365: # For each object file added to OBJS, add a dependency line to reflect files ! 366: # that are depended on. For example, if foo.c includes rt.h ! 367: # which is located in the h directory use ! 368: # ! 369: # foo.o: ../h/rt.h ! 370: # ! 371: .Dd ! 372: OBJS= ! 373: .Dd ! 374: PIOBJS=../std/init.o ../std/strprc.o ! 375: RTOBJS=$(PIOBJS) $(OBJS) ! 376: .Dd ! 377: Pi: ../picont ../piconx ../pilink ! 378: .Dd ! 379: ../picont: ../std/icont.c ! 380: rm -f ../picont picont ! 381: cc -o ../picont -DIntBin="\e"$(DIR)\e"" -DIconx="\e"$(DIR)/piconx\e"" \e ! 382: -DIconxEnv="\e"ICONX=$(DIR)/piconx\e"" \e ! 383: -DILINK="\e"$(DIR)/pilink\e"" \e ! 384: -DITRAN="\e"$(V5GBIN)/itran\e"" -DFORK=QFORK \e ! 385: ../std/icont.c ! 386: ln ../picont ! 387: .Dd ! 388: ../pilink: ../std/linklib ../std/builtin.o ! 389: cc $(LDFLAGS) -X -o ../pilink ../std/builtin.o ../std/linklib ! 390: .Dd ! 391: ../piconx: ../std/rtlib $(RTOBJS) ! 392: cc $(LDFLAGS) -X -o ../piconx -e start -u start $(RTOBJS) ../std/rtlib $(LIB) ! 393: ! 394: ../std/init.o: ../h/rt.h ../h/err.h ../h/config.h ../h/pdef.h ! 395: cd ../std; cc -c init.c ! 396: .Dd ! 397: ../std/builtin.o: ../std/ilink.h ../h/config.h ../h/pdef.h ! 398: cd ../std; cc -c builtin.c ! 399: .Dd ! 400: ../std/strprc.o: ../h/rt.h ../h/pnames.h ../h/config.h ../h/pdef.h ! 401: cd ../std; cc -c strprc.c ! 402: .Dd ! 403: Strip: ../picont ../piconx ../pilink ! 404: strip ../picont ../piconx ../pilink ! 405: .De ! 406: .Ap "Appendix B \(em C Functions from the Icon Program Library" ! 407: .sp ! 408: .SH ! 409: getenv.c: ! 410: .LP ! 411: .Ds ! 412: /* ! 413: # GETENV(3.icon) ! 414: # ! 415: # Get contents of environment variables ! 416: # ! 417: # Stephen B. Wampler ! 418: # ! 419: # Last modified 8/19/84 ! 420: # ! 421: */ ! 422: .Dd ! 423: #include "../h/rt.h" ! 424: .Dd ! 425: /* ! 426: * getenv(s) - return contents of environment variable s ! 427: */ ! 428: .Dd ! 429: Xgetenv(nargs, arg1, arg0) ! 430: int nargs; ! 431: struct descrip arg1, arg0; ! 432: { ! 433: register char *p; ! 434: register int len; ! 435: char sbuf\^[MAXSTRING]; ! 436: extern char *getenv(); ! 437: extern char *alcstr(); ! 438: .Dd ! 439: DeRef(arg1) ! 440: .Dd ! 441: if (!QUAL(arg1)) /* check legality of argument */ ! 442: runerr(103, &arg1); ! 443: if (STRLEN(arg1) \*(<= 0 || STRLEN(arg1) \*(>= MAXSTRING) ! 444: runerr(401, &arg1); ! 445: qtos(&arg1, sbuf); /* convert argument to C-style string */ ! 446: .Dd ! 447: if ((p = getenv(sbuf)) != NULL) { /* get environment variable */ ! 448: len = strlen(p); ! 449: sneed(len); ! 450: STRLEN(arg0) = len; ! 451: STRLOC(arg0) = alcstr(p, len); ! 452: } ! 453: else /* fail if variable not in environment */ ! 454: fail(); ! 455: } ! 456: .Dd ! 457: Procblock(getenv,\*b-1) ! 458: .De ! 459: .bp ! 460: .SH ! 461: math.c: ! 462: .LP ! 463: .Ds ! 464: /* ! 465: # MATH(3.icon) ! 466: # ! 467: # Miscellaneous math functions ! 468: # ! 469: # Ralph E. Griswold ! 470: # ! 471: # Last modified 8/19/84 ! 472: # ! 473: */ ! 474: .Dd ! 475: #include "../h/rt.h" ! 476: #include <errno.h> ! 477: .Dd ! 478: int errno; ! 479: /* ! 480: * exp(x), x in radians ! 481: */ ! 482: Xexp(nargs, arg1, arg0) ! 483: int nargs; ! 484: struct descrip arg1, arg0; ! 485: { ! 486: int t; ! 487: double y; ! 488: union numeric r; ! 489: double exp(); ! 490: ! 491: if ((t = cvreal(&arg1, &r)) == NULL) runerr(102, &arg1); ! 492: y = exp(r.real); ! 493: if (errno == ERANGE) runerr(252, NULL); ! 494: mkreal(y,\*b&arg0); ! 495: } ! 496: Procblock(exp,\*b1) ! 497: .Dd ! 498: /* ! 499: * log(x), x in radians ! 500: */ ! 501: Xlog(nargs, arg1, arg0) ! 502: int nargs; ! 503: struct descrip arg1, arg0; ! 504: { ! 505: int t; ! 506: double y; ! 507: union numeric r; ! 508: double log(); ! 509: ! 510: if ((t = cvreal(&arg1, &r)) == NULL) runerr(102, &arg1); ! 511: y = log(r.real); ! 512: if (errno == EDOM) runerr(251, NULL); ! 513: mkreal(y,\*b&arg0); ! 514: } ! 515: Procblock(log,\*b1) ! 516: .Dd ! 517: /* ! 518: * log10(x), x in radians ! 519: */ ! 520: Xlog10(nargs, arg1, arg0) ! 521: int nargs; ! 522: struct descrip arg1, arg0; ! 523: { ! 524: int t; ! 525: double y; ! 526: union numeric r; ! 527: double log10(); ! 528: ! 529: if ((t = cvreal(&arg1, &r)) == NULL) runerr(102, &arg1); ! 530: y = log10(r.real); ! 531: if (errno == EDOM) runerr(251, NULL); ! 532: mkreal(y,\*b&arg0); ! 533: } ! 534: Procblock(log10,\*b1) ! 535: .Dd ! 536: /* ! 537: * sqrt(x), x in radians ! 538: */ ! 539: Xsqrt(nargs, arg1, arg0) ! 540: int nargs; ! 541: struct descrip arg1, arg0; ! 542: { ! 543: int t; ! 544: double y; ! 545: union numeric r; ! 546: double sqrt(); ! 547: ! 548: if ((t = cvreal(&arg1, &r)) == NULL) runerr(102, &arg1); ! 549: y = sqrt(r.real); ! 550: if (errno == EDOM) runerr(251, NULL); ! 551: mkreal(y,\*b&arg0); ! 552: } ! 553: Procblock(sqrt,\*b1) ! 554: .De ! 555: .bp ! 556: .SH ! 557: seek.c: ! 558: .Ds ! 559: /* ! 560: # SEEK(3.icon) ! 561: # ! 562: # Seek to position in stream ! 563: # ! 564: # Stephen B. Wampler ! 565: # ! 566: # Last modified 8/19/84 ! 567: # ! 568: */ ! 569: .Dd ! 570: #include "../h/rt.h" ! 571: .Dd ! 572: /* ! 573: * seek(file,\*boffset,\*bstart) - seek to offset byte from start in file. ! 574: */ ! 575: .Dd ! 576: Xseek(nargs, arg3, arg2, arg1, arg0) ! 577: int nargs; ! 578: struct descrip arg3, arg2, arg1, arg0; ! 579: { ! 580: long l1, l2; ! 581: int status; ! 582: FILE *fd; ! 583: long ftell(); ! 584: .Dd ! 585: DeRef(arg1) ! 586: if (arg1.type != D_FILE) ! 587: runerr(106); ! 588: .Dd ! 589: defint(&arg2, &l1, 0); ! 590: defshort(&arg3, 0); ! 591: .Dd ! 592: fd = BLKLOC(arg1)->file.fd; ! 593: .Dd ! 594: if ((BLKLOC(arg1)->file.status == 0) || ! 595: (fseek(fd, l1, arg3.value.integr) == -1)) ! 596: fail(); ! 597: mkint(ftell(fd), &arg0); ! 598: } ! 599: .Dd ! 600: Procblock(seek,\*b3) ! 601: .De ! 602: .LP
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.