Пример #1
0
static void sighandler ( int signum )
{
  switch ( signum )
  {
    case SIGTERM:
      continuar = 0;
      break;

    case SIGINT:
      writef ( 1, "\r\n" );
      mostrar_prompt ();
      linea_inicializar ( linea );
      linea = &lineaActual;
      posicion_historial = -1;
      break;
  }
}
Пример #2
0
int main ( int argc, const char* argv[], char* envp[] )
{
  linea = &lineaActual;

  // Definido en historial.h
  Historial* hist = historial_obtener_instancia ();

  // Definido en variables.h
  Variables* vars = variables_crear ();

  // Definido en aliases.h
  Aliases* aliases = aliases_obtener_instancia ();

  // Inicializaciones.
  linea_inicializar ( &lineaActual );
  linea_inicializar ( &lineaHistorial );
  historial_cargar_desde_fichero ( hist, FICHERO_HISTORIAL );
  historial_guardar_a_fichero ( hist, FICHERO_HISTORIAL );
  registrar_comandos_internos ();

  // Señales.
  signal ( SIGTERM, sighandler );
  signal ( SIGINT, sighandler );

  // Mostramos el prompt.
  mostrar_prompt ();

  // Bucle principal.
  char c;
  int n = 0;
  while ( continuar && ( ( n = getch ( &c ) ) == 1 ) )
  {
    switch ( c )
    {
      case 4:
        // CTRL+D
        if ( linea->len == 0 )
        {
          continuar = 0;
          writef ( 1, "exit\n" );
        }
        break;

      case 11:
        // CTRL+K
        ejecutar_secuencia_escape ( LINEA_LIMPIAR_DERECHA );
        linea_eliminar_desde_cursor ( linea );
        break;
      case 12:
        // CTRL+L (Limpiar pantalla)
        hacer_eco ( 12 );
        linea_mostrar_reset ( linea );
        break;
      case '\t':
        procesar_sugerencias ( linea );
        break;
      case 8:
        // CTRL+H
      case 127:
        // Backspace
        linea_backspace ( linea );
        break;
      case 27:
        // Secuencia de escape
        linea_anyadir_secuencia_escape ( linea, c, hacer_eco );
        break;
      default:
        // Almacenamos el caracter leido
        if ( c != '\n' )
        {
          linea_anyadir ( linea, c, hacer_eco );

          // Verificamos si tenemos que mostrar secuencias de escape y procesamos
          // algunos casos concretos.
          CodigoSecuencia codigoEscape = procesar_secuencia_escape ( linea, NULL );
          switch ( codigoEscape )
          {
            case SECUENCIA_MAXIMA:
            case SECUENCIA_NO_INICIADA:
            case SECUENCIA_NO_FINALIZADA:
              break;
            case SECUENCIA_INEXISTENTE:
              linea_mostrar_secuencia_escape ( linea, hacer_eco );
              linea_limpiar_secuencia_escape ( linea );
              break;

            default:
              if ( linea_procesar_secuencia_escape ( linea, codigoEscape ) == 1 )
              {
                ejecutar_secuencia_escape ( codigoEscape );
              }
              linea_limpiar_secuencia_escape ( linea );
              break;

            // Casos concretos.
            // Historial.
            case FLECHA_ARRIBA:
            {
              char* lineaContenido;

              linea_limpiar_secuencia_escape ( linea );

              ++posicion_historial;
              lineaContenido = historial_obtener ( hist, posicion_historial );
              if ( lineaContenido == NULL )
              {
                --posicion_historial;
              }
              else
              {
                if ( linea == &lineaActual )
                  linea = &lineaHistorial;
                linea_cargar_contenido ( linea, lineaContenido );
                linea_mostrar_reset ( linea );
              }

              break;
            }

            case FLECHA_ABAJO:
            {
              char* lineaContenido;

              linea_limpiar_secuencia_escape ( linea );

              if ( posicion_historial > -1 )
              {
                --posicion_historial;
              
                if ( posicion_historial > -1 )
                {
                  lineaContenido = historial_obtener ( hist, posicion_historial );
                  if ( lineaContenido != NULL )
                  {
                    linea = &lineaHistorial;
                    linea_cargar_contenido ( linea, lineaContenido );
                    linea_mostrar_reset ( linea );
                  }
                }
                else
                {
                  linea = &lineaActual;
                  linea->cursor = linea->len;
                  linea_mostrar_reset ( linea );
                }
              }

              break;
            }

            case PAGINA_ARRIBA:
            {
              char* lineaContenido;

              linea_limpiar_secuencia_escape ( linea );

              posicion_historial += 5;
              if ( posicion_historial >= historial_tamanyo ( hist ) )
                posicion_historial = historial_tamanyo ( hist ) - 1;

              lineaContenido = historial_obtener ( hist, posicion_historial );
              if ( lineaContenido != NULL )
              {
                if ( linea == &lineaActual )
                  linea = &lineaHistorial;
                linea_cargar_contenido ( linea, lineaContenido );
                linea_mostrar_reset ( linea );
              }

              break;
            }

            case PAGINA_ABAJO:
            {
              char* lineaContenido;

              linea_limpiar_secuencia_escape ( linea );
              if ( posicion_historial > -1 )
              {
                posicion_historial -= 5;
                if ( posicion_historial < 0 )
                  posicion_historial = -1;

                if ( posicion_historial > -1 )
                {
                  lineaContenido = historial_obtener ( hist, posicion_historial );
                  if ( lineaContenido != NULL )
                  {
                    linea = &lineaHistorial;
                    linea_cargar_contenido ( linea, lineaContenido );
                    linea_mostrar_reset ( linea );
                  }
                }
                else
                {
                  linea = &lineaActual;
                  linea_mostrar_reset ( linea );
                }
              }
            }
          }
        }

        // Si leemos un salto de linea, el comando ha sido introducido completamente.
        else
        {
          // Nos aseguramos de que no queden secuencias de escape iniciadas pero no finalizadas.
          linea_mostrar_secuencia_escape ( linea, hacer_eco );
          linea_limpiar_secuencia_escape ( linea );

          // Introducimos el salto de linea en pantalla.
          hacer_eco ( '\r' );
          hacer_eco ( '\n' );

          // Procesamos el comando introducido.
          if ( procesar_comando ( linea_hacer_string( linea ), envp, vars, aliases ) == COMANDO_SALIR )
            continuar = 0;

          // Reiniciamos el acceso al historial.
          linea = &lineaActual;
          posicion_historial = -1;
          linea_inicializar ( linea );

          if ( continuar )
            mostrar_prompt ();
        }
    }
  }

  // Finalizaciones
  historial_eliminar ( hist );
  variables_eliminar ( vars );
  aliases_eliminar ( aliases );

  // Verificamos si ha ocurrido algun error leyendo la linea.
  if ( n == -1 )
    error ( "getch" );

  return 0;
}
Пример #3
0
int main() {
  lista lst = crear_lista();

  nat cont_comandos = 0;
  bool salir = false;
  while (!salir) {

    mostrar_prompt(cont_comandos);
    enum_cmd_t enum_com = identificador_comando();

    // procesar el comando
    switch (enum_com) {
    case cmd_fin:
      salir = true;
      imprimir_con_nl(msg_fin);
      break;
    case cmd_comentario:
      escribir_nueva_linea();
      break;
    case cmd_ins_lista: {
      info_t info = leer_info(MAX_LARGO_PALABRA);
      while (es_valida_info(info)) {
        insertar_despues(info, final_lista(lst), lst);
        info = leer_info(MAX_LARGO_PALABRA);
      }
      liberar_info(info);
      texto_t txt = cadena_a_texto("primero");
      info = crear_info(0, txt);
      insertar_antes(info, inicio_lista(lst), lst);
      imprimir_lista(lst);
      break;
    }
    case cmd_recorrido_lista: {
      if (!es_vacia_lista(lst)) {
        localizador loc = inicio_lista(lst);
        while (es_localizador_lista(loc)) {
          texto_t txt = info_a_texto(info_lista(loc, lst));
          escribir_texto(txt);
          liberar_texto(txt);
          loc = siguiente(loc, lst);
        }
        loc = final_lista(lst);
        while (es_localizador_lista(loc)) {
          texto_t txt = info_a_texto(info_lista(loc, lst));
          escribir_texto(txt);
          liberar_texto(txt);
          loc = anterior(loc, lst);
        }
        escribir_nueva_linea();
      }
      break;
    }
    case cmd_segmentos_lista: {
      int clave1 = leer_int();
      int clave2 = leer_int();
      localizador desde = siguiente_clave(clave1, inicio_lista(lst), lst);
      localizador hasta = anterior_clave(clave2, final_lista(lst), lst);
      if (es_localizador_lista(desde) && es_localizador_lista(hasta) &&
          precede_en_lista(desde, hasta, lst)) {
        lista sgm = separar_segmento(desde, hasta, lst);
        lista copia = segmento_lista(inicio_lista(sgm), final_lista(sgm), sgm);
        imprimir_lista(sgm);
        liberar_lista(sgm);
        insertar_segmento_despues(copia, final_lista(lst), lst);
        liberar_lista(copia);
        imprimir_lista(lst);
      }
      break;
    }
    case cmd_modificar_lista: {
      int clave1 = leer_int();
      int clave2 = leer_int();
      localizador loc1 = siguiente_clave(clave1, inicio_lista(lst), lst);
      localizador loc2 = anterior_clave(clave2, final_lista(lst), lst);
      if (es_localizador_lista(loc1) && es_localizador_lista(loc2)) {
        intercambiar(loc1, loc2, lst);
        imprimir_lista(lst);
        retroceder(loc2, lst);
        imprimir_lista(lst);
      }
      break;
    }
    case cmd_ordenar_lista: {
      nat len_lst = longitud(lst);
      imprimir_int(len_lst);
      localizador loc = inicio_lista(lst);
      for (nat i = 0; i < len_lst / 2 - 1; i++)
        loc = siguiente(loc, lst);
      lista primera = segmento_lista(inicio_lista(lst), loc, lst);
      lista segunda =
          segmento_lista(siguiente(loc, lst), final_lista(lst), lst);

      lista concat = concatenar(primera, segunda);
      imprimir_lista(concat);
      liberar_lista(concat);

      if (son_numeros_iguales(primera, segunda)) {
        imprimir_lista(primera);
      }

      if (!esta_ordenada(primera))
        ordenar(primera);
      if (!esta_ordenada(segunda))
        ordenar(segunda);

      lista mzc = mezcla(primera, segunda);
      imprimir_lista(mzc);

      unificar(mzc);
      imprimir_lista(mzc);
      liberar_lista(mzc);
      liberar_lista(primera);
      liberar_lista(segunda);
      break;
    }
    case cmd_filtrado_lista: {
      int clave = leer_int();
      texto_t palabra = leer_palabra(MAX_LARGO_PALABRA);
      comp_t criterio = texto_a_comp(palabra);
      liberar_texto(palabra);
      if (pertenece(clave, lst)) {
        imprimir_int(cantidad(clave, lst));
      }
      lista flt = filtrado(clave, criterio, lst);
      imprimir_lista(flt);
      liberar_lista(flt);
      break;
    }
    case cmd_reversa_lista: {
      int dato1 = leer_int();
      int dato2 = leer_int();
      if (esta_ordenada(lst) && pertenece(dato1, lst) &&
          pertenece(dato2, lst) && dato1 < dato2) {
        lista sub = sublista(dato1, dato2, lst);
        imprimir_lista(sub);
        lista rev = reversa(sub);
        imprimir_lista(rev);
        cambiar_todos(dato1, dato2, rev);
        imprimir_lista(rev);
        liberar_lista(sub);
        liberar_lista(rev);
      }
      break;
    }
    case cmd_liberar_lista: {
      liberar_lista(lst);
      lst = crear_lista();
      break;
    }
    default:
      imprimir_con_nl(msg_cmd_no_reconocido);
      break;
    } // switch
    texto_t resto_linea = leer_resto_linea(MAX_RESTO_LINEA);
    liberar_texto(resto_linea);
  } // while
  liberar_lista(lst);
  return 0;
}