home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / extra18 / toolbox / execdemo.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-01-21  |  5.1 KB  |  135 lines

  1. (* ------------------------------------------------- *)
  2. (*                EXECDEMO.PAS                       *)
  3. (*    (c) 1991, 1992 Gerd Cebulla & DMV-Verlag       *)
  4. (*    Turbo-Pascal ab Version 4.0 oder Quick-Pascal  *)
  5. (* ------------------------------------------------- *)
  6. PROGRAM ExecDemo;
  7.  
  8. USES Dos;
  9.  
  10.   PROCEDURE Execute(Name : PathStr; Params : ComStr);
  11.  
  12.   { Die folgende Prozedur bringt die Fragmentliste    }
  13.   { der Turbo-Pascal-Heapverwaltung in Sicherheit,    }
  14.   { gibt den unbenutzten Teil des Heap frei und ruft  }
  15.   { anschließend das Programm "Name" mit den Kommando-}
  16.   { zeilenparametern "Params" auf.                    }
  17.   { "Name" kann optional einen Laufwerksbezeichner    }
  18.   { und/oder einen Suchpfad enthalten. Nach erfolgtem }
  19.   { Programmaufruf wird die Speicherbelegung auf die  }
  20.   { Originalwerte zurückgesetzt. Der Fehlerstatus läßt}
  21.   { sich wie üblich der Systemvariablen DosError ent- }
  22.   { nehmen, die folgende Werte enthalten kann:        }
  23.   {   0 = alles o.k.                                  }
  24.   {   2 = Datei nicht gefunden                        }
  25.   {   3 = Verzeichnis nicht gefunden                  }
  26.   {   8 = nicht genug Hauptspeicher                   }
  27.   VAR
  28.     Regs      : Registers;
  29.     FragLen,
  30.     FragParas,
  31.     ParasAlt,
  32.     ParasNeu  : WORD;
  33.   BEGIN
  34.     IF Ofs(FreePtr^) = 0 THEN
  35.       FragLen := 0    { keine Fragmentliste vorhanden }
  36.     ELSE BEGIN
  37.       FragLen := $10000 - Ofs(FreePtr^);
  38.           { Länge der Fragmentliste in Byte berechnen }
  39.       Move(FreePtr^, HeapPtr^, FragLen);
  40.       { Fragmentliste an Anfang
  41.         des freien Heap kopieren   }
  42.     END;
  43.     FragParas := Succ(FragLen DIV 16);
  44.              { Länge der Fragmentliste in Paragraphen }
  45.     ParasAlt := Seg(FreePtr^) + $1000 - PrefixSeg;
  46.              { derzeit vom Programm belegter Speicher }
  47.     ParasNeu := Succ(Seg(HeapPtr^) + FragParas - PrefixSeg);
  48.                     { tatsächlich benötigter Speicher }
  49.     Regs.AH := $4A;      { Speichergröße ändern       }
  50.     Regs.BX := ParasNeu;    { BX = Speichergröße      }
  51.     Regs.ES := PrefixSeg;   { ES ->  Programmanfang   }
  52.     MsDos (Regs);
  53.                 { nicht benötigten Speicher freigeben }
  54.  
  55.     {$IFNDEF VER40
  56.               (SwapVectors erst ab Turbo 5.0 definiert}
  57.     SwapVectors;        { DOS-Vektoren reinstallieren }
  58.     {$ENDIF}
  59.     Exec(Name, Params);       { Kindprogramm aufrufen }
  60.     {$IFNDEF VER40 }
  61.     SwapVectors;              { Turbo-Vektoren zurück }
  62.     {$ENDIF}
  63.  
  64.     Regs.AH := $4A;           { Speichergröße ändern  }
  65.     Regs.BX := ParasAlt;
  66.     Regs.ES := PrefixSeg;
  67.     MsDos(Regs);
  68.                  { freigegebenen Speicher zurückholen }
  69.     IF Regs.Flags AND FCarry <> 0 THEN BEGIN
  70.                    { Carry gesetzt => Speicher konnte }
  71.                    {           nicht zugeteilt werden }
  72.       WriteLn('Fraktaler FEHLER: Das aufgerufene ' +
  73.               'Programm hat die Speicherorganisation'+
  74.               ' verändert!');
  75.       Halt (1);                     { Programmabbruch }
  76.     END;
  77.     IF FragLen > 0 THEN
  78.       Move(HeapPtr^, FreePtr^, FragLen);
  79.                        { Fragmentliste zurückkopieren }
  80.   END;
  81.  
  82.  
  83. (* ------------------------------------------------- *)
  84. (* Das folgende Programm demonstriert die Verwendung *)
  85. (* der Prozedur "Execute" anhand des Aufrufs einer   *)
  86. (* DOS-Shell und veranschaulicht, daß trotzdem noch  *)
  87. (* der volle Heap verfügbar ist.                     *)
  88. (* Achtung: Da dieses Programm die Speicher-         *)
  89. (* organisation manipuliert, sollte es *NICHT* von   *)
  90. (* der integrierten Entwicklungsumgebung aus         *)
  91. (* gestartet werden!                                 *)
  92.  
  93. TYPE
  94.   BigArray    = ARRAY [1..60000] OF BYTE;
  95.   BigArrayPtr = ^BigArray;
  96. VAR
  97.   Big   : ARRAY [1..10] OF BigArrayPtr;
  98.   Index : BYTE;
  99. BEGIN
  100.   WriteLn('MemAvail = ', MemAvail, ' Byte');
  101.   Index := 0;
  102.   WHILE MaxAvail > SizeOf (BigArray) DO BEGIN
  103.     Inc(Index);
  104.     New(Big[Index]);
  105.     WriteLn(Index, '. dynamische Variable erzeugt; ',
  106.                    'MemAvail = ', MemAvail);
  107.   END;
  108.   FOR Index := Index DOWNTO 1 DO BEGIN
  109.     Dispose(Big[Index]);
  110.     WriteLn(Index,
  111.             '. dynamische Variable freigegeben; ',
  112.             'MemAvail = ', MemAvail);
  113.   END;
  114.   WriteLn;
  115.   WriteLn('Wie man sieht, lassen sich beliebige ',
  116.           'Operationen auf dem Heap durchführen.');
  117.   Write  ('Trotzdem ist es noch möglich, ein anderes ',
  118.           'Programm aufzurufen. Zur Demonstration');
  119.   Write  ('wird jetzt der DOS-Kommandointerpreter ',
  120.           'geladen. Geben Sie beliebige Befehle ein,');
  121.   WriteLn('und verlassen Sie ihn mit EXIT ...');
  122.  
  123.   {$IFNDEF VER40 -
  124.     GetEnv erst ab Turbo 5.0 implementiert }
  125.   Execute(GetEnv('COMSPEC'), '');
  126.   {$ELSE (V4.0: annehmen, daß sich COMMAND.COM im    }
  127.   {             Suchpfad befindet).                  }
  128.   Execute('COMMAND.COM', '');
  129.   {$ENDIF}
  130.   WriteLn('Zurück in ExecDemo ...');
  131.   WriteLn('DosError = ', DosError);
  132. END.
  133. (* ------------------------------------------------- *)
  134. (*              Ende von EXECDEMO.PAS                *)
  135.