system.pp 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2002-2004 by Olle Raab
  5. FreePascal system unit for MacOS.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit System;
  13. interface
  14. { include system-independent routine headers }
  15. {$I systemh.inc}
  16. {Platform specific information}
  17. type
  18. {$ifdef CPU64}
  19. THandle = Int64;
  20. {$else CPU64}
  21. THandle = Longint;
  22. {$endif CPU64}
  23. const
  24. LineEnding = #13;
  25. LFNSupport = true;
  26. DirectorySeparator = ':';
  27. DriveSeparator = ':';
  28. PathSeparator = ','; {Is used in MPW and OzTeX}
  29. FileNameCaseSensitive = false;
  30. { include heap support headers }
  31. {$I heaph.inc}
  32. const
  33. { Default filehandles }
  34. UnusedHandle : Longint = -1;
  35. StdInputHandle : Longint = 0;
  36. StdOutputHandle : Longint = 1;
  37. StdErrorHandle : Longint = 2;
  38. sLineBreak = LineEnding;
  39. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCR;
  40. var
  41. argc : longint;
  42. argv : ppchar;
  43. envp : ppchar;
  44. {*********************************}
  45. {** MacOS specific functions **}
  46. {*********************************}
  47. {To be called at regular intervals, for lenghty tasks.
  48. Yield might give time for other tasks to run under the cooperative
  49. multitasked macos. For an MPW Tool, it also spinns the cursor.}
  50. procedure Yield;
  51. {*********************************}
  52. {** Available features on macos **}
  53. {*********************************}
  54. var
  55. macosHasGestalt: Boolean;
  56. macosHasWaitNextEvent: Boolean;
  57. macosHasColorQD: Boolean;
  58. macosHasFPU: Boolean;
  59. macosSystemVersion: Integer;
  60. macosHasSysDebugger: Boolean = false;
  61. macosHasCFM: Boolean;
  62. macosHasAppleEvents: Boolean;
  63. macosHasAliasMgr: Boolean;
  64. macosHasFSSpec: Boolean;
  65. macosHasFindFolder: Boolean;
  66. macosHasScriptMgr: Boolean;
  67. macosNrOfScriptsInstalled: Integer;
  68. macosHasAppearance: Boolean;
  69. macosHasAppearance101: Boolean;
  70. macosHasAppearance11: Boolean;
  71. macosBootVolumeVRefNum: Integer;
  72. macosBootVolumeName: String[31];
  73. {
  74. MacOS paths
  75. ===========
  76. MacOS directory separator is a colon ":" which is the only character not
  77. allowed in filenames.
  78. A path containing no colon or which begins with a colon is a partial path.
  79. E g ":kalle:petter" ":kalle" "kalle"
  80. All other paths are full (absolute) paths. E g "HD:kalle:" "HD:"
  81. When generating paths, one is safe is one ensures that all partial paths
  82. begins with a colon, and all full paths ends with a colon.
  83. In full paths the first name (e g HD above) is the name of a mounted volume.
  84. These names are not unique, because, for instance, two diskettes with the
  85. same names could be inserted. This means that paths on MacOS is not
  86. waterproof. In case of equal names the first volume found will do.
  87. Two colons "::" are the relative path to the parent. Three is to the
  88. grandparent etc.
  89. }
  90. implementation
  91. {
  92. About the implementation
  93. ========================
  94. A MacOS application is assembled and linked by MPW (Macintosh
  95. Programmers Workshop), which nowadays is free to use. For info
  96. and download of MPW and MacOS api, see www.apple.com
  97. It can be linked to either a graphical user interface application,
  98. a standalone text only application (using SIOW) or
  99. to an MPW tool, this is entirely controlled by the linking step.
  100. It requires system 7 and CFM, which is always the case for PowerPC.
  101. If a m68k version would be implemented, it would save a lot
  102. of efforts if it also uses CFM. This System.pp should, with
  103. minor modifications, probably work with m68k.
  104. Initial working directory is the directory of the application,
  105. or for an MPWTool, the working directory as set by the
  106. Directory command in MPW.
  107. Note about working directory. There is a facility in MacOS which
  108. manages a working directory for an application, initially set to
  109. the applications directory, or for an MPWTool, the tool's directory.
  110. However, this requires the application to have a unique application
  111. signature (creator code), to distinguish its working directory
  112. from working directories of other applications. Due to the fact
  113. that casual applications are anonymous in this sense (without an
  114. application signature), this facility will not work. Also, this
  115. working directory facility is not present in Carbon. Hence we
  116. will manage a working directory by our self.
  117. Deviations
  118. ==========
  119. In current implementation, working directory is stored as
  120. directory id. This means there is a possibility the user moves the
  121. working directory or a parent to it, while the application uses it.
  122. Then the path to the wd suddenly changes. This is AFAIK not in
  123. accordance with other OS's. Although this is a minor caveat,
  124. it is mentioned here. To overcome this the wd could be stored
  125. as a path instead, but this imposes translations from fullpath
  126. to directory ID each time the filesystem is accessed.
  127. The initial working directory for an MPWTool, as considered by
  128. FPC, is different from the MacOS working directory facility,
  129. see above.
  130. Possible improvements:
  131. =====================
  132. Perhaps handle readonly filesystems, as in sysunix.inc
  133. }
  134. {This implementation uses StdCLib, which is included in the MPW.}
  135. {$define MACOS_USE_STDCLIB}
  136. {******** include system independent routines **********}
  137. {$I system.inc}
  138. {*********************** MacOS API *********************}
  139. {Below is some MacOS API routines included for internal use.
  140. Note, because the System unit is the most low level, it should not
  141. depend on any other units, and thus the macos api must be accessed
  142. as an include file and not a unit.}
  143. {$I macostp.inc}
  144. {If the Apples Universal Interfaces are used, the qd variable is required
  145. to be allocated somewhere, so we do it here for the convenience to the user.}
  146. var
  147. qd: QDGlobals; cvar;
  148. {$ifdef MACOS_USE_STDCLIB}
  149. {************** API to StdCLib in MacOS ***************}
  150. {The reason StdCLib is used is that it can easily be connected
  151. to either SIOW or, in case of MPWTOOL, to MPW }
  152. {The prefix C_ or c_ is used where names conflicts with pascal
  153. keywords and names. Suffix Ptr is added for pointer to a type.}
  154. type
  155. size_t = Longint;
  156. off_t = Longint;
  157. C_int = Longint;
  158. C_short = Integer;
  159. C_long = Longint;
  160. C_unsigned_int = Cardinal;
  161. var
  162. errno: C_int; external name 'errno';
  163. MacOSErr: C_short; external name 'MacOSErr';
  164. const
  165. _IOFBF = $00;
  166. _IOLBF = $40;
  167. _IONBF = $04;
  168. O_RDONLY = $00; // Open for reading only.
  169. O_WRONLY = $01; // Open for writing only.
  170. O_RDWR = $02; // Open for reading & writing.
  171. O_APPEND = $08; // Write to the end of the file.
  172. O_RSRC = $10; // Open the resource fork.
  173. O_ALIAS = $20; // Open alias file.
  174. O_CREAT = $100; // Open or create a file.
  175. O_TRUNC = $200; // Open and truncate to zero length.
  176. O_EXCL = $400; // Create file only; fail if exists.
  177. O_BINARY = $800; // Open as a binary stream.
  178. O_NRESOLVE = $4000; // Don't resolve any aliases.
  179. SEEK_SET = 0;
  180. SEEK_CUR = 1;
  181. SEEK_END = 2;
  182. FIOINTERACTIVE = $00006602; // If device is interactive
  183. FIOBUFSIZE = $00006603; // Return optimal buffer size
  184. FIOFNAME = $00006604; // Return filename
  185. FIOREFNUM = $00006605; // Return fs refnum
  186. FIOSETEOF = $00006606; // Set file length
  187. TIOFLUSH = $00007408; // discard unread input. arg is ignored
  188. function c_open(path: PChar; oflag: C_int): C_int; cdecl;
  189. external 'StdCLib' name 'open';
  190. function c_close(filedes: C_int): C_int; cdecl;
  191. external 'StdCLib' name 'close';
  192. function c_write(filedes: C_int; buf: pointer; nbyte: size_t): size_t; cdecl;
  193. external 'StdCLib' name 'write';
  194. function c_read(filedes: C_int; buf: pointer; nbyte: size_t): size_t; cdecl;
  195. external 'StdCLib' name 'read';
  196. function lseek(filedes: C_int; offset: off_t; whence: C_int): off_t; cdecl;
  197. external 'StdCLib' name 'lseek';
  198. function ioctl(filedes: C_int; cmd: C_unsigned_int; arg: pointer): C_int; cdecl;
  199. external 'StdCLib' name 'ioctl';
  200. function remove(filename: PChar): C_int; cdecl;
  201. external 'StdCLib';
  202. function c_rename(old, c_new: PChar): C_int; cdecl;
  203. external 'StdCLib' name 'rename';
  204. procedure c_exit(status: C_int); cdecl;
  205. external 'StdCLib' name 'exit';
  206. {cdecl is actually only needed for m68k}
  207. var
  208. {Is set to nonzero for MPWTool, zero otherwise.}
  209. StandAlone: C_int; external name 'StandAlone';
  210. CONST
  211. Sys_EPERM = 1; { No permission match }
  212. Sys_ENOENT = 2; { No such file or directory }
  213. Sys_ENORSRC = 3; { Resource not found *}
  214. Sys_EINTR = 4; { System service interrupted *}
  215. Sys_EIO = 5; { I/O error }
  216. Sys_ENXIO = 6; { No such device or address }
  217. Sys_E2BIG = 7; { Insufficient space for return argument * }
  218. Sys_ENOEXEC = 8; { File not executable * }
  219. Sys_EBADF = 9; { Bad file number }
  220. Sys_ECHILD = 10; { No child processes }
  221. Sys_EAGAIN = 11; { Resource temporarily unavailable * }
  222. Sys_ENOMEM = 12; { Not enough space * }
  223. Sys_EACCES = 13; { Permission denied }
  224. Sys_EFAULT = 14; { Illegal filename * }
  225. Sys_ENOTBLK = 15; { Block device required }
  226. Sys_EBUSY = 16; { Device or resource busy }
  227. Sys_EEXIST = 17; { File exists }
  228. Sys_EXDEV = 18; { Cross-device link }
  229. Sys_ENODEV = 19; { No such device }
  230. Sys_ENOTDIR = 20; { Not a directory }
  231. Sys_EISDIR = 21; { Is a directory }
  232. Sys_EINVAL = 22; { Invalid parameter * }
  233. Sys_ENFILE = 23; { File table overflow }
  234. Sys_EMFILE = 24; { Too many open files }
  235. Sys_ENOTTY = 25; { Not a typewriter }
  236. Sys_ETXTBSY = 26; { Text file busy. The new process was
  237. a pure procedure (shared text) file which was
  238. open for writing by another process, or file
  239. which was open for writing by another process,
  240. or while the pure procedure file was being
  241. executed an open(2) call requested write access
  242. requested write access.
  243. (Probably not applicable on macos)}
  244. Sys_EFBIG = 27; { File too large }
  245. Sys_ENOSPC = 28; { No space left on device }
  246. Sys_ESPIPE = 29; { Illegal seek }
  247. Sys_EROFS = 30; { Read-only file system }
  248. Sys_EMLINK = 31; { Too many links }
  249. Sys_EPIPE = 32; { Broken pipe }
  250. Sys_EDOM = 33; { Math argument out of domain of func }
  251. Sys_ERANGE = 34; { Math result not representable }
  252. { Note * is slightly different, compared to rtl/sunos/errno.inc}
  253. {$endif}
  254. {*********************** Macutils *********************}
  255. {And also include the same utilities as in the macutils.pp unit.}
  256. var
  257. {emulated working directory}
  258. workingDirectorySpec: FSSpec; cvar;
  259. {Also declared in macutils.pp as external. Declared here to be available
  260. to macutils.inc and below in this file.}
  261. {$I macutils.inc}
  262. {******************************************************}
  263. function GetAppFileLocation (var spec: FSSpec): Boolean;
  264. {Requires >= System 7}
  265. var
  266. PSN: ProcessSerialNumber;
  267. info: ProcessInfoRec;
  268. appFileRefNum: Integer;
  269. appName: Str255;
  270. dummy: Mac_Handle;
  271. begin
  272. begin
  273. PSN.highLongOfPSN := 0;
  274. PSN.lowLongOfPSN := kCurrentProcess;
  275. info.processInfoLength := SizeOf(info);
  276. info.processName := nil;
  277. info.processAppSpec := @spec;
  278. if GetProcessInformation(PSN, info) = noErr then
  279. begin
  280. spec.name := '';
  281. GetAppFileLocation := true;
  282. end
  283. else
  284. GetAppFileLocation := false;
  285. end
  286. end;
  287. Procedure Errno2InOutRes;
  288. {
  289. Convert ErrNo error to the correct InOutRes value.
  290. It seems that some of the errno is, in macos,
  291. used for other purposes than its original definition.
  292. }
  293. begin
  294. if errno = 0 then { Else it will go through all the cases }
  295. exit;
  296. case Errno of
  297. Sys_ENFILE,
  298. Sys_EMFILE : Inoutres:=4;
  299. Sys_ENOENT : Inoutres:=2;
  300. Sys_EBADF : Inoutres:=6;
  301. Sys_ENOMEM,
  302. Sys_EFAULT : Inoutres:=217; //TODO Exchange to something better
  303. Sys_EINVAL : Inoutres:=218; //TODO RTE 218 doesn't exist
  304. Sys_EAGAIN,
  305. Sys_ENOSPC : Inoutres:=101;
  306. Sys_ENOTDIR : Inoutres:=3;
  307. Sys_EPERM,
  308. Sys_EROFS,
  309. Sys_EEXIST,
  310. Sys_EISDIR,
  311. Sys_EINTR, //Happens when attempt to rename a file fails
  312. Sys_EBUSY, //Happens when attempt to remove a locked file
  313. Sys_EACCES,
  314. Sys_EMLINK : Inoutres:=5; //Happens when attempt to remove open file
  315. Sys_ENXIO : InOutRes:=152;
  316. Sys_ESPIPE : InOutRes:=156; //Illegal seek
  317. else
  318. InOutRes := Integer(errno);//TODO Exchange to something better
  319. end;
  320. errno:=0;
  321. end;
  322. Procedure OSErr2InOutRes(err: OSErr);
  323. begin
  324. InOutRes:= MacOSErr2RTEerr(err);
  325. end;
  326. function FSpLocationFromFullPath(fullPathLength: Integer;
  327. fullPath: Mac_Ptr; var spec: FSSpec ):OSErr;
  328. var
  329. alias: AliasHandle;
  330. res: OSErr;
  331. wasChanged: Boolean;
  332. nullString: Str32;
  333. begin
  334. nullString:= '';
  335. res:= NewAliasMinimalFromFullPath(fullPathLength,
  336. fullPath, nullString, nullString, alias);
  337. if res = noErr then
  338. begin
  339. res:= ResolveAlias(nil, alias, spec, wasChanged);
  340. DisposeHandle(Mac_Handle(alias));
  341. end;
  342. FSpLocationFromFullPath:= res;
  343. end;
  344. {*****************************************************************************
  345. MacOS specific functions
  346. *****************************************************************************}
  347. procedure Yield;
  348. begin
  349. if StandAlone = 0 then
  350. SpinCursor(1);
  351. end;
  352. {*****************************************************************************
  353. ParamStr/Randomize
  354. *****************************************************************************}
  355. { number of args }
  356. function paramcount : longint;
  357. begin
  358. paramcount := argc - 1;
  359. //paramcount:=0;
  360. end;
  361. { argument number l }
  362. function paramstr(l : longint) : string;
  363. begin
  364. if (l>=0) and (l+1<=argc) then
  365. paramstr:=strpas(argv[l])
  366. else
  367. paramstr:='';
  368. end;
  369. { set randseed to a new pseudo random value }
  370. procedure randomize;
  371. begin
  372. randseed:= Cardinal(TickCount);
  373. end;
  374. {*****************************************************************************
  375. Heap Management
  376. *****************************************************************************}
  377. var
  378. { Pointer to a block allocated with the MacOS Memory Manager, which
  379. is used as the initial FPC heap. }
  380. theHeap: Mac_Ptr;
  381. intern_heapsize : longint;external name 'HEAPSIZE';
  382. { first address of heap }
  383. function getheapstart:pointer;
  384. begin
  385. getheapstart:= theHeap;
  386. end;
  387. { current length of heap }
  388. function getheapsize:longint;
  389. begin
  390. getheapsize:= intern_heapsize ;
  391. end;
  392. {*****************************************************************************
  393. OS Memory allocation / deallocation
  394. ****************************************************************************}
  395. { function to allocate size bytes more for the program }
  396. { must return the first address of new data space or nil if failed }
  397. function SysOSAlloc(size: ptrint): pointer;
  398. begin
  399. result := NewPtr(size);
  400. end;
  401. {$define HAS_SYSOSFREE}
  402. procedure SysOSFree(p: pointer; size: ptrint);
  403. begin
  404. DisposePtr(p);
  405. end;
  406. { include standard heap management }
  407. {$I heap.inc}
  408. {*****************************************************************************
  409. Low Level File Routines
  410. ****************************************************************************}
  411. function do_isdevice(handle:longint):boolean;
  412. begin
  413. do_isdevice:=false;
  414. end;
  415. { close a file from the handle value }
  416. procedure do_close(h : longint);
  417. var
  418. err: OSErr;
  419. {No error handling, according to the other targets, which seems reasonable,
  420. because close might be used to clean up after an error.}
  421. begin
  422. {$ifdef MACOS_USE_STDCLIB}
  423. c_close(h);
  424. // Errno2InOutRes;
  425. {$else}
  426. err:= FSClose(h);
  427. // OSErr2InOutRes(err);
  428. {$endif}
  429. end;
  430. procedure do_erase(p : pchar);
  431. var
  432. spec: FSSpec;
  433. err: OSErr;
  434. res: Integer;
  435. begin
  436. res:= PathArgToFSSpec(p, spec);
  437. if (res = 0) then
  438. begin
  439. if not IsDirectory(spec) then
  440. begin
  441. err:= FSpDelete(spec);
  442. OSErr2InOutRes(err);
  443. end
  444. else
  445. InOutRes:= 2;
  446. end
  447. else
  448. InOutRes:=res;
  449. end;
  450. procedure do_rename(p1,p2 : pchar);
  451. var
  452. s1,s2: AnsiString;
  453. begin
  454. {$ifdef MACOS_USE_STDCLIB}
  455. InOutRes:= PathArgToFullPath(p1, s1);
  456. if InOutRes <> 0 then
  457. exit;
  458. InOutRes:= PathArgToFullPath(p2, s2);
  459. if InOutRes <> 0 then
  460. exit;
  461. c_rename(PChar(s1),PChar(s2));
  462. Errno2InoutRes;
  463. {$else}
  464. InOutRes:=1;
  465. {$endif}
  466. end;
  467. function do_write(h:longint;addr:pointer;len : longint) : longint;
  468. begin
  469. {$ifdef MACOS_USE_STDCLIB}
  470. do_write:= c_write(h, addr, len);
  471. Errno2InoutRes;
  472. {$else}
  473. InOutRes:=1;
  474. if FSWrite(h, len, Mac_Ptr(addr)) = noErr then
  475. InOutRes:=0;
  476. do_write:= len;
  477. {$endif}
  478. end;
  479. function do_read(h:longint;addr:pointer;len : longint) : longint;
  480. var
  481. i: Longint;
  482. begin
  483. {$ifdef MACOS_USE_STDCLIB}
  484. len:= c_read(h, addr, len);
  485. Errno2InoutRes;
  486. do_read:= len;
  487. {$else}
  488. InOutRes:=1;
  489. if FSread(h, len, Mac_Ptr(addr)) = noErr then
  490. InOutRes:=0;
  491. do_read:= len;
  492. {$endif}
  493. end;
  494. function do_filepos(handle : longint) : longint;
  495. var
  496. pos: Longint;
  497. begin
  498. {$ifdef MACOS_USE_STDCLIB}
  499. {This returns the filepos without moving it.}
  500. do_filepos := lseek(handle, 0, SEEK_CUR);
  501. Errno2InoutRes;
  502. {$else}
  503. InOutRes:=1;
  504. if GetFPos(handle, pos) = noErr then
  505. InOutRes:=0;
  506. do_filepos:= pos;
  507. {$endif}
  508. end;
  509. procedure do_seek(handle,pos : longint);
  510. begin
  511. {$ifdef MACOS_USE_STDCLIB}
  512. lseek(handle, pos, SEEK_SET);
  513. Errno2InoutRes;
  514. {$else}
  515. InOutRes:=1;
  516. if SetFPos(handle, fsFromStart, pos) = noErr then
  517. InOutRes:=0;
  518. {$endif}
  519. end;
  520. function do_seekend(handle:longint):longint;
  521. begin
  522. {$ifdef MACOS_USE_STDCLIB}
  523. do_seekend:= lseek(handle, 0, SEEK_END);
  524. Errno2InoutRes;
  525. {$else}
  526. InOutRes:=1;
  527. if SetFPos(handle, fsFromLEOF, 0) = noErr then
  528. InOutRes:=0;
  529. {TODO Resulting file position is to be returned.}
  530. {$endif}
  531. end;
  532. function do_filesize(handle : longint) : longint;
  533. var
  534. aktfilepos: Longint;
  535. begin
  536. {$ifdef MACOS_USE_STDCLIB}
  537. aktfilepos:= lseek(handle, 0, SEEK_CUR);
  538. if errno = 0 then
  539. begin
  540. do_filesize := lseek(handle, 0, SEEK_END);
  541. Errno2InOutRes; {Report the error from this operation.}
  542. lseek(handle, aktfilepos, SEEK_SET); {Always try to move back,
  543. even in presence of error.}
  544. end
  545. else
  546. Errno2InOutRes;
  547. {$else}
  548. InOutRes:=1;
  549. if GetEOF(handle, pos) = noErr then
  550. InOutRes:=0;
  551. do_filesize:= pos;
  552. {$endif}
  553. end;
  554. { truncate at a given position }
  555. procedure do_truncate (handle,pos:longint);
  556. begin
  557. {$ifdef MACOS_USE_STDCLIB}
  558. ioctl(handle, FIOSETEOF, pointer(pos));
  559. Errno2InoutRes;
  560. {$else}
  561. InOutRes:=1;
  562. do_seek(handle,pos); //TODO: Is this needed (Does the user anticipate the filemarker is at the end?)
  563. if SetEOF(handle, pos) = noErr then
  564. InOutRes:=0;
  565. {$endif}
  566. end;
  567. procedure do_open(var f;p:pchar;flags:longint);
  568. {
  569. filerec and textrec have both handle and mode as the first items so
  570. they could use the same routine for opening/creating.
  571. when (flags and $100) the file will be append
  572. when (flags and $1000) the file will be truncate/rewritten
  573. when (flags and $10000) there is no check for close (needed for textfiles)
  574. }
  575. var
  576. creator, fileType: OSType;
  577. scriptTag: ScriptCode;
  578. refNum: Integer;
  579. res: OSErr;
  580. fh: Longint;
  581. oflags : longint;
  582. s: AnsiString;
  583. begin
  584. // AllowSlash(p);
  585. { close first if opened }
  586. if ((flags and $10000)=0) then
  587. begin
  588. case filerec(f).mode of
  589. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  590. fmclosed : ;
  591. else
  592. begin
  593. {not assigned}
  594. inoutres:=102;
  595. exit;
  596. end;
  597. end;
  598. end;
  599. { reset file handle }
  600. filerec(f).handle:=UnusedHandle;
  601. {$ifdef MACOS_USE_STDCLIB}
  602. { We do the conversion of filemodes here, concentrated on 1 place }
  603. case (flags and 3) of
  604. 0 : begin
  605. oflags :=O_RDONLY;
  606. filerec(f).mode:=fminput;
  607. end;
  608. 1 : begin
  609. oflags :=O_WRONLY;
  610. filerec(f).mode:=fmoutput;
  611. end;
  612. 2 : begin
  613. oflags :=O_RDWR;
  614. filerec(f).mode:=fminout;
  615. end;
  616. end;
  617. if (flags and $1000)=$1000 then
  618. oflags:=oflags or (O_CREAT or O_TRUNC)
  619. else if (flags and $100)=$100 then
  620. oflags:=oflags or (O_APPEND);
  621. { empty name is special }
  622. if p[0]=#0 then
  623. begin
  624. case FileRec(f).mode of
  625. fminput :
  626. FileRec(f).Handle:=StdInputHandle;
  627. fminout, { this is set by rewrite }
  628. fmoutput :
  629. FileRec(f).Handle:=StdOutputHandle;
  630. fmappend :
  631. begin
  632. FileRec(f).Handle:=StdOutputHandle;
  633. FileRec(f).mode:=fmoutput; {fool fmappend}
  634. end;
  635. end;
  636. exit;
  637. end
  638. else
  639. begin
  640. InOutRes:= PathArgToFullPath(p, s);
  641. if InOutRes <> 0 then
  642. exit;
  643. p:= PChar(s);
  644. end;
  645. fh:= c_open(p, oflags);
  646. if (fh = -1) and (errno = Sys_EROFS) and ((oflags and O_RDWR)<>0) then
  647. begin
  648. oflags:=oflags and not(O_RDWR);
  649. fh:= c_open(p, oflags);
  650. end;
  651. Errno2InOutRes;
  652. if fh <> -1 then
  653. filerec(f).handle:= fh
  654. else
  655. filerec(f).handle:= UnusedHandle;
  656. {$else}
  657. InOutRes:=1;
  658. //creator:= $522A6368; {'MPS ' -- MPW}
  659. //creator:= $74747874; {'ttxt'}
  660. creator:= $522A6368; {'R*ch' -- BBEdit}
  661. fileType:= $54455854; {'TEXT'}
  662. { reset file handle }
  663. filerec(f).handle:=UnusedHandle;
  664. res:= FSpLocationFromFullPath(StrLen(p), p, spec);
  665. if (res = noErr) or (res = fnfErr) then
  666. begin
  667. if FSpCreate(spec, creator, fileType, smSystemScript) = noErr then
  668. ;
  669. if FSpOpenDF(spec, fsCurPerm, refNum) = noErr then
  670. begin
  671. filerec(f).handle:= refNum;
  672. InOutRes:=0;
  673. end;
  674. end;
  675. if (filerec(f).handle=UnusedHandle) then
  676. begin
  677. //errno:=GetLastError;
  678. //Errno2InoutRes;
  679. end;
  680. {$endif}
  681. end;
  682. {*****************************************************************************
  683. UnTyped File Handling
  684. *****************************************************************************}
  685. {$i file.inc}
  686. {*****************************************************************************
  687. Typed File Handling
  688. *****************************************************************************}
  689. {$i typefile.inc}
  690. {*****************************************************************************
  691. Text File Handling
  692. *****************************************************************************}
  693. { #26 is not end of a file in MacOS ! }
  694. {$i text.inc}
  695. {*****************************************************************************
  696. Directory Handling
  697. *****************************************************************************}
  698. procedure mkdir(const s:string);[IOCheck];
  699. var
  700. spec: FSSpec;
  701. createdDirID: Longint;
  702. err: OSErr;
  703. res: Integer;
  704. begin
  705. If (s='') or (InOutRes <> 0) then
  706. exit;
  707. res:= PathArgToFSSpec(s, spec);
  708. if (res = 0) or (res = 2) then
  709. begin
  710. err:= FSpDirCreate(spec, smSystemScript, createdDirID);
  711. OSErr2InOutRes(err);
  712. end
  713. else
  714. InOutRes:=res;
  715. end;
  716. procedure rmdir(const s:string);[IOCheck];
  717. var
  718. spec: FSSpec;
  719. err: OSErr;
  720. res: Integer;
  721. begin
  722. If (s='') or (InOutRes <> 0) then
  723. exit;
  724. res:= PathArgToFSSpec(s, spec);
  725. if (res = 0) then
  726. begin
  727. if IsDirectory(spec) then
  728. begin
  729. err:= FSpDelete(spec);
  730. OSErr2InOutRes(err);
  731. end
  732. else
  733. InOutRes:= 20;
  734. end
  735. else
  736. InOutRes:=res;
  737. end;
  738. procedure chdir(const s:string);[IOCheck];
  739. var
  740. spec, newDirSpec: FSSpec;
  741. err: OSErr;
  742. res: Integer;
  743. begin
  744. if (s='') or (InOutRes <> 0) then
  745. exit;
  746. res:= PathArgToFSSpec(s, spec);
  747. if (res = 0) or (res = 2) then
  748. begin
  749. { The fictive file x is appended to the directory name to make
  750. FSMakeFSSpec return a FSSpec to a file in the directory.
  751. Then by clearing the name, the FSSpec then
  752. points to the directory. It doesn't matter whether x exists or not.}
  753. err:= FSMakeFSSpec (spec.vRefNum, spec.parID, ':'+spec.name+':x', newDirSpec);
  754. if (err = noErr) or (err = fnfErr) then
  755. begin
  756. workingDirectorySpec:= newDirSpec;
  757. workingDirectorySpec.name:='';
  758. InOutRes:= 0;
  759. end
  760. else
  761. begin
  762. {E g if the directory doesn't exist.}
  763. OSErr2InOutRes(err);
  764. end;
  765. end
  766. else
  767. InOutRes:=res;
  768. end;
  769. procedure getDir (DriveNr: byte; var Dir: ShortString);
  770. var
  771. pathHandle: Mac_Handle;
  772. pathHandleSize: Longint;
  773. begin
  774. if FSpGetFullPath(workingDirectorySpec, pathHandle, false) <> noErr then
  775. Halt(3); {exit code 3 according to MPW}
  776. pathHandleSize:= GetHandleSize(pathHandle);
  777. SetString(dir, pathHandle^, pathHandleSize);
  778. DisposeHandle(pathHandle);
  779. if pathHandleSize <= 255 then {because dir is ShortString}
  780. InOutRes := 0
  781. else
  782. InOutRes := 1; //TODO Exchange to something better
  783. end;
  784. {*****************************************************************************
  785. SystemUnit Initialization
  786. *****************************************************************************}
  787. procedure pascalmain; external name 'PASCALMAIN';
  788. {Main entry point in C style, needed to capture program parameters.
  789. For this to work, the system unit must be before the main program
  790. in the linking order.}
  791. procedure main(argcparam: Longint; argvparam: ppchar; envpparam: ppchar); cdecl; [public];
  792. begin
  793. argc:= argcparam;
  794. argv:= argvparam;
  795. envp:= envpparam;
  796. pascalmain; {run the pascal main program}
  797. end;
  798. procedure setup_arguments;
  799. begin
  800. {Nothing needs to be done here.}
  801. end;
  802. procedure setup_environment;
  803. begin
  804. end;
  805. { FindSysFolder returns the (real) vRefNum, and the DirID of the current
  806. system folder. It uses the Folder Manager if present, otherwise it falls
  807. back to SysEnvirons. It returns zero on success, otherwise a standard
  808. system error. }
  809. function FindSysFolder(var foundVRefNum: Integer; var foundDirID: Longint): OSErr;
  810. var
  811. gesResponse: Longint;
  812. envRec: SysEnvRec;
  813. myWDPB: WDPBRec;
  814. volName: String[34];
  815. err: OSErr;
  816. begin
  817. foundVRefNum := 0;
  818. foundDirID := 0;
  819. if macosHasGestalt
  820. and (Gestalt (FourCharCodeToLongword(gestaltFindFolderAttr), gesResponse) = noErr)
  821. and BitIsSet (gesResponse, gestaltFindFolderPresent) then
  822. begin { Does Folder Manager exist? }
  823. err := FindFolder (kOnSystemDisk, FourCharCodeToLongword(kSystemFolderType),
  824. kDontCreateFolder, foundVRefNum, foundDirID);
  825. end
  826. else
  827. begin
  828. { Gestalt can't give us the answer, so we resort to SysEnvirons }
  829. err := SysEnvirons (curSysEnvVers, envRec);
  830. if (err = noErr) then
  831. begin
  832. myWDPB.ioVRefNum := envRec.sysVRefNum;
  833. volName := '';
  834. myWDPB.ioNamePtr := @volName;
  835. myWDPB.ioWDIndex := 0;
  836. myWDPB.ioWDProcID := 0;
  837. err := PBGetWDInfoSync (@myWDPB);
  838. if (err = noErr) then
  839. begin
  840. foundVRefNum := myWDPB.ioWDVRefNum;
  841. foundDirID := myWDPB.ioWDDirID;
  842. end;
  843. end;
  844. end;
  845. FindSysFolder:= err;
  846. end;
  847. procedure InvestigateSystem;
  848. {$IFDEF CPUM68K}
  849. const
  850. _GestaltDispatch = $A0AD;
  851. _WaitNextEvent = $A860;
  852. _ScriptUtil = $A8B5;
  853. qdOffscreenTrap = $AB1D;
  854. {$ENDIF}
  855. var
  856. err: Integer;
  857. response: Longint;
  858. {$IFDEF CPUM68K}
  859. environs: SysEnvRec;
  860. {$ENDIF}
  861. {Vi rŠknar med att man kšr pŒ minst system 6.0.5. DŒ finns bŒde Gestalt och GDevice med.}
  862. {Enligt Change Histrory Šr MacOS 6.0.5 mera konsistent mellan maskinmodellerna Šn fšregŒende system}
  863. begin
  864. {$IFDEF CPUM68K}
  865. macosHasGestalt := TrapAvailable(_GestaltDispatch);
  866. {$ELSE}
  867. macosHasGestalt := true; {There is always Gestalt on PowerPC}
  868. {$ENDIF}
  869. if not macosHasGestalt then (* If we don't have Gestalt, then we can't have any System 7 features *)
  870. begin
  871. {$IFDEF CPUM68K}
  872. { Detta kan endast gŠlla pŒ en 68K maskin.}
  873. macosHasScriptMgr := TrapAvailable(_ScriptUtil);
  874. macosNrOfScriptsInstalled := 1; (* assume only Roman script, to start with *)
  875. err := SysEnvirons(1, environs);
  876. if err = noErr then
  877. begin
  878. if environs.machineType < 0 then { gammalt ROM}
  879. macosHasWaitNextEvent := FALSE
  880. else
  881. macosHasWaitNextEvent := TrapAvailable(_WaitNextEvent);
  882. macosHasColorQD := environs.hasColorQD;
  883. macosHasFPU := environs.hasFPU;
  884. macosSystemVersion := environs.systemVersion;
  885. end
  886. else
  887. begin
  888. macosHasWaitNextEvent := FALSE;
  889. macosHasColorQD := FALSE;
  890. macosHasFPU := FALSE;
  891. macosSystemVersion := 0;
  892. end;
  893. macosHasSysDebugger := (LongintPtr(MacJmp)^ <> 0);
  894. macosHasCFM := false;
  895. macosHasAppleEvents := false;
  896. macosHasAliasMgr := false;
  897. macosHasFSSpec := false;
  898. macosHasFindFolder := false;
  899. macosHasAppearance := false;
  900. macosHasAppearance101 := false;
  901. macosHasAppearance11 := false;
  902. {$IFDEF THINK_PASCAL}
  903. if (macosHasScriptMgr) then
  904. macosNrOfScriptsInstalled := GetEnvirons(smEnabled);
  905. {$ELSE}
  906. if (macosHasScriptMgr) then
  907. macosNrOfScriptsInstalled := GetScriptManagerVariable(smEnabled); {Gamla rutinnamnet var GetEnvirons.}
  908. {$ENDIF}
  909. {$ENDIF}
  910. end
  911. else
  912. begin
  913. macosHasScriptMgr := Gestalt(FourCharCodeToLongword(gestaltScriptMgrVersion), response) = noErr; {Fšr att ta reda pŒ om script mgr finns.}
  914. macosNrOfScriptsInstalled := 1; (* assume only Roman script, to start with *)
  915. macosHasWaitNextEvent := true;
  916. if Gestalt(FourCharCodeToLongword(gestaltSystemVersion), response) = noErr then
  917. macosSystemVersion := response
  918. else
  919. macosSystemVersion := 0; {Borde inte kunna hŠnda.}
  920. if Gestalt(FourCharCodeToLongword(gestaltOSAttr), response) = noErr then
  921. macosHasSysDebugger := BitIsSet(response, gestaltSysDebuggerSupport)
  922. else
  923. macosHasSysDebugger := false;
  924. if Gestalt(FourCharCodeToLongword(gestaltQuickdrawVersion), response) = noErr then
  925. macosHasColorQD := (response >= $0100)
  926. else
  927. macosHasColorQD := false;
  928. if Gestalt(FourCharCodeToLongword(gestaltFPUType), response) = noErr then
  929. macosHasFPU := (response <> gestaltNoFPU)
  930. else
  931. macosHasFPU := false;
  932. if Gestalt(FourCharCodeToLongword(gestaltCFMAttr), response) = noErr then
  933. macosHasCFM := BitIsSet(response, gestaltCFMPresent)
  934. else
  935. macosHasCFM := false;
  936. macosHasAppleEvents := Gestalt(FourCharCodeToLongword(gestaltAppleEventsAttr), response) = noErr;
  937. macosHasAliasMgr := Gestalt(FourCharCodeToLongword(gestaltAliasMgrAttr), response) = noErr;
  938. if Gestalt(FourCharCodeToLongword(gestaltFSAttr), response) = noErr then
  939. macosHasFSSpec := BitIsSet(response, gestaltHasFSSpecCalls)
  940. else
  941. macosHasFSSpec := false;
  942. macosHasFindFolder := Gestalt(FourCharCodeToLongword(gestaltFindFolderAttr), response) = noErr;
  943. if macosHasScriptMgr then
  944. begin
  945. err := Gestalt(FourCharCodeToLongword(gestaltScriptCount), response);
  946. if (err = noErr) then
  947. macosNrOfScriptsInstalled := Integer(response);
  948. end;
  949. if (Gestalt(FourCharCodeToLongword(gestaltAppearanceAttr), response) = noErr) then
  950. begin
  951. macosHasAppearance := BitIsSet(response, gestaltAppearanceExists);
  952. if Gestalt(FourCharCodeToLongword(gestaltAppearanceVersion), response) = noErr then
  953. begin
  954. macosHasAppearance101 := (response >= $101);
  955. macosHasAppearance11 := (response >= $110);
  956. end
  957. end
  958. else
  959. begin
  960. macosHasAppearance := false;
  961. macosHasAppearance101 := false;
  962. macosHasAppearance11 := false;
  963. end;
  964. end;
  965. end;
  966. {*****************************************************************************
  967. System Dependent Exit code
  968. *****************************************************************************}
  969. Procedure system_exit;
  970. var
  971. s: ShortString;
  972. begin
  973. if StandAlone <> 0 then
  974. if exitcode <> 0 then
  975. begin
  976. Str(exitcode,s);
  977. if IsConsole then
  978. Writeln( '### Program exited with exit code ' + s)
  979. else if macosHasSysDebugger then
  980. DebugStr('A possible error occured, exit code: ' + s + '. Type "g" and return to continue.')
  981. else
  982. {Be quiet}
  983. end;
  984. {$ifndef MACOS_USE_STDCLIB}
  985. if StandAlone <> 0 then
  986. ExitToShell;
  987. {$else}
  988. c_exit(exitcode); {exitcode is only utilized by an MPW tool}
  989. {$endif}
  990. end;
  991. procedure SysInitStdIO;
  992. begin
  993. { Setup stdin, stdout and stderr }
  994. {$ifdef MACOS_USE_STDCLIB}
  995. OpenStdIO(Input,fmInput,StdInputHandle);
  996. OpenStdIO(Output,fmOutput,StdOutputHandle);
  997. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  998. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  999. {$endif }
  1000. end;
  1001. var
  1002. resHdl: Mac_Handle;
  1003. isFolder, hadAlias, leafIsAlias: Boolean;
  1004. dirStr: string[2];
  1005. err: OSErr;
  1006. dummySysFolderDirID: Longint;
  1007. begin
  1008. InvestigateSystem; {Must be first}
  1009. {Check requred features for system.pp to work.}
  1010. if not macosHasFSSpec then
  1011. Halt(3); //exit code 3 according to MPW
  1012. if FindSysFolder(macosBootVolumeVRefNum, dummySysFolderDirID) <> noErr then
  1013. Halt(3); //exit code 3 according to MPW
  1014. if GetVolumeName(macosBootVolumeVRefNum, macosBootVolumeName) <> noErr then
  1015. Halt(3); //exit code 3 according to MPW
  1016. { To be set if this is a GUI or console application }
  1017. if StandAlone = 0 then
  1018. IsConsole := true {Its an MPW tool}
  1019. else
  1020. begin
  1021. resHdl:= Get1Resource(FourCharCodeToLongword('siow'),0);
  1022. IsConsole := (resHdl <> nil); {A SIOW app is also a console}
  1023. ReleaseResource(resHdl);
  1024. end;
  1025. { To be set if this is a library and not a program }
  1026. IsLibrary := FALSE;
  1027. StackLength := InitialStkLen;
  1028. StackBottom := SPtr - StackLength;
  1029. { Setup working directory }
  1030. if StandAlone <> 0 then
  1031. begin
  1032. if not GetAppFileLocation(workingDirectorySpec) then
  1033. Halt(3); //exit code 3 according to MPW
  1034. end
  1035. else
  1036. begin
  1037. { The fictive file x is used to make
  1038. FSMakeFSSpec return a FSSpec to a file in the directory.
  1039. Then by clearing the name, the FSSpec then
  1040. points to the directory. It doesn't matter whether x exists or not.}
  1041. dirStr:= ':x';
  1042. err:= ResolveFolderAliases(0, 0, @dirStr, true,
  1043. workingDirectorySpec, isFolder, hadAlias, leafIsAlias);
  1044. if (err <> noErr) and (err <> fnfErr) then
  1045. Halt(3); //exit code 3 according to MPW
  1046. end;
  1047. { Setup heap }
  1048. if StandAlone <> 0 then
  1049. MaxApplZone;
  1050. if Mac_FreeMem - intern_heapsize < 30000 then
  1051. Halt(3); //exit code 3 according to MPW
  1052. theHeap:= SysOSAlloc(intern_heapsize);
  1053. if theHeap = nil then
  1054. Halt(3); //exit code 3 according to MPW
  1055. InitHeap;
  1056. SysInitStdIO;
  1057. { Setup environment and arguments }
  1058. Setup_Environment;
  1059. setup_arguments;
  1060. { Reset IO Error }
  1061. InOutRes:=0;
  1062. errno:=0;
  1063. (* This should be changed to a real value during *)
  1064. (* thread driver initialization if appropriate. *)
  1065. ThreadID := 1;
  1066. {$ifdef HASVARIANT}
  1067. initvariantmanager;
  1068. {$endif HASVARIANT}
  1069. if StandAlone = 0 then
  1070. InitCursorCtl(nil);
  1071. end.
  1072. {
  1073. $Log$
  1074. Revision 1.19 2004-08-20 10:18:15 olle
  1075. + added Yield routine
  1076. Revision 1.18 2004/07/14 23:34:07 olle
  1077. + added qd, the "QuickDraw globals"
  1078. Revision 1.17 2004/06/21 19:23:34 olle
  1079. + Variables describing misc OS features added
  1080. + Detection of GUI app
  1081. * Working directory for APPTYPE TOOL correct now
  1082. + Exit code <> 0 written to, console for console apps, to system debugger (if installed) for GUI apps.
  1083. * Misc fixes
  1084. Revision 1.16 2004/06/17 16:16:13 peter
  1085. * New heapmanager that releases memory back to the OS, donated
  1086. by Micha Nelissen
  1087. Revision 1.15 2004/05/11 18:05:41 olle
  1088. + added call to MaxApplZone to have the whole MacOS heap available
  1089. Revision 1.14 2004/04/29 11:27:36 olle
  1090. * do_read/do_write addr arg changed to pointer
  1091. * misc internal changes
  1092. Revision 1.13 2004/02/04 15:17:16 olle
  1093. * internal changes
  1094. Revision 1.12 2004/01/20 23:11:20 hajny
  1095. * ExecuteProcess fixes, ProcessID and ThreadID added
  1096. Revision 1.11 2004/01/04 21:06:43 jonas
  1097. * make the C-main public
  1098. Revision 1.10 2003/10/29 22:34:52 olle
  1099. + handles program parameters for MPW
  1100. + program start stub
  1101. * improved working directory handling
  1102. * minor changes
  1103. + some documentation
  1104. Revision 1.9 2003/10/17 23:44:30 olle
  1105. + working direcory emulated
  1106. + implemented directory handling procs
  1107. + all proc which take a path param, now resolve it relative wd
  1108. Revision 1.8 2003/10/16 15:43:13 peter
  1109. * THandle is platform dependent
  1110. Revision 1.7 2003/09/27 11:52:35 peter
  1111. * sbrk returns pointer
  1112. Revision 1.6 2003/09/12 12:45:15 olle
  1113. + filehandling complete
  1114. + heaphandling complete
  1115. + support for random
  1116. * filehandling now uses filedecriptors in StdCLib
  1117. * other minor changes
  1118. - removed DEFINE MAC_SYS_RUNNABLE
  1119. Revision 1.5 2003/01/13 17:18:55 olle
  1120. + added support for rudimentary file handling
  1121. Revision 1.4 2002/11/28 10:58:02 olle
  1122. + added support for rudimentary heap
  1123. Revision 1.3 2002/10/23 15:29:09 olle
  1124. + added switch MAC_SYS_RUNABLE
  1125. + added include of system.h etc
  1126. + added standard globals
  1127. + added dummy hook procedures
  1128. Revision 1.2 2002/10/10 19:44:05 florian
  1129. * changes from Olle to compile/link a simple program
  1130. Revision 1.1 2002/10/02 21:34:31 florian
  1131. * first dummy implementation
  1132. }