🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.modula2
Article #1872

Re: POINTER/LINKED LIST HELP?

#1872
From: Gerhard Moeller
Date: Tue, 02 Apr 1991 19:23
277 lines
9592 bytes
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.
Technical Details
Message-ID: <5175@uniol.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!math.fu-berlin.de!uniol!Gerhard.Moeller
References: <1991Mar30.151406.29367@kuhub.cc.ukans.edu> <5164@uniol.UUCP> <1991Apr1.123810.29390@kuhub.cc.ukans.edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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