Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / core / ansiesc.c
1 /*
2  * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <string.h>
23 #include <assert.h>
24 #include <ipxe/ansiesc.h>
25
26 /** @file
27  *
28  * ANSI escape sequences
29  *
30  */
31
32 /**
33  * Call ANSI escape sequence handler
34  *
35  * @v ctx               ANSI escape sequence context
36  * @v function          Control function identifier
37  * @v count             Parameter count
38  * @v params            Parameter list
39  */
40 static void ansiesc_call_handler ( struct ansiesc_context *ctx,
41                                    unsigned int function, int count,
42                                    int params[] ) {
43         struct ansiesc_handler *handlers = ctx->handlers;
44         struct ansiesc_handler *handler;
45
46         for ( handler = handlers ; handler->function ; handler++ ) {
47                 if ( handler->function == function ) {
48                         handler->handle ( ctx, count, params );
49                         break;
50                 }
51         }
52 }
53
54 /**
55  * Process character that may be part of ANSI escape sequence
56  *
57  * @v ctx               ANSI escape sequence context
58  * @v c                 Character
59  * @ret c               Original character if not part of escape sequence
60  * @ret <0              Character was part of escape sequence
61  *
62  * ANSI escape sequences will be plucked out of the character stream
63  * and interpreted; once complete they will be passed to the
64  * appropriate handler if one exists in this ANSI escape sequence
65  * context.
66  *
67  * In the interests of code size, we are rather liberal about the
68  * sequences we are prepared to accept as valid.
69  */
70 int ansiesc_process ( struct ansiesc_context *ctx, int c ) {
71
72         if ( ctx->count == 0 ) {
73                 if ( c == ESC ) {
74                         /* First byte of CSI : begin escape sequence */
75                         ctx->count = 1;
76                         memset ( ctx->params, 0xff, sizeof ( ctx->params ) );
77                         ctx->function = 0;
78                         return -1;
79                 } else {
80                         /* Normal character */
81                         return c;
82                 }
83         } else {
84                 if ( c == '[' ) {
85                         /* Second byte of CSI : do nothing */
86                 } else if ( ( c >= '0' ) && ( c <= '9' ) ) {
87                         /* Parameter Byte : part of a parameter value */
88                         int *param = &ctx->params[ctx->count - 1];
89                         if ( *param < 0 )
90                                 *param = 0;
91                         *param = ( ( *param * 10 ) + ( c - '0' ) );
92                 } else if ( c == ';' ) {
93                         /* Parameter Byte : parameter delimiter */
94                         ctx->count++;
95                         if ( ctx->count > ( sizeof ( ctx->params ) /
96                                             sizeof ( ctx->params[0] ) ) ) {
97                                 /* Excessive parameters : abort sequence */
98                                 ctx->count = 0;
99                                 DBG ( "Too many parameters in ANSI escape "
100                                       "sequence\n" );
101                         }
102                 } else if ( ( ( c >= 0x20 ) && ( c <= 0x2f ) ) ||
103                             ( c == '?' ) ) {
104                         /* Intermediate Byte */
105                         ctx->function <<= 8;
106                         ctx->function |= c;
107                 } else {
108                         /* Treat as Final Byte.  Zero ctx->count before 
109                          * calling handler to avoid potential infinite loops.
110                          */
111                         int count = ctx->count;
112                         ctx->count = 0;
113                         ctx->function <<= 8;
114                         ctx->function |= c;
115                         ansiesc_call_handler ( ctx, ctx->function,
116                                                count, ctx->params );
117                 }
118                 return -1;
119         }
120 }