El día de ayer, sábado, pensaba en qué podría invertir mi tiempo. Buscando algún proyecto que hacer para pasar la tarde y de paso aprender algo y crear algo práctico, se me ocurrió la idea de crear un editor de texto… Pero, como siempre, la realidad me hizo poner los pies en la tierra. Investigando, crear un editor de texto es un trabajo considerablemente laborioso, y claramente no sería algo que me costaría hacer en una tarde, ni en dos, ni en tres…
Aún con las ganas de querer hacer algo, recordé la forma tan directa y rápida de crear directorios en el terminal de Linux (o GNU/Linux, para los colegas), y me propuse a crear un programa para hacer precisamente eso, además de también poder crear cualquier tipo de archivo; por lo que sé, se puede hacer algo similar en la PowerShell de Windows, pero quería hacer algo por mi cuenta.
Usé C para poder crear este programa, además de una implementación del patrón de diseño Command.
El programa funciona mediante argumentos, como si fuera un comando:
PS C:\Users\Name> ./prgm <ruta> <tipo de elemento: carpeta/archivo> <nombre1> <nombre2> <nombre3> <...>
En general el código es un poco soso, y el programa es algo limitado en funcionalidad, pero pasé un muy buen rato programando esta idea.
#include <stdio.h>
#include <string.h>
#include <windows.h>
// interface
typedef struct{
void (*exe_command)(const char*);
} command;
// lista de comandos
typedef struct{
command* command_sp[4];
} command_list;
// funciones para manejar la lista de comandos
void command_list_init(command_list*);
void command_handle(command_list*, const char*, const char*, const char*);
// comandos concretos
void print_guide();
void set_path_current(const char*);
void set_path_by_user(const char*);
void create_dir(const char*);
void create_file(const char*);
// ruta para crear las carpetas y archivos
char path[MAX_PATH];
int main(int argc, char *argv[]){
command_list cmnd_list;
command_list_init(&cmnd_list);
if (argc == 2){
print_guide();
}
for (int i = 3; i < argc; i++){
command_handle(&cmnd_list, argv[1], argv[2], argv[i]);
}
return 0;
}
// inicializar comandos
void command_list_init(command_list* cmnd_list){
cmnd_list->command_sp[0] = &(command){.exe_command = set_path_current};
cmnd_list->command_sp[1] = &(command){.exe_command = set_path_by_user};
cmnd_list->command_sp[2] = &(command){.exe_command = create_dir};
cmnd_list->command_sp[3] = &(command){.exe_command = create_file};
}
// control de comandos
void command_handle(command_list* cmnd_list, const char* first_arg, const char* command, const char* arg){
// comandos para path
if (strcmp(first_arg, "here") == 0){
cmnd_list->command_sp[0]->exe_command("");
}else{ // usar path_command como ruta, la variable global path lo copiara
cmnd_list->command_sp[1]->exe_command(first_arg);
}
// comandos para crear carpeta/archivo
if (strcmp(command, "cdir") == 0){
cmnd_list->command_sp[2]->exe_command(arg);
}else if (strcmp(command, "cfile") == 0){
cmnd_list->command_sp[3]->exe_command(arg);
}
}
// comandos concretos
void print_guide(const char* arg){
printf("SYNOPSIS: \n");
printf("\tPATH ITEM_TYPE ITEM_NAME1 ITEM_NAME2 ...\n");
printf("PATH: \n");
printf("\t> Escribe una ruta en concreto\n");
printf("\t> Comando: <here> Selecciona la ruta en donde se esta ejecutando el programa\n");
printf("ITEM_TYPE: \n");
printf("\t> Comando: <cdir> Crea una carpeta\n");
printf("\t> Comando: <cfile> Crea un archivo\n");
printf("ITEM_NAME: \n");
printf("\t> Nombre del elemento\n");
}
void set_path_current(const char* arg){
GetCurrentDirectoryA(MAX_PATH, path);
}
void set_path_by_user(const char* arg){
strncpy(path, arg, MAX_PATH-1);
path[MAX_PATH-1] = '\0';
}
void create_dir(const char* arg){
strcat(path, "\\"); // añadir caracter, necesario para poder agregar carpeta/archivo
strcat(path, arg); // acoplar el nombre de la carpeta a la ruta del usuario
if (CreateDirectoryA(path, NULL) || GetLastError() == ERROR_ALREADY_EXISTS){
printf("Carpeta creada con exito\n");
printf("%s\n", path);
}else{
printf("%s\n", GetLastError());
}
}
void create_file(const char* arg){
strcat(path, "\\");
strcat(path, arg);
FILE* file = fopen(path, "w");
if (file == NULL){
perror("Error al crear archivo");
return;
}
printf("Archivo creado con exito\n");
printf("%s\n", path);
fclose(file);
}