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; } }
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; }
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; }