ansiesc.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020 
00021 #include <string.h>
00022 #include <assert.h>
00023 #include <gpxe/ansiesc.h>
00024 
00025 /** @file
00026  *
00027  * ANSI escape sequences
00028  *
00029  */
00030 
00031 /**
00032  * Call ANSI escape sequence handler
00033  *
00034  * @v handlers          List of escape sequence handlers
00035  * @v function          Control function identifier
00036  * @v count             Parameter count
00037  * @v params            Parameter list
00038  */
00039 static void ansiesc_call_handler ( struct ansiesc_handler *handlers,
00040                                    unsigned int function, int count,
00041                                    int params[] ) {
00042         struct ansiesc_handler *handler;
00043 
00044         for ( handler = handlers ; handler->function ; handler++ ) {
00045                 if ( handler->function == function ) {
00046                         handler->handle ( count, params );
00047                         break;
00048                 }
00049         }
00050 }
00051 
00052 /**
00053  * Process character that may be part of ANSI escape sequence
00054  *
00055  * @v ctx               ANSI escape sequence context
00056  * @v c                 Character
00057  * @ret c               Original character if not part of escape sequence
00058  * @ret <0              Character was part of escape sequence
00059  *
00060  * ANSI escape sequences will be plucked out of the character stream
00061  * and interpreted; once complete they will be passed to the
00062  * appropriate handler if one exists in this ANSI escape sequence
00063  * context.
00064  *
00065  * In the interests of code size, we are rather liberal about the
00066  * sequences we are prepared to accept as valid.
00067  */
00068 int ansiesc_process ( struct ansiesc_context *ctx, int c ) {
00069         if ( ctx->count == 0 ) {
00070                 if ( c == ESC ) {
00071                         /* First byte of CSI : begin escape sequence */
00072                         ctx->count = 1;
00073                         memset ( ctx->params, 0xff, sizeof ( ctx->params ) );
00074                         ctx->function = 0;
00075                         return -1;
00076                 } else {
00077                         /* Normal character */
00078                         return c;
00079                 }
00080         } else {
00081                 if ( c == '[' ) {
00082                         /* Second byte of CSI : do nothing */
00083                 } else if ( ( c >= '0' ) && ( c <= '9' ) ) {
00084                         /* Parameter Byte : part of a parameter value */
00085                         int *param = &ctx->params[ctx->count - 1];
00086                         if ( *param < 0 )
00087                                 *param = 0;
00088                         *param = ( ( *param * 10 ) + ( c - '0' ) );
00089                 } else if ( c == ';' ) {
00090                         /* Parameter Byte : parameter delimiter */
00091                         ctx->count++;
00092                         if ( ctx->count > ( sizeof ( ctx->params ) /
00093                                             sizeof ( ctx->params[0] ) ) ) {
00094                                 /* Excessive parameters : abort sequence */
00095                                 ctx->count = 0;
00096                                 DBG ( "Too many parameters in ANSI escape "
00097                                       "sequence\n" );
00098                         }
00099                 } else if ( ( c >= 0x20 ) && ( c <= 0x2f ) ) {
00100                         /* Intermediate Byte */
00101                         ctx->function <<= 8;
00102                         ctx->function |= c;
00103                 } else {
00104                         /* Treat as Final Byte.  Zero ctx->count before 
00105                          * calling handler to avoid potential infinite loops.
00106                          */
00107                         int count = ctx->count;
00108                         ctx->count = 0;
00109                         ctx->function <<= 8;
00110                         ctx->function |= c;
00111                         ansiesc_call_handler ( ctx->handlers, ctx->function,
00112                                                count, ctx->params );
00113                 }
00114                 return -1;
00115         }
00116 }

Generated on Tue Apr 6 20:00:51 2010 for gPXE by  doxygen 1.5.7.1