Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!math.fu-berlin.de!uniol!Gerhard.Moeller From: Gerhard.Moeller@arbi.informatik.uni-oldenburg.de (Gerhard Moeller) Newsgroups: comp.lang.modula2 Subject: Re: POINTER/LINKED LIST HELP? Message-ID: <5175@uniol.UUCP> Date: 2 Apr 91 19:23:17 GMT References: <1991Mar30.151406.29367@kuhub.cc.ukans.edu> <5164@uniol.UUCP> <1991Apr1.123810.29390@kuhub.cc.ukans.edu> Organization: University of Oldenburg, Germany Lines: 277 Hi again... >In article <5164@uniol.UUCP>, Gerhard.Moeller@arbi.informatik.uni-oldenburg.de (Gerhard Moeller) writes: >> Hi. >> 2hnenature@kuhub.cc.ukans.edu writes: >> >> >>> I seem to have a problem with using the type POINTER with linked lists. >>>I have a seperate module with linked list functions such as Delete,Insert, >>>NewList etc., that I have written myself. The problem is that I wish to make >>>these procedures as general as possible so they can be used with a variety of >>>programs. Is it possible to specify a general POINTER type that can point to >>>any data type? I assume it must be possible since the function NEW(x) allows x >>>to be a pointer to any type of data. >> Yes, as far as I know, use ADDRESS. (Must be imported from SYSTEM) Then >> you can do something like this: >> >> PROCEDURE InsertElement (Root :ADDRESS; >> Element :ADDRESS) : BOOLEAN; >> >> Now it doesn't care of what Element the Pointer points. But however yet >> be warned: The internal Structure of the Elements should be at least >> similar, I don't want to know what happens if you try to insert a >> FIFO-List-Element into a Bayer-Tree... > OK, that makes sense, but when I try to implement it and try to access a field >of the record that for example "Root" is pointing to I get an error: > Current:=Root^.Link > ^ Is not a field of a record (something like that) > >and that makes sense too since the compiler sees "Root" as an ADDRESS type and >not as a pointer to a record. Thus the fields are not recognized, (I guess). >Also DISPOSE and NEW do not let me send an ADDRESS type as a parameter. > Furthermore (as if you guys have nothing better to do than help me) another >error I get is: > > Current:=Root^.Link > ^ Incompatible type (?) > I get this error because the field "Link" is a pointer to a record and not an >ADDRESS type. > Is there any way around this or should I give up? Does anybody know where >I could get some source code for linked list functions that are already >written? > Thanks for help recieved. Well, before I start explaning, I'd better send a copy of source that I've written many days ago. It sure works and should be self-explaining. (Sometimes a sample helps more than 1000 words.) BTW the following source implements a few useful system-calls of the UNIX c-library and therefore only works with Unix... have a close look at the time-routines for example. (* for UNIX only *) FOREIGN MODULE MySysLib; FROM SYSTEM IMPORT ADDRESS; TYPE int = INTEGER; SIGNED = INTEGER; UNSIGNED = INTEGER; inoT = CARDINAL; offT = INTEGER; devT = SHORTINT; timeT = INTEGER; Stat = RECORD stDev : devT; stIno : inoT; stMode : SHORTCARD; stNlink : SHORTINT; stUid : SHORTINT; stGid : SHORTINT; stRdev : devT; stSize : offT; stAtime : timeT; stSpare1 : INTEGER; stMtime : timeT; stSpare2 : INTEGER; stCtime : timeT; stSpare3 : INTEGER; stBlksize: INTEGER; stBlocks : INTEGER; stSpare4 : ARRAY [0..1] OF INTEGER; END; tms = RECORD utime : timeT; stime : timeT; cutime : timeT; cstime : timeT; END; tmtype = RECORD tm_sec : int; tm_min : int; tm_hour : int; tm_mday : int; tm_mon : int; tm_year : int; tm_wday : int; tm_yday : int; tm_istdst : int; END; CONST (* signals *) SIGHUP = 01; (* hangup *) SIGINT = 02; (* interrupt *) SIGQUIT = 03; (* [1] quit *) SIGILL = 04; (* [1] illegal instruction (not reset when caught) *) SIGTRAP = 05; (* [1] trace trap (not reset when caught) *) SIGIOT = 06; (* [1] IOT instruction *) SIGEMT = 07; (* [1] EMT instruction *) SIGFPE = 08; (* [1] floating point exception *) SIGKILL = 09; (* kill (cannot be caught or ignored) *) SIGBUS = 10; (* [1] bus error *) SIGSEGV = 11; (* [1] segmentation violation *) SIGSYS = 12; (* [1] bad argument to system call *) SIGPIPE = 13; (* write on a pipe with no one to read it *) SIGALRM = 14; (* alarm clock *) SIGTERM = 15; (* software termination signal *) SIGADDR = 16; (* [1] address error: odd address *) SIGZERO = 17; (* [1] zero divide *) SIGCHK = 18; (* [1] check error (68000 chk instruction) *) SIGOVER = 19; (* [1] software termination signal *) SIGPRIV = 20; (* [1] software termination signal *) SIGUSR1 = 21; (* user-defined signal 1 *) SIGUSR2 = 22; (* user-defined signal 2 *) SIGCLD = 23; (* [2] death of a child *) SIGPWR = 24; (* [2] power fail *) SIGWINCH = 25; (* [2] window size changed *) SIGPOLL = 26; (* [3] selectable event pending *) (* flags for open *) oTRUNC = 01000B; (* open with truncation *) oAPPEND = 010B; (* append, i.e writes at the end *) oRDWR = 02B; (* open for reading and writing *) oWRONLY = 01B; (* open for writing only *) oRDONLY = 0B; (* open for reading only *) (* file access permisson flags (for create and umask) *) pXUSID = 04000B; (* set user ID on execution *) pXGRID = 02000B; (* set group ID on execution *) pSTEXT = 01000B; (* save text image after execution *) pROWNER = 0400B; (* read by owner *) pWOWNER = 0200B; (* write by owner *) pXOWNER = 0100B; (* execute by owner *) pRGROUP = 040B; (* read by group *) pWGROUP = 020B; (* write by group *) pXGROUP = 010B; (* execute by group *) pROTHERS = 04B; (* read by others *) pWOTHERS = 02B; (* write by others *) pXOTHERS = 01B; (* execute by others *) pEMPTY = 0B; (* no flag set *) (* file access check flags (for access) *) cREAD = 04H; (* check if readable *) cWRITE = 02H; (* check if writable *) cEXEC = 01H; (* check if executable *) cEXISTS = 0H; (* check existance *) PROCEDURE umask (cmask : SIGNED) : SIGNED; PROCEDURE access (path : ADDRESS; amode : SIGNED) : SIGNED; PROCEDURE creat (path : ADDRESS; cmode : SIGNED) : SIGNED; PROCEDURE open (path : ADDRESS; oflag : SIGNED) : SIGNED; PROCEDURE close (fildes : SIGNED) : SIGNED; PROCEDURE unlink (path : ADDRESS) : SIGNED; PROCEDURE read (fildes : SIGNED; buf : ADDRESS; nbyte : UNSIGNED) : SIGNED; PROCEDURE write (fildes : SIGNED; buf : ADDRESS; nbyte : UNSIGNED) : SIGNED; PROCEDURE malloc (size : UNSIGNED) : ADDRESS; PROCEDURE free (ptr : ADDRESS); PROCEDURE stat (path: ADDRESS; VAR buf: Stat) : INTEGER; PROCEDURE fstat (fd: SIGNED ; VAR buf: Stat) : INTEGER; PROCEDURE time (VAR t : INTEGER); PROCEDURE times (VAR buffer: tms); PROCEDURE localtime (clockpointer : ADDRESS) : ADDRESS; PROCEDURE system (string : ADDRESS) : SIGNED; PROCEDURE exit (n: INTEGER); PROCEDURE alarm (sec : UNSIGNED); PROCEDURE signal (sig :int; func :PROC); PROCEDURE sigset (sig :int; func :PROC); PROCEDURE sighold (sig :int); PROCEDURE sigrelse (sig :int); PROCEDURE sigignore (sig :int); PROCEDURE sigpause (sig :int); END MySysLib. (*============================================================================*) IMPLEMENTATION MODULE MySysLib; (* implemented by C library *) END MySysLib. (*============================================================================*) [...] (* Stuff deleted *) MODULE Editor; (* @@ EXPORT Edit (Filename); *) FROM MyStuff IMPORT (* TYPE *) StringType; FROM MySysLib IMPORT (* TYPE *) SIGNED, (* PROC *) system; [...] (* Stuff deleted *) CONST Editor = "em "; Filename = "Test"; PROCEDURE Edit (File :ARRAY OF CHAR); VAR EditFile : StringType; unixcommand : StringType; unixcall : POINTER TO StringType; error : SIGNED; BEGIN (* Edit *) Concat (Editor, File, EditFile); ALLOCATE (unixcall, SIZE (unixcommand)); unixcall^ := EditFile; error := system (unixcall); DEALLOCATE (unixcall, SIZE(unixcommand)); END Edit; BEGIN (* Editor *) [...] (* Stuff deleted *) END Editor. [...] (* Stuff deleted *) (*============================================================================*) Ok?? Hope that helped, Gerhard.