You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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. * You can also choose to distribute this program under the terms of
  20. * the Unmodified Binary Distribution Licence (as given in the file
  21. * COPYING.UBDL), provided that you have satisfied its requirements.
  22. */
  23. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. #include <string.h>
  25. #include <assert.h>
  26. #include <ipxe/ansiesc.h>
  27. /** @file
  28. *
  29. * ANSI escape sequences
  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. for ( handler = handlers ; handler->function ; handler++ ) {
  46. if ( handler->function == function ) {
  47. handler->handle ( ctx, count, params );
  48. break;
  49. }
  50. }
  51. }
  52. /**
  53. * Process character that may be part of ANSI escape sequence
  54. *
  55. * @v ctx ANSI escape sequence context
  56. * @v c Character
  57. * @ret c Original character if not part of escape sequence
  58. * @ret <0 Character was part of escape sequence
  59. *
  60. * ANSI escape sequences will be plucked out of the character stream
  61. * and interpreted; once complete they will be passed to the
  62. * appropriate handler if one exists in this ANSI escape sequence
  63. * context.
  64. *
  65. * In the interests of code size, we are rather liberal about the
  66. * sequences we are prepared to accept as valid.
  67. */
  68. int ansiesc_process ( struct ansiesc_context *ctx, int c ) {
  69. if ( ctx->count == 0 ) {
  70. if ( c == ESC ) {
  71. /* First byte of CSI : begin escape sequence */
  72. ctx->count = 1;
  73. memset ( ctx->params, 0xff, sizeof ( ctx->params ) );
  74. ctx->function = 0;
  75. return -1;
  76. } else {
  77. /* Normal character */
  78. return c;
  79. }
  80. } else {
  81. if ( c == '[' ) {
  82. /* Second byte of CSI : do nothing */
  83. } else if ( ( c >= '0' ) && ( c <= '9' ) ) {
  84. /* Parameter Byte : part of a parameter value */
  85. int *param = &ctx->params[ctx->count - 1];
  86. if ( *param < 0 )
  87. *param = 0;
  88. *param = ( ( *param * 10 ) + ( c - '0' ) );
  89. } else if ( c == ';' ) {
  90. /* Parameter Byte : parameter delimiter */
  91. ctx->count++;
  92. if ( ctx->count > ( sizeof ( ctx->params ) /
  93. sizeof ( ctx->params[0] ) ) ) {
  94. /* Excessive parameters : abort sequence */
  95. ctx->count = 0;
  96. DBG ( "Too many parameters in ANSI escape "
  97. "sequence\n" );
  98. }
  99. } else if ( ( ( c >= 0x20 ) && ( c <= 0x2f ) ) ||
  100. ( c == '?' ) ) {
  101. /* Intermediate Byte */
  102. ctx->function <<= 8;
  103. ctx->function |= c;
  104. } else {
  105. /* Treat as Final Byte. Zero ctx->count before
  106. * calling handler to avoid potential infinite loops.
  107. */
  108. int count = ctx->count;
  109. ctx->count = 0;
  110. ctx->function <<= 8;
  111. ctx->function |= c;
  112. ansiesc_call_handler ( ctx, ctx->function,
  113. count, ctx->params );
  114. }
  115. return -1;
  116. }
  117. }