grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / tools / debug / bifteck / Bifteck.c
blob671179b9e1e417d4220cd16eda2d7a651036454b
1 /*
2 Copyright © 2009-2012, The AROS Development Team. All rights reserved.
3 $Id$
5 Bifteck -- Retrieves memory-stored debug output.
6 */
8 #include <exec/memory.h>
9 #include <dos/dos.h>
11 #include <proto/exec.h>
12 #include <proto/dos.h>
14 struct Args
16 TEXT *to;
19 struct LogBlock
21 struct MinNode node;
22 ULONG length; /* number of data bytes that follow */
25 struct LogData
27 struct SignalSemaphore lock;
28 struct MinList buffers;
29 struct LogBlock *block;
30 ULONG block_pos;
31 APTR pool;
34 static TEXT GetLogChar(struct LogData *data, struct LogBlock **block,
35 ULONG *pos);
37 const TEXT template[] = "TO/K";
38 const TEXT version_string[] = "$VER: Bifteck 41.2 (30.8.2012)";
39 #if (0)
40 static const TEXT data_name[] = "bifteck";
41 #endif
43 LONG main(VOID)
45 struct RDArgs *read_args;
46 LONG error = 0, result = RETURN_OK;
47 BPTR output;
48 struct Args args = {NULL};
49 struct LogData *data;
50 struct LogBlock *block;
51 ULONG pos = 0;
52 TEXT ch, old_ch = '\n';
54 /* Parse arguments */
56 read_args = ReadArgs(template, (SIPTR *)&args, NULL);
58 /* Get buffer */
60 Forbid();
61 data = (struct LogData *)FindSemaphore("bifteck");
62 Permit();
64 if (read_args != NULL && data != NULL)
66 ObtainSemaphore(&data->lock);
67 block = (struct LogBlock *)data->buffers.mlh_Head;
69 /* Get destination */
71 if (args.to != NULL)
72 output = Open(args.to, MODE_NEWFILE);
73 else
74 output = Output();
76 /* Type debug log */
78 if (output != (BPTR)NULL)
80 while ((ch = GetLogChar(data, &block, &pos)) != '\0' && error == 0)
82 FPutC(output,ch);
83 if (SetSignal(0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
84 error = ERROR_BREAK;
85 old_ch = ch;
87 error = IoErr();
89 if (old_ch != '\n')
90 FPutC(output, '\n');
92 else
94 result = RETURN_FAIL;
95 error = IoErr();
98 /* Close the destination file */
100 if (args.to != NULL && output != BNULL)
101 Close(output);
103 ReleaseSemaphore(&data->lock);
105 else
107 result = RETURN_FAIL;
108 if (read_args != NULL && data == NULL)
110 PutStr("Debug data not found. "
111 "Add \"debug=memory\" to boot options.\n");
112 error = ERROR_OBJECT_NOT_FOUND;
114 else
115 error = IoErr();
118 FreeArgs(read_args);
120 /* Print any error message and exit */
122 if (result == RETURN_OK)
123 SetIoErr(0);
124 else
125 PrintFault(error, NULL);
127 return result;
131 static TEXT GetLogChar(struct LogData *data, struct LogBlock **block,
132 ULONG *pos)
134 TEXT ch = '\0';
136 /* Move on to next block if necessary */
138 if (*pos == (*block)->length)
140 *block = (struct LogBlock *)(*block)->node.mln_Succ;
141 *pos = 0;
144 /* Retrieve a character if the current block is valid and we're not past
145 the used portion of the last block. Assume that block_pos is updated
146 atomically */
148 if ((*block)->node.mln_Succ != NULL
149 && (*block != data->block || *pos < data->block_pos))
150 ch = ((UBYTE *)*block)[sizeof(struct LogBlock) + (*pos)++];
152 return ch;