consoleio.pp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2011 by the Free Pascal development team.
  4. Console i/o for the FPC embedded target
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$mode objfpc}
  12. Unit consoleio;
  13. interface
  14. type
  15. TWriteCharFunc = function(ACh: char; AUserData: pointer): boolean;
  16. TReadCharFunc = function(var ACh: char; AUserData: pointer): boolean;
  17. procedure OpenIO(var f: Text; AWrite: TWriteCharFunc; ARead: TReadCharFunc; AMode:longint; AUserData: pointer);
  18. implementation
  19. {$i textrec.inc}
  20. type
  21. PUserData = ^TUserData;
  22. TUserData = record
  23. WriteChar: TWriteCharFunc;
  24. ReadChar: TReadCharFunc;
  25. UserData: Pointer;
  26. end;
  27. function EmptyWrite(ACh: char; AUserData: pointer): boolean;
  28. begin
  29. result:=true;
  30. end;
  31. function EmptyRead(var ACh: char; AUserData: pointer): boolean;
  32. begin
  33. result:=true;
  34. ACh:=#0;
  35. end;
  36. procedure Console_Close(var t:TextRec);
  37. begin
  38. end;
  39. function ReadData(Func: TReadCharFunc; UserData: pointer; Buffer: pchar; count: longint): longint;
  40. var
  41. c: char;
  42. got_linechar: boolean;
  43. begin
  44. result:=0;
  45. got_linechar:=false;
  46. while (result < count) and (not got_linechar) do
  47. begin
  48. if Func(c, UserData) then
  49. begin
  50. if c = #10 then
  51. got_linechar:=true;
  52. buffer^:=c;
  53. inc(buffer);
  54. inc(result);
  55. end;
  56. end;
  57. end;
  58. Procedure Console_Read(var t:TextRec);
  59. var
  60. userdata: PUserData;
  61. begin
  62. userdata:[email protected][1];
  63. InOutRes:=0;
  64. t.bufend:=ReadData(userdata^.ReadChar,userdata^.UserData,pchar(t.bufptr),t.bufsize);
  65. t.bufpos:=0;
  66. end;
  67. Procedure Console_Write(var t:TextRec);
  68. var
  69. userdata: PUserData;
  70. p: pchar;
  71. i: longint;
  72. begin
  73. if t.BufPos=0 then exit;
  74. userdata:[email protected][1];
  75. i := 0;
  76. p := pchar(t.bufptr);
  77. while i < t.bufpos do
  78. begin
  79. if not userdata^.WriteChar(p^, userdata^.UserData) then
  80. break;
  81. inc(p);
  82. inc(i);
  83. end;
  84. if i<>t.BufPos then
  85. InOutRes:=101
  86. else
  87. InOutRes:=0;
  88. t.BufPos:=0;
  89. end;
  90. procedure OpenIO(var f: Text; AWrite: TWriteCharFunc; ARead: TReadCharFunc; AMode:longint; AUserData: pointer);
  91. var
  92. userdata: PUserData;
  93. begin
  94. Assign(f,'');
  95. userdata:=@TextRec(f).UserData[1];
  96. TextRec(f).Mode:=AMode;
  97. case AMode of
  98. fmInput: TextRec(f).Handle:=StdInputHandle;
  99. fmOutput: TextRec(f).Handle:=StdOutputHandle;
  100. end;
  101. TextRec(f).CloseFunc:=@Console_Close;
  102. TextRec(f).FlushFunc:=nil;
  103. case AMode of
  104. fmInput: TextRec(f).InOutFunc:=@Console_Read;
  105. fmOutput:
  106. begin
  107. TextRec(f).InOutFunc:=@Console_Write;
  108. TextRec(f).FlushFunc:=@Console_Write;
  109. end;
  110. end;
  111. userdata^.WriteChar := AWrite;
  112. userdata^.ReadChar := ARead;
  113. userdata^.UserData := AUserData;
  114. end;
  115. procedure SysInitStdIO;
  116. begin
  117. OpenIO(Input, @EmptyWrite, @EmptyRead, fmInput, nil);
  118. OpenIO(Output, @EmptyWrite, @EmptyRead, fmOutput, nil);
  119. OpenIO(ErrOutput, @EmptyWrite, @EmptyRead, fmOutput, nil);
  120. OpenIO(StdOut, @EmptyWrite, @EmptyRead, fmOutput, nil);
  121. OpenIO(StdErr, @EmptyWrite, @EmptyRead, fmOutput, nil);
  122. end;
  123. procedure SysFlushStdIO;
  124. begin
  125. end;
  126. var
  127. ErrorBase : Pointer;external name 'FPC_ERRORBASE';
  128. var
  129. pstdout : ^Text;
  130. initialization
  131. { Setup stdin, stdout and stderr }
  132. SysInitStdIO;
  133. finalization
  134. { Show runtime error and exit }
  135. pstdout:=@stdout;
  136. If erroraddr<>nil Then
  137. Begin
  138. Writeln(pstdout^,'Runtime error ',Errorcode,' at $',hexstr(erroraddr));
  139. { to get a nice symify }
  140. Writeln(pstdout^,BackTraceStrFunc(Erroraddr));
  141. dump_stack(pstdout^,ErrorBase);
  142. Writeln(pstdout^,'');
  143. End;
  144. SysFlushStdIO;
  145. end.