consoleio.pp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. Unit consoleio;
  12. interface
  13. type
  14. TWriteCharFunc = function(ACh: char; AUserData: pointer): boolean;
  15. TReadCharFunc = function(var ACh: char; AUserData: pointer): boolean;
  16. procedure OpenIO(var f: Text; AWrite: TWriteCharFunc; ARead: TReadCharFunc; AMode: word; AUserData: pointer);
  17. implementation
  18. {$i textrec.inc}
  19. type
  20. PUserData = ^TUserData;
  21. TUserData = record
  22. WriteChar: TWriteCharFunc;
  23. ReadChar: TReadCharFunc;
  24. UserData: Pointer;
  25. end;
  26. function EmptyWrite(ACh: char; AUserData: pointer): boolean;
  27. begin
  28. EmptyWrite:=true;
  29. end;
  30. function EmptyRead(var ACh: char; AUserData: pointer): boolean;
  31. begin
  32. EmptyRead:=true;
  33. ACh:=#0;
  34. end;
  35. procedure Console_Close(var t:TextRec);
  36. begin
  37. end;
  38. function ReadData(Func: TReadCharFunc; UserData: pointer; Buffer: pchar; count: SizeInt): SizeInt;
  39. var
  40. c: char;
  41. got_linechar: boolean;
  42. begin
  43. ReadData:=0;
  44. got_linechar:=false;
  45. while (ReadData < count) and (not got_linechar) do
  46. begin
  47. if Func(c, UserData) then
  48. begin
  49. if c = #10 then
  50. got_linechar:=true;
  51. buffer^:=c;
  52. inc(buffer);
  53. inc(ReadData);
  54. end;
  55. end;
  56. end;
  57. Procedure Console_Read(var t:TextRec);
  58. var
  59. userdata: PUserData;
  60. begin
  61. userdata:[email protected][1];
  62. InOutRes:=0;
  63. t.bufend:=ReadData(userdata^.ReadChar,userdata^.UserData,pchar(t.bufptr),t.bufsize);
  64. t.bufpos:=0;
  65. end;
  66. Procedure Console_Write(var t:TextRec);
  67. var
  68. userdata: PUserData;
  69. p: pchar;
  70. i: SizeInt;
  71. begin
  72. if t.BufPos=0 then exit;
  73. userdata:[email protected][1];
  74. i := 0;
  75. p := pchar(t.bufptr);
  76. while i < t.bufpos do
  77. begin
  78. if not userdata^.WriteChar(p^, userdata^.UserData) then
  79. break;
  80. inc(p);
  81. inc(i);
  82. end;
  83. if i<>t.BufPos then
  84. InOutRes:=101
  85. else
  86. InOutRes:=0;
  87. t.BufPos:=0;
  88. end;
  89. procedure OpenIO(var f: Text; AWrite: TWriteCharFunc; ARead: TReadCharFunc; AMode: word; AUserData: pointer);
  90. var
  91. userdata: PUserData;
  92. begin
  93. { Essentially just init everything, more or less what Assign(f,'');
  94. does }
  95. FillChar(f,SizeOf(TextRec),0);
  96. { only set things that are not zero }
  97. TextRec(f).Handle:=UnusedHandle;
  98. TextRec(f).BufSize:=TextRecBufSize;
  99. TextRec(f).Bufptr:=@TextRec(f).Buffer;
  100. TextRec(f).OpenFunc:=nil;
  101. TextRec(f).LineEnd := #13#10;
  102. userdata:=@TextRec(f).UserData[1];
  103. TextRec(f).Mode:=AMode;
  104. case AMode of
  105. fmInput: TextRec(f).Handle:=StdInputHandle;
  106. fmOutput: TextRec(f).Handle:=StdOutputHandle;
  107. end;
  108. TextRec(f).CloseFunc:=@Console_Close;
  109. TextRec(f).FlushFunc:=nil;
  110. case AMode of
  111. fmInput: TextRec(f).InOutFunc:=@Console_Read;
  112. fmOutput:
  113. begin
  114. TextRec(f).InOutFunc:=@Console_Write;
  115. TextRec(f).FlushFunc:=@Console_Write;
  116. end;
  117. end;
  118. userdata^.WriteChar := AWrite;
  119. userdata^.ReadChar := ARead;
  120. userdata^.UserData := AUserData;
  121. end;
  122. procedure SysInitStdIO;
  123. begin
  124. OpenIO(Input, @EmptyWrite, @EmptyRead, fmInput, nil);
  125. OpenIO(Output, @EmptyWrite, @EmptyRead, fmOutput, nil);
  126. OpenIO(ErrOutput, @EmptyWrite, @EmptyRead, fmOutput, nil);
  127. OpenIO(StdOut, @EmptyWrite, @EmptyRead, fmOutput, nil);
  128. OpenIO(StdErr, @EmptyWrite, @EmptyRead, fmOutput, nil);
  129. end;
  130. procedure SysFlushStdIO;
  131. begin
  132. end;
  133. var
  134. ErrorBase : Pointer;external name 'FPC_ERRORBASE';
  135. var
  136. pstdout : ^Text;
  137. {$ifndef CPUAVR}
  138. initialization
  139. { Setup stdin, stdout and stderr }
  140. SysInitStdIO;
  141. finalization
  142. { Show runtime error and exit }
  143. pstdout:=@stdout;
  144. If erroraddr<>nil Then
  145. Begin
  146. Writeln(pstdout^,'Runtime error ',Errorcode,' at $',hexstr(erroraddr));
  147. { to get a nice symify }
  148. Writeln(pstdout^,BackTraceStrFunc(Erroraddr));
  149. dump_stack(pstdout^,ErrorBase);
  150. Writeln(pstdout^,'');
  151. End;
  152. SysFlushStdIO;
  153. {$endif CPUAVR}
  154. end.