From 13f83567d36f46edd8f4a6595cd43e9bff50646a Mon Sep 17 00:00:00 2001 From: Agustin Ranieri Date: Thu, 15 Aug 2024 10:38:32 -0300 Subject: [PATCH] Docs: Improved headers (#188) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * config, log, memory, string, temporal, y txt agregados * docs: Quito código de la página principal * Todo medianamente documentado * Listas recontra documentadas, Abrazo * Otro día indentaré como corresponde * Dije que luego indento como se debe * Boeeeeeee * Así está el temporal chicos? * Agrego al pingu * Improve config.h header * Muevo list_add() para arriba * Update log.h * Update list.h * Update temporal.h --------- Co-authored-by: f-and --- docs/Doxyfile | 6 +- docs/favicon-32x32.png | Bin 0 -> 2282 bytes src/commons/collections/dictionary.h | 147 +++-- src/commons/collections/list.h | 849 +++++++++++++++++++++++++-- src/commons/collections/queue.h | 21 +- src/commons/config.h | 12 +- src/commons/log.h | 22 +- src/commons/memory.h | 1 + src/commons/process.h | 12 +- src/commons/string.h | 432 ++++++++++---- src/commons/temporal.h | 27 +- src/commons/txt.h | 1 + 12 files changed, 1252 insertions(+), 278 deletions(-) create mode 100644 docs/favicon-32x32.png diff --git a/docs/Doxyfile b/docs/Doxyfile index 3d1b033..90ec4e2 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -51,7 +51,7 @@ PROJECT_BRIEF = "TADs de uso común en aplicaciones desarrolladas en C" # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. -PROJECT_LOGO = +PROJECT_LOGO = "./favicon-32x32.png" # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is @@ -158,7 +158,7 @@ INLINE_INHERITED_MEMB = NO # shortest path that makes the file name unique will be used # The default value is: YES. -FULL_PATH_NAMES = YES +FULL_PATH_NAMES = NO # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand @@ -1082,7 +1082,7 @@ SOURCE_BROWSER = YES # classes and enums directly into the documentation. # The default value is: NO. -INLINE_SOURCES = YES +INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and diff --git a/docs/favicon-32x32.png b/docs/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..2e425719bb7f6d09a8de832be02d183e2d658024 GIT binary patch literal 2282 zcmVPx-q)9|UR9Hu?mwilBR~p8jJ2SvA%)sy=FjBB!%XBM@9l6-z4Yx>PHI zf^paFX4lqiQrGBa{ez@xOoYIH%?g|Y#vXz5s3aTrk$7#Lujf%$@&0cP&q zyvIr;XqG0N`t>272XNO=7{l%rKs;UoXZ5b96 z6#TNhyu8xK$46?lT9KX|co={K+L|tWQXzt0Y;xE2>(}FE1%QfA zU0vNJ0GoPydl4EMih_aytWKB*rLzNaYZKyE$Y5->;5%U>j$XKluCA`$oSdAbl9Ce3 zOdwuc2Xb<9d|fWrSB;I0zY&YYtmtHCXEP5hTeghB4D=h|`u=O!6>%5~P~qgslgx;z zsi}=IF)<&Om6iS9iuhW9{QUeRole(mFc>%*oacEQK71J4w{K^zuc)ZN@#DwgbUIl9 zqCzw@G{lx86)FHd6B858*Qj8(+wH#wpnoMmK|#Tq2M-=xFq_TMWIVlIkA({t;>3v) zSiO2R#>dA|Qc{BZ_wTa-3682F6{(pt02XK4}z>Xa|vNambX^+RFjEsy#M@I*hR!{}pzkfgW?c0ZdfB;ZQreZ`sAaw!* z0~vt7zdw?bli9SiwY6c+oHGqG&B@RYE1$Z78ZuxxpU{N zN~PLFfk;|%J~hgK0)&Ny;mVaOtoU5Jc8z7|a5&h&BrDyoUAvaOOBX3fexUt=RC?i; z`uh5>O(xTpDF7K68SC6`cQs`)I5^05J90lY3QoW2qCu$a&YL$6eSLiljHZJ6(Dcv> zp*|!z$*t9D8887*pGS`#L8H;E1n}JyfSjD1LA_odK{5>w53>Wu>l&R2Qd3iD&9lMC zd^G1vmo8E*E|q z`4sPOiNUQ(Gm0BIh(uxp$mOgUkwOGRQ$Yuo^tWZ$yVi{%vjRvd09xtF**NrcG z!kH)Hb7JS9y`}|!y=Lk8G+X^2iJwo7slE5y`m(;?PpgC}DJe~N z@7_&*S*C_R#bWg)6^3jQ_(?+`Gim^@2T%sX>XC$EJ?JeRwziu%H78 z8SxObO>meTa7VrcnJOBR!AJPE!hB}^xxVS8SglsaTCLWnFRy}zk7JO!(g(tX`}x2e z2Ttq*f#(6i3t_~9+RlX-UHumZK=U51EkpVyDYy|cgi$BJd!D~5mcVW3#qIxwy&51d zFHc%uUtg@(>-SP1Y6P$<(Fwt611Apw=O+axRe-lstq{=NIgXxp4?{FJ5$)~m2p#Q0 zvaAjqQ{gi#9}pm4h-w4C$u`(L>m78MnxG&eV2YHDhFlK?(j7m7b; z$)Mnk-~xgn3JihZ@h~94_6)k-V00}10v)|Z^mlh4BcvUx)+-^kcR?@?JRe*D1g908 zObM?d0NukXJbP@J`e~M*pFdYD7So~f7=Re7)fzyXN|?ulvRnbt!B&WZ!XfZpa8enB zF(-z5Eja&l86J4&!(y{Ra6ChC<_OfQ!XWevKp>SkF$9Mh;JtuI45wQHE5gkBLB+>Y z6xg+E*LxhtT>+qa*@XUr3mcSLq^Sqt>+cJ}I|0tuA6}Cl72iwow{N8|P582%bBQ_z zr#=!x{k8=BKpzVu*ys~ZK$lSgk4J$z)QV=jqVE zTD-UOXItW0=BdJYK;nlnw}40Oo*&LQ(x2Jf!X$5~RFGvyJY4gR(g4Bjgmzd3^INz*3+j?SH9f;e-XJ{!x-jPBLDyZ07*qoM6N<$ Efelement) al diccionario, en caso de ya existir la key actualiza el elemento. - * @relates t_dictionary - * - * @warning Tener en cuenta que esto no va a liberar la memoria del `element` original. - */ - void dictionary_put(t_dictionary *, char *key, void *element); + * @brief Crea el diccionario + * @return Devuelve un puntero al diccionario creado, liberable con: + * - dictionary_destroy() si se quiere liberar el diccionario pero no + * los elementos que contiene. + * - dictionary_destroy_and_destroy_elements() si se quieren liberar + * el diccionario con los elementos que contiene. + * @relates t_dictionary + */ + t_dictionary *dictionary_create(void); + + /** + * @brief Inserta un nuevo par (key->element) al diccionario, en caso de ya + * existir la key actualiza el elemento. + * @param[in] key La clave del elemento. Una copia de la clave será almacenada + * en el diccionario, por lo que no se afectará a la original. + * @param[in] element El elemento a insertar. Este elemento pasará a pertenecer + * al diccionario, por lo que no debe ser liberado por fuera de éste. + * @relates t_dictionary + * + * @warning Tener en cuenta que esto no va a liberar la memoria del `element` original. + */ + void dictionary_put(t_dictionary *, char *key, void *element); /** - * @brief Obtiene el elemento asociado a la key. - * @relates t_dictionary - */ - void *dictionary_get(t_dictionary *, char *key); + * @brief Obtiene el elemento asociado a la key. + * @return Devuelve un puntero perteneciente al diccionario, o NULL si no existe. + * Este puntero no debe ser liberado por fuera del diccionario. + * @relates t_dictionary + */ + void *dictionary_get(t_dictionary *, char *key); /** - * @brief Remueve un elemento del diccionario y lo retorna. - * @relates t_dictionary - */ - void *dictionary_remove(t_dictionary *, char *key); + * @brief Remueve un elemento del diccionario y lo retorna. + * @return Devuelve un puntero al elemento removido, o NULL si no existe. + * Al haberse removido, debe ser liberado por fuera del diccionario en + * caso de ser necesario. + * @relates t_dictionary + */ + void *dictionary_remove(t_dictionary *, char *key); /** - * @brief Remueve un elemento del diccionario y lo destruye. - * @relates t_dictionary - */ - void dictionary_remove_and_destroy(t_dictionary *, char *, void(*element_destroyer)(void*)); + * @brief Remueve un elemento del diccionario y lo destruye llamando a la función + * `element_destroyer` pasada por parámetro. + * @relates t_dictionary + */ + void dictionary_remove_and_destroy(t_dictionary *, char *, void(*element_destroyer)(void*)); /** - * @brief Aplica closure a todos los elementos del diccionario. - * @relates t_dictionary - */ - void dictionary_iterator(t_dictionary *, void(*closure)(char* key, void* element)); + * @brief Aplica `closure` a todos los elementos del diccionario. + * @relates t_dictionary + */ + void dictionary_iterator(t_dictionary *, void(*closure)(char* key, void* element)); /** - * @brief Quita todos los elementos del diccionario - * @relates t_dictionary - */ - void dictionary_clean(t_dictionary *); + * @brief Quita todos los elementos del diccionario sin liberarlos, dejando el + * diccionario vacío. + * @relates t_dictionary + */ + void dictionary_clean(t_dictionary *); /** - * @brief Quita todos los elementos del diccionario y los destruye - * @relates t_dictionary - */ - void dictionary_clean_and_destroy_elements(t_dictionary *, void(*element_destroyer)(void*)); + * @brief Quita todos los elementos del diccionario y los destruye, dejando el + * diccionario vacío. + * @relates t_dictionary + */ + void dictionary_clean_and_destroy_elements(t_dictionary *, void(*element_destroyer)(void*)); /** - * @brief Retorna true si key se encuentra en el diccionario - * @relates t_dictionary - */ - bool dictionary_has_key(t_dictionary *, char* key); + * @brief Retorna true si `key` se encuentra en el diccionario + * @relates t_dictionary + */ + bool dictionary_has_key(t_dictionary *, char* key); /** - * @brief Retorna true si el diccionario está vacío - * @relates t_dictionary - */ - bool dictionary_is_empty(t_dictionary *); + * @brief Retorna true si el diccionario está vacío + * @relates t_dictionary + */ + bool dictionary_is_empty(t_dictionary *); /** - * @brief Retorna la cantidad de elementos del diccionario - * @relates t_dictionary - */ - int dictionary_size(t_dictionary *); + * @brief Retorna la cantidad de elementos del diccionario + * @relates t_dictionary + */ + int dictionary_size(t_dictionary *); /** - * @brief Retorna todas las keys en una lista - * @relates t_dictionary - */ - t_list *dictionary_keys(t_dictionary *self); + * @brief Retorna todas las keys en una lista + * @relates t_dictionary + */ + t_list *dictionary_keys(t_dictionary *self); /** - * @brief Retorna todos los elementos en una lista - * @relates t_dictionary - */ - t_list *dictionary_elements(t_dictionary *self); + * @brief Retorna todos los elementos en una lista + * @relates t_dictionary + */ + t_list *dictionary_elements(t_dictionary *self); /** - * @brief Destruye el diccionario - * @relates t_dictionary - */ - void dictionary_destroy(t_dictionary *); + * @brief Destruye el diccionario + * @relates t_dictionary + */ + void dictionary_destroy(t_dictionary *); /** - * @brief Destruye el diccionario y destruye sus elementos - * @relates t_dictionary - */ - void dictionary_destroy_and_destroy_elements(t_dictionary *, void(*element_destroyer)(void*)); + * @brief Destruye el diccionario y destruye sus elementos + * @note En caso de recibir un diccionario vacío, se comporta como dictionary_destroy() + * @relates t_dictionary + */ + void dictionary_destroy_and_destroy_elements(t_dictionary *, void(*element_destroyer)(void*)); #endif /* DICTIONARY_H_ */ diff --git a/src/commons/collections/list.h b/src/commons/collections/list.h index f8aff31..1fcbb47 100755 --- a/src/commons/collections/list.h +++ b/src/commons/collections/list.h @@ -21,7 +21,6 @@ #include /** - * @struct t_list * @brief Estructura de una lista enlazada */ typedef struct { @@ -40,287 +39,1023 @@ } t_list_iterator; /** - * @brief Crea una lista - * @relates t_list - */ - t_list * list_create(); + * @brief Crea una lista + * @return Retorna un puntero a la lista creada, liberable con: + * - list_destroy() si se quiere liberar la lista pero no + * los elementos que contiene. + * - list_destroy_and_destroy_elements() si se quiere liberar + * la lista con los elementos que contiene + * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * + * => people = [] + * @endcode + */ + t_list * list_create(void); /** - * @brief Destruye una lista sin liberar - * los elementos contenidos en los nodos + * @brief Agrega un elemento al final de la lista + * @param element: El elemento a agregar. Este elemento pasará a pertenecer + * a la lista, por lo que no debe ser liberado por fuera de ésta. + * @return El índice en el que se agregó el elemento * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * + * t_person* person_create(char* name, int age) { + * t_person* person = malloc(sizeof(t_person)); + * person->name = string_duplicate(name); + * person->age = age; + * return person; + * } + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ - void list_destroy(t_list* self); + int list_add(t_list* self, void *element); /** - * @brief Destruye una lista y sus elementos + * @brief Destruye una lista sin liberar los elementos contenidos en los nodos * @relates t_list + * + * Ejemplo de uso: + * @code + * t_person* messi = person_create("Lionel Messi", 33); // 0x1234 + * t_person* ronaldo = person_create("Cristiano Ronaldo", 35); // 0x5678 + * t_person* neymar = person_create("Neymar Jr.", 29); // 0x9abc + * + * t_list* people = list_create(); + * list_add(people, messi); + * list_add(people, ronaldo); + * list_add(people, neymar); + * + * list_destroy(people); + * + * => neymar = 0x9abc + * => ronaldo = 0x5678 + * => messi = 0x1234 + * @endcode */ - void list_destroy_and_destroy_elements(t_list* self, void(*element_destroyer)(void*)); + void list_destroy(t_list* self); /** - * @brief Agrega un elemento al final de la lista + * @brief Destruye una lista y sus elementos contenidos llamando a la función + * `element_destroyer` sobre cada uno de ellos. + * @note En caso de recibir una lista vacía, se comporta como list_destroy(). * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * void person_destroy(void* ptr) { + * t_person* person = (t_person*) ptr; + * free(person->name); + * free(person); + * } + * list_destroy_and_destroy_elements(people, person_destroy); + * + * => **no hay punteros sin liberar** + * @endcode */ - int list_add(t_list* self, void *element); + void list_destroy_and_destroy_elements(t_list* self, void(*element_destroyer)(void*)); /** * @brief Agrega un elemento en una posicion determinada de la lista + * @param index: La posicion en la que se quiere agregar el elemento + * @param element: El elemento a agregar. Este elemento pasará a pertenecer + * a la lista, por lo que no debe ser liberado por fuera de ésta. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, 0, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, 1, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, 1, person_create("Neymar Jr.", 29)); // 0x9abc + * + * list_add_in_index(people, 1, person_create("Kylian Mbappé", 22)); // 0xdef0 + * + * => people = [0x1234, 0xdef0, 0x5678, 0x9abc] + * @endcode */ void list_add_in_index(t_list* self, int index, void *element); /** * @brief Agrega un elemento a una lista ordenada, manteniendo el * orden definido por el comparador + * @param data: El elemento a agregar. Este elemento pasará a pertenecer + * a la lista, por lo que no debe ser liberado por fuera de ésta. + * @param comparator: Funcion que compara dos elementos. Debe devolver + * true si el primer parametro debe aparecer antes que el + * segundo en la lista * @relates t_list * - * @note El comparador devuelve true si el primer parametro debe aparecer - * antes que el segundo en la lista + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Kylian Mbappé", 22)); // 0x1234 + * list_add(people, person_create("Lionel Messi", 33)); // 0x5678 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x9abc + * + * bool _has_age_less_than(void* a, void* b) { + * t_person* person_a = (t_person*) a; + * t_person* person_b = (t_person*) b; + * return person_a->age < person_b->age; + * } + * list_add_sorted(people, person_create("Neymar Jr.", 29), _has_age_less_than); // 0xdef0 + * + * => people = [0x1234, 0xdef0, 0x5678, 0x9abc] + * @endcode */ int list_add_sorted(t_list *self, void* data, bool (*comparator)(void*,void*)); /** - * @brief Agrega todos los elementos de la segunda lista en la primera + * @brief Agrega todos los elementos de la segunda lista al final de la primera. + * @param self: La lista a la que se le agregarán los elementos. + * @param other: La lista de la que se tomarán los elementos. Dichos elementos + * pasarán a pertenecer a ambas listas a la vez. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * + * t_list* other_people = list_create(); + * list_add(other_people, person_create("Neymar Jr.", 29)); // 0x9abc + * list_add(other_people, person_create("Kylian Mbappé", 22)); // 0xdef0 + * + * list_add_all(people, other_people); + * + * => people = [0x1234, 0x5678, 0x9abc, 0xdef0] + * => other_people = [0x9abc, 0xdef0] + * @endcode */ void list_add_all(t_list* self, t_list* other); /** * @brief Retorna el contenido de una posicion determinada de la lista + * @return El elemento en la posición index. Este elemento seguirá + * perteneciendo a la lista, por lo que no debe ser liberado por fuera + * de ésta. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * t_person* person = list_get(people, 1); + * + * => person = 0x5678 + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ void *list_get(t_list* self, int index); /** * @brief Retorna el minimo de la lista según el comparador + * @param minimum: Funcion que compara dos elementos. Debe devolver + * el menor de los dos + * @return El elemento mínimo de la lista. Este elemento seguirá + * perteneciendo a la lista, por lo que no debe ser liberado por fuera + * de ésta. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * void* _min_age(void* a, void* b) { + * t_person* person_a = (t_person*) a; + * t_person* person_b = (t_person*) b; + * return person_a->age < person_b->age ? person_a : person_b; + * } + * t_person* youngest = list_get_minimum(people, _min_age); + * + * => youngest = 0x9abc + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ void *list_get_minimum(t_list* self, void* (*minimum)(void*, void*)); /** * @brief Retorna el maximo de la lista según el comparador + * @param maximum: Funcion que compara dos elementos. Debe devolver + * el mayor de los dos + * @return El elemento máximo de la lista. Este elemento seguirá + * perteneciendo a la lista, por lo que no debe ser liberado por fuera + * de ésta. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * void* _max_age(void* a, void* b) { + * t_person* person_a = (t_person*) a; + * t_person* person_b = (t_person*) b; + * return person_a->age > person_b->age ? person_a : person_b; + * } + * t_person* oldest = list_get_maximum(people, _max_age); + * + * => oldest = 0x5678 + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ void *list_get_maximum(t_list* self, void* (*maximum)(void*, void*)); /** * @brief Retorna una nueva lista con los primeros n elementos. + * @param count: Cantidad máxima de elementos a tomar. + * @return Una nueva lista con los elementos tomados. Seguirán perteneciendo + * a la lista original. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * t_list* first_two = list_take(people, 2); + * + * => first_two = [0x1234, 0x5678] + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ t_list* list_take(t_list* self, int count); /** * @brief Retorna una nueva lista con los primeros n elementos partiendo * desde el índice indicado. + * @param start: Índice desde el cual se tomarán los elementos. + * @param count: Cantidad máxima de elementos a tomar. + * @return Una nueva lista con los elementos tomados. Seguirán perteneciendo + * a la lista original. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * t_list* last_two = list_slice(people, 1, 2); + * + * => last_two = [0x5678, 0x9abc] + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ t_list* list_slice(t_list* self, int start, int count); /** * @brief Retorna una nueva lista con los primeros n elementos, eliminando * del origen estos elementos. + * @param count: Cantidad máxima de elementos a tomar. + * @return Una nueva lista con los elementos tomados. Dichos elementos + * dejarán de pertenecer a la lista original. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * t_list* first_two = list_take_and_remove(people, 2); + * + * => first_two = [0x1234, 0x5678] + * => people = [0x9abc] + * @endcode */ t_list* list_take_and_remove(t_list* self, int count); /** * @brief Retorna una nueva lista con los primeros n elementos partiendo * desde el índice indicado, eliminando del origen estos elementos. + * @param start: Índice desde el cual se tomarán los elementos. + * @param count: Cantidad máxima de elementos a tomar. + * @return Una nueva lista con los elementos tomados. Dichos elementos + * dejarán de pertenecer a la lista original. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * t_list* last_two = list_slice_and_remove(people, 1, 2); + * + * => last_two = [0x5678, 0x9abc] + * => people = [0x1234] + * @endcode */ t_list* list_slice_and_remove(t_list* self, int start, int count); /** * @brief Retorna una nueva lista con los elementos que cumplen la condicion + * @return Los elementos de la lista retornada seguirán perteneciendo a la lista original. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * bool _has_e(void* ptr) { + * t_person* person = (t_person*) ptr; + * return string_contains(person->name, "e"); + * } + * t_list* with_e = list_filter(people, _has_e); + * + * => with_e = [0x1234, 0x9abc] + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ t_list* list_filter(t_list* self, bool(*condition)(void*)); /** * @brief Retorna una nueva lista con los elementos transformados + * @return Los elementos de la lista retornada seguirán perteneciendo a la lista original. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * void* _get_name(void* ptr) { + * t_person* person = (t_person*) ptr; + * return string_duplicate(person->name); + * } + * t_list* names = list_map(people, _get_name); + * + * => names = ["Lionel Messi", "Cristiano Ronaldo", "Neymar Jr."] + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ t_list* list_map(t_list* self, void*(*transformer)(void*)); /** * @brief Retorna una nueva lista con los elementos de la lista de listas - * recibida + * recibida. + * @return Los elementos de la lista retornada seguirán perteneciendo a las listas originales. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* america = list_create(); + * list_add(america, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(america, person_create("Neymar Jr.", 29)); // 0x5678 + * + * t_list* europe = list_create(); + * list_add(europe, person_create("Cristiano Ronaldo", 35)); // 0x9abc + * list_add(europe, person_create("Kylian Mbappé", 22)); // 0xdef0 + * + * t_list* continents = list_create(); + * list_add(continents, america); + * list_add(continents, europe); + * + * t_list* people = list_flatten(continents); + * + * => people = [0x1234, 0x5678, 0x9abc, 0xdef0] + * => continents = [[0x1234, 0x5678], [0x9abc, 0xdef0]] + * @endcode */ t_list* list_flatten(t_list* self); /** * @brief Coloca un elemento en una de la posiciones de la lista retornando * el valor anterior + * @param index: La posicion en la que se quiere agregar el elemento + * @param element: El elemento a agregar. Este elemento pasará a pertenecer + * a la lista, por lo que no debe ser liberado por fuera de ésta. + * @return El valor ubicado en la posición index antes de ser reemplazado. + * Dejará de pertenecer a la lista, por lo que debe ser liberado + * una vez que no se lo necesite. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * t_person* replaced = list_replace( + * people, 1, person_create("Kylian Mbappé", 22)); // 0xdef0 + * + * => replaced = 0x5678 + * => people = [0x1234, 0xdef0, 0x9abc] + * @endcode */ void *list_replace(t_list* self, int index, void* element); /** - * @brief Coloca un elemento en la posición de la lista - * en donde se encuentra el primer valor que haga que - * condition sea != 0, retornando el valor anterior. + * @brief Coloca un elemento en la posición de la lista que cumpla con la + * condición, retornando el valor anterior + * @param condition: Función que recibe un elemento y devuelve `true` si + * es el elemento a reemplazar. + * @param element: El elemento a agregar. Este elemento pasará a pertenecer + * a la lista, por lo que no debe ser liberado por fuera de ésta. + * @return El valor ubicado en la posición index antes de ser reemplazado, o NULL + * en caso de no encontrar ningún valor. + * Dejará de pertenecer a la lista, por lo que debe ser liberado + * una vez que no se lo necesite. * @relates t_list * - * @note En caso de no encontrar ningún valor, no realiza el - * reemplazo y retorna NULL. + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * bool _has_age_more_than_30(void* ptr) { + * t_person* person = (t_person*) ptr; + * return person->age > 30; + * } + * t_person* replaced = list_replace_by_condition( + * people, _has_age_more_than_30, person_create("Kylian Mbappé", 22)); // 0xdef0 + * + * => replaced = 0x1234 + * => people = [0xdef0, 0x5678, 0x9abc] + * @endcode */ void *list_replace_by_condition(t_list* self, bool(*condition)(void*), void* element); /** * @brief Coloca un valor en una de la posiciones de la lista liberando el * valor anterior + * @param index: La posicion en la que se quiere agregar el elemento + * @param element: El elemento a agregar. Este elemento pasará a pertenecer + * a la lista, por lo que no debe ser liberado por fuera de ésta. + * @param element_destroyer: Función que se encargará de liberar el valor + * reemplazado. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * list_replace_and_destroy_element( + * people, 1, person_create("Kylian Mbappé", 22), person_destroy); // 0xdef0 + * + * => people = [0x1234, 0xdef0, 0x9abc] + * @endcode */ void list_replace_and_destroy_element(t_list* self, int index, void* element, void(*element_destroyer)(void*)); /** * @brief Remueve un elemento de la lista de una determinada posicion y lo * retorna. + * @param index: La posicion del elemento a remover + * @return El elemento removido. Dejará de pertenecer a la lista, por lo que + * debe ser liberado una vez que no se lo necesite. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * t_person* removed = list_remove(people, 1); + * + * => removed = 0x5678 + * => people = [0x1234, 0x9abc] + * @endcode */ void *list_remove(t_list* self, int index); /** - * @brief Remueve al elemento de la lista recibido por parámetro. Devuelve - * false en caso de no haberlo encontrado. + * @brief Remueve al elemento de la lista recibido por parámetro. + * @param element: El elemento a remover. Al ser removido, ya estaremos seguros + * de que no pertenece a la lista, por lo que debe ser liberado + * una vez que no se lo necesite. + * @return `true` si el elemento fue removido, `false` en caso de no haber sido + * encontrado. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * t_person* messi = person_create("Lionel Messi", 33); // 0x1234 + * list_add(people, messi); + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * bool removed = list_remove_element(people, messi); + * + * => removed = true + * => people = [0x5678, 0x9abc] + * => messi = 0x1234 + * @endcode */ bool list_remove_element(t_list* self, void* element); /** * @brief Remueve un elemento de la lista de una determinada posicion y * libera la memoria. + * @param index: La posicion del elemento a remover + * @param element_destroyer: Función que se encargará de liberar el valor * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * list_remove_and_destroy_element(people, 1, person_destroy); + * + * => people = [0x1234, 0x9abc] + * @endcode */ void list_remove_and_destroy_element(t_list* self, int index, void(*element_destroyer)(void*)); /** * @brief Remueve el primer elemento de la lista que haga que condition - * devuelva != 0. + * devuelva `true`. + * @return El elemento removido. Dejará de pertenecer a la lista, por lo que + * debe ser liberado una vez que no se lo necesite. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * bool _has_a(void* ptr) { + * t_person* person = (t_person*) ptr; + * return string_contains(person->name, "a"); + * } + * t_person* removed = list_remove_by_condition(people, _has_a); + * + * => removed = 0x5678 + * => people = [0x1234, 0x9abc] + * @endcode */ void *list_remove_by_condition(t_list* self, bool(*condition)(void*)); /** - * @brief Remueve y destruye el primer elemento de la lista que haga que - * condition devuelva != 0. + * @brief Remueve y libera el primer elemento de la lista que haga que + * condition devuelva `true`. + * @param element_destroyer: Función que se encargará de liberar el valor * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * bool _has_a(void* ptr) { + * t_person* person = (t_person*) ptr; + * return string_contains(person->name, "a"); + * } + * list_remove_and_destroy_by_condition(people, _has_a, person_destroy); + * + * => people = [0x1234, 0x9abc] + * @endcode */ void list_remove_and_destroy_by_condition(t_list* self, bool(*condition)(void*), void(*element_destroyer)(void*)); /** * @brief Remueve y destruye todos los elementos de la lista que hagan que - * condition devuelva != 0. + * condition devuelva `true`. + * @param element_destroyer: Función que se encargará de liberar cada valor * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * bool _has_a(void* ptr) { + * t_person* person = (t_person*) ptr; + * return string_contains(person->name, "a"); + * } + * list_remove_and_destroy_all_by_condition(people, _has_a, person_destroy); + * + * => people = [0x1234] + * @endcode */ void list_remove_and_destroy_all_by_condition(t_list *self, bool(*condition)(void*), void(*element_destroyer)(void*)); /** - * @brief Quita todos los elementos de la lista. + * @brief Quita todos los elementos de la lista, sin liberarlos * @relates t_list + * + * Ejemplo de uso: + * @code + * t_person* messi = person_create("Lionel Messi", 33); // 0x1234 + * t_person* ronaldo = person_create("Cristiano Ronaldo", 35); // 0x5678 + * t_person* neymar = person_create("Neymar Jr.", 29); // 0x9abc + * + * t_list* people = list_create(); + * list_add(people, messi); + * list_add(people, ronaldo); + * list_add(people, neymar); + * + * list_clean(people); + * + * => people = [] + * => neymar = 0x9abc + * => ronaldo = 0x5678 + * => messi = 0x1234 + * @endcode */ void list_clean(t_list* self); /** - * @brief Quita y destruye todos los elementos de la lista + * @brief Quita todos los elementos de la lista y los libera llamando a la + * función `element_destroyer` sobre cada uno de ellos + * @note En caso de recibir una lista vacía, se comporta como list_clean(). * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); + * list_add(people, person_create("Cristiano Ronaldo", 35)); + * list_add(people, person_create("Neymar Jr.", 29)); + * + * list_clean_and_destroy_elements(people, person_destroy); + * + * => people = [] + * @endcode */ void list_clean_and_destroy_elements(t_list *self, void(*element_destroyer)(void*)); /** - * @brief Itera la lista llamando al closure por cada elemento + * @brief Itera la lista llamando al closure por cada elemento. En caso de + * querer modificar la lista durante la iteración, utilizar + * list_iterator_create() para recorrerla externamente. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); + * list_add(people, person_create("Cristiano Ronaldo", 35)); + * list_add(people, person_create("Neymar Jr.", 29)); + * + * void print_person(void* ptr) { + * t_person* person = (t_person*) ptr; + * printf("%s(%d)\n", person->name, person->age); + * } + * list_iterate(people, print_person); + * + * => Lionel Messi(33) + * Cristiano Ronaldo(35) + * Neymar Jr.(29) + * @endcode */ void list_iterate(t_list* self, void(*closure)(void*)); /** * @brief Retorna el primer valor encontrado, el cual haga que condition - * devuelva != 0 + * devuelva `true`, o NULL en caso de no encontrar ninguno. * @relates t_list + * + * Ejemplo de uso: + * @code + * t_person* find_by_name_contains(t_list* people, char* substring) { + * bool _name_contains(void* ptr) { + * t_person* person = (t_person*) ptr; + * return string_contains(person->name, substring); + * } + * return list_find(people, _name_contains); + * } + * + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * t_person* a = find_by_name_contains(people, "a"); + * t_person* x = find_by_name_contains(people, "x"); + * + * => a = 0x5678 + * => x = NULL + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ void *list_find(t_list* self, bool(*closure)(void*)); /** * @brief Retorna el tamaño de la lista * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * int size = list_size(people); + * + * => size = 3 + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ int list_size(t_list* self); /** * @brief Verifica si la lista esta vacia * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * bool is_empty = list_is_empty(people); + * + * => is_empty = true + * => people = [] + * @endcode */ bool list_is_empty(t_list* self); /** * @brief Ordena la lista segun el comparador + * @param comparator: Funcion que compara dos elementos. Debe devolver + * true si el primer parametro debe aparecer antes que el + * segundo en la lista * @relates t_list * - * @note El comparador devuelve si el primer parametro debe aparecer antes - * que el segundo en la lista + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * bool _has_age_less_than(void* a, void* b) { + * t_person* person_a = (t_person*) a; + * t_person* person_b = (t_person*) b; + * return person_a->age < person_b->age; + * } + * list_sort(people, _has_age_less_than); + * + * => people = [0x9abc, 0x1234, 0x5678] + * @endcode */ void list_sort(t_list* self, bool (*comparator)(void *, void *)); /** * @brief Retorna una lista nueva ordenada segun el comparador + * @param comparator: Funcion que compara dos elementos. Debe devolver + * true si el primer parametro debe aparecer antes que el + * segundo en la lista + * @return La lista ordenada. Los elementos de la lista retornada seguirán + * perteneciendo a la lista original. * @relates t_list * - * @note El comparador devuelve si el primer parametro debe aparecer antes - * que el segundo en la lista + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * bool _has_age_less_than(void* a, void* b) { + * t_person* person_a = (t_person*) a; + * t_person* person_b = (t_person*) b; + * return person_a->age < person_b->age; + * } + * t_list* sorted = list_sorted(people, _has_age_less_than); + * + * => sorted = [0x9abc, 0x1234, 0x5678] + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ t_list* list_sorted(t_list* self, bool (*comparator)(void *, void *)); /** - * @brief Cuenta la cantidad de elementos de la lista que cumplen una - * condición + * @brief Cuenta la cantidad de elementos de la lista que devuelven true + * al aplicarles la condición * @relates t_list + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * bool _has_a(void* ptr) { + * t_person* person = (t_person*) ptr; + * return string_contains(person->name, "a"); + * } + * int count = list_count_satisfying(people, _has_a); + * + * => count = 2 + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ int list_count_satisfying(t_list* self, bool(*condition)(void*)); /** - * @brief Determina si algún elemento de la lista cumple una condición + * @brief Determina si algún elemento de la lista devuelve true al aplicarle + * la condición * @relates t_list + * + * Ejemplo de uso: + * @code + * bool people_any_contains(t_list* self, char* substring) { + * bool _contains_substring(void* ptr) { + * t_person* person = (t_person*) ptr; + * return string_contains(person->name, substring); + * } + * return list_any_satisfy(self, _contains_substring); + * } + + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * bool has_a = people_any_contains(people, "a"); + * bool has_x = people_any_contains(people, "x"); + * + * => has_a = true + * => has_x = false + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ bool list_any_satisfy(t_list* self, bool(*condition)(void*)); /** - * @brief Determina si todos los elementos de la lista cumplen una condición + * @brief Determina si todos los elementos de la lista devuelven true al + * aplicarles la condición * @relates t_list + * + * Ejemplo de uso: + * @code + * bool people_all_have_age_greater_than(t_list* self, int age) { + * bool _has_age_greater_than(void* ptr) { + * t_person* person = (t_person*) ptr; + * return person->age > age; + * } + * return list_all_satisfy(self, _has_age_greater_than); + * } + * + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * bool all_greater_than_25 = people_all_have_age_greater_than(people, 25); + * bool all_greater_than_30 = people_all_have_age_greater_than(people, 30); + * + * => all_greater_than_25 = true + * => all_greater_than_30 = false + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ bool list_all_satisfy(t_list* self, bool(*condition)(void*)); /** * @brief Crea una lista nueva con los mismos elementos que la original. + * @return La lista duplicada. Los elementos de la lista retornada seguirán + * perteneciendo a la lista original. * @relates t_list - **/ + * + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * + * t_list* people_copy = list_duplicate(people); + * + * => people = [0x1234, 0x5678] + * => people_copy = [0x1234, 0x5678] + * @endcode + */ t_list* list_duplicate(t_list* self); /** * @brief Devuelve un valor que resulta de aplicar la operacion entre todos - * los elementos de la lista, tomando al primero como semilla y - * partiendo desde el segundo (si existe). + * los elementos de la lista, partiendo desde el primero. + * @param seed: Valor inicial para el primer parámetro de la operación. + * @param operation: Funcion que recibe dos valores: + * El primero es el resultado de la operación anterior + * y el segundo es el siguiente elemento de la lista. + * Debe devolver un valor del mismo tipo que el inicial. + * @return El resultado de aplicar la operación al último elemento de la lista. * @relates t_list * - * @note La funcion 'operation' debe recibir dos valores del tipo de los - * elementos de la lista. + * Ejemplo de uso: + * @code + * t_list* people = list_create(); + * list_add(people, person_create("Lionel Messi", 33)); // 0x1234 + * list_add(people, person_create("Cristiano Ronaldo", 35)); // 0x5678 + * list_add(people, person_create("Neymar Jr.", 29)); // 0x9abc + * + * void *_append_person(char* acc, void* ptr) { + * t_person* person = (t_person*) ptr; + * if (!string_is_empty(acc)) { + * string_append(&acc, ", "); + * } + * string_append_with_format(&acc, "%s(%d)", person->name, person->age); + * return acc; + * } + * char* str = list_fold(people, string_new(), _append_person); + * + * => str = "Lionel Messi(33), Cristiano Ronaldo(35), Neymar Jr.(29)" + * => people = [0x1234, 0x5678, 0x9abc] + * @endcode */ - void* list_fold1(t_list* self, void* (*operation)(void*, void*)); + void* list_fold(t_list* self, void* seed, void*(*operation)(void*, void*)); /** * @brief Devuelve un valor que resulta de aplicar la operacion entre todos - * los elementos de la lista, partiendo desde el primero. + * los elementos de la lista, tomando al primero como semilla y + * partiendo desde el segundo (si existe). + * @param operation: Funcion que recibe dos valores del tipo de los elementos + * de la lista y devuelve otro valor del mismo tipo. + * @return El resultado de aplicar la operación al último elemento de la lista. * @relates t_list * - * @note La funcion 'operation' debe recibir dos valores: uno del tipo del - * valor initial (seed) y otro del tipo de los elementos de la lista. + * Ejemplo de uso: + * @code + * t_list* names = list_create(); + * list_add(names, string_duplicate("Lionel Messi")); // 0x1234 + * list_add(names, string_duplicate("Cristiano Ronaldo")); // 0x5678 + * list_add(names, string_duplicate("Neymar Jr.")); // 0x9abc + * + * void* _longest_name(void* ptr1, void* ptr2) { + * char* name1 = (char*) ptr1; + * char* name2 = (char*) ptr2; + * return string_length(name1) > string_length(name2) ? name1 : name2; + * } + * char* longest_name = list_fold1(names, _longest_name); + * + * => longest_name = "Cristiano Ronaldo" + * => names = [0x1234, 0x5678, 0x9abc] + * @endcode */ - void* list_fold(t_list* self, void* seed, void*(*operation)(void*, void*)); + void* list_fold1(t_list* self, void* (*operation)(void*, void*)); /** - * @brief Inicializa una iteración externa de la lista + * @brief Inicializa una iteración externa de la lista. Es útil para recorrer + * la lista y modificarla al mismo tiempo. En caso de + * no querer modificar la lista, puede utilizarse list_iterate(). * @relates t_list_iterator + * + * Ejemplo de uso: + * @code + * t_list_iterator* iterator = list_iterator_create(list); + * while(list_iterator_has_next(iterator)) { + * void* element = list_iterator_next(iterator); + * // Hacer algo que requiera list_iterator_add() o list_iterator_remove() + * } + * list_iterator_destroy(iterator); + * @endcode */ t_list_iterator* list_iterator_create(t_list* list); @@ -333,6 +1068,9 @@ /** * @brief Avanza hacia el siguiente elemento a iterar de la lista y * lo devuelve + * @return El elemento actual de la iteración. Pertenecerá a la lista, + * por lo que no debe ser liberado por fuera de ésta a menos que + * se lo remueva con list_iterator_remove(). * @relates t_list_iterator */ void* list_iterator_next(t_list_iterator* iterator); @@ -346,19 +1084,24 @@ /** * @brief Agrega a la lista un elemento delante del actual y detrás * del siguiente. Luego, avanza hacia el elemento agregado. + * @param data: El elemento a agregar. Este elemento pasará a pertenecer + * a la lista, por lo que no debe ser liberado por fuera de ésta. * @relates t_list_iterator - */ + */ void list_iterator_add(t_list_iterator* iterator, void *data); /** * @brief Remueve de la lista al elemento actual de la iteración + * @note El elemento removido es el último devuelto por list_iterator_next() + * y dejará de pertenecer a la lista, por lo que debe ser liberado + * una vez que no se lo necesite. * @relates t_list_iterator */ void list_iterator_remove(t_list_iterator* iterator); /** - * @brief Finaliza la instancia de iteración externa liberando sus - * recursos + * @brief Finaliza la instancia de iteración externa liberando sus recursos + * @note Esta operación no libera la lista ni sus elementos. * @relates t_list_iterator */ void list_iterator_destroy(t_list_iterator* iterator); diff --git a/src/commons/collections/queue.h b/src/commons/collections/queue.h index ebf805b..5355993 100755 --- a/src/commons/collections/queue.h +++ b/src/commons/collections/queue.h @@ -28,13 +28,18 @@ } t_queue; /** - * @brief Crea y devuelve un puntero a una cola + * @brief Crea una cola + * @return Retorna un puntero a la cola creada, liberable con: + * - queue_destroy() si se quiere liberar la cola pero no + * los elementos que contiene. + * - queue_destroy_and_destroy_elements() si se quiere liberar + * la cola con los elementos que contiene. * @relates t_queue */ - t_queue *queue_create(); + t_queue *queue_create(void); /** - * @brief Destruye una cola. + * @brief Destruye una cola sin liberar los elementos que contiene * @relates t_queue */ void queue_destroy(t_queue *); @@ -48,30 +53,36 @@ /** * @brief Agrega un elemento al final de la cola + * @param element Elemento a agregar. Este elemento pasará a pertenecer + * a la cola, por lo que no debe ser liberado por fuera de ésta. * @relates t_queue */ void queue_push(t_queue *, void *element); /** * @brief quita el primer elemento de la cola + * @return El elemento extraído de la cola. Este elemento debe ser liberado + * una vez que se deje de usar. * @relates t_queue */ void *queue_pop(t_queue *); /** * @brief Devuelve el primer elemento de la cola sin extraerlo + * @return El primer elemento de la cola. Este elemento no debe ser liberado + * ya que seguirá perteneciendo a la cola. * @relates t_queue */ void *queue_peek(t_queue *); /** - * @brief Elimina todos los elementos de la cola. + * @brief Quita todos los elementos de la cola sin liberarlos * @relates t_queue */ void queue_clean(t_queue *); /** - * @brief Elimina y destruye todos los elementos de la cola. + * @brief Quita y libera todos los elementos de la cola. * @relates t_queue */ void queue_clean_and_destroy_elements(t_queue *, void(*element_destroyer)(void*)); diff --git a/src/commons/config.h b/src/commons/config.h index d670c01..c226880 100644 --- a/src/commons/config.h +++ b/src/commons/config.h @@ -30,11 +30,11 @@ /** * @brief Crea una estructura t_config - * @relates t_config - * * @param path Ruta hacia el archivo de configuracion * @return Retorna un puntero hacia la estructura creada, o NULL * en caso de no encontrar el archivo en el path especificado. + * Una vez que se deje de usar, se debe liberar con config_destroy(). + * @relates t_config */ t_config *config_create(char *path); @@ -46,6 +46,8 @@ /** * @brief Retorna un string con el valor asociado a key. + * @warning Devuelve un puntero perteneciente a la estructura t_config, por lo + * que no debe ser liberado por fuera de la misma. * @relates t_config */ char *config_get_string_value(t_config*, char *key); @@ -71,6 +73,8 @@ /** * @brief Retorna un array con los valores asociados a la key especificada. * @relates t_config + * @return Devuelve un array de strings terminado en NULL. Debe ser liberado + * con string_array_destroy() una vez que se deje de usar. * * @note En el archivo de configuracion un valor de este tipo debería ser representado * de la siguiente forma [lista_valores_separados_por_coma]. Ejemplo: @@ -78,8 +82,6 @@ * @code * VALORES=[1,2,3,4,5] * @endcode - * - * @note El array que devuelve termina en NULL */ char** config_get_array_value(t_config*, char* key); @@ -109,12 +111,14 @@ /** * @brief Reescribe el archivo de configuracion con los valores del config. + * @return Retorna mayor a 0 si se pudo guardar el archivo, -1 en caso de error. * @relates t_config */ int config_save(t_config*); /** * @brief Escribe un archivo de configuracion en el path indicado con los valores del config. + * @return Retorna mayor a 0 si se pudo guardar el archivo, -1 en caso de error. * @relates t_config */ int config_save_in_file(t_config*, char *path); diff --git a/src/commons/log.h b/src/commons/log.h index 4dd93ed..3f8ace2 100644 --- a/src/commons/log.h +++ b/src/commons/log.h @@ -49,12 +49,14 @@ * @param process_name: El nombre a ser mostrado en los logs * @param is_active_console: Si lo que se loguea debe mostrarse por consola * @param level: El nivel de detalle mínimo a loguear (ver definición de t_log_level) + * @return Retorna una instancia de logger, o NULL en caso de error. Debe ser + * liberada con log_destroy() * - * @note si file ya existe, se escribirá al final del archivo - * @note si file no existe, se creará un nuevo archivo en el directorio indicado - * @note si el directorio hacia file no existe, se producirá un error - * - * @return Retorna una instancia de logger, o NULL en caso de error + * @note Se debe tener en cuenta que: + * - si `file` es NULL, no se imprimirá en ningún archivo + * - si `file` ya existe, se escribirá al final del archivo + * - si `file` no existe, se creará un nuevo archivo en el directorio indicado + * - si el directorio hacia `file` no existe, se producirá un error */ t_log* log_create(char* file, char *process_name, bool is_active_console, t_log_level level); @@ -66,7 +68,7 @@ /** * @brief Loguea un mensaje con el siguiente formato - * [TRACE] hh:mm:ss:mmmm PROCESS_NAME/(PID:TID): MESSAGE + * `[TRACE] hh:mm:ss:mmmm PROCESS_NAME/(PID:TID): MESSAGE` * @relates t_log * */ @@ -74,7 +76,7 @@ /** * @brief Loguea un mensaje con el siguiente formato - * [DEBUG] hh:mm:ss:mmmm PROCESS_NAME/(PID:TID): MESSAGE + * `[DEBUG] hh:mm:ss:mmmm PROCESS_NAME/(PID:TID): MESSAGE` * @relates t_log * */ @@ -82,7 +84,7 @@ /** * @brief Loguea un mensaje con el siguiente formato - * [INFO] hh:mm:ss:mmmm PROCESS_NAME/(PID:TID): MESSAGE + * `[INFO] hh:mm:ss:mmmm PROCESS_NAME/(PID:TID): MESSAGE` * @relates t_log * */ @@ -90,7 +92,7 @@ /** * @brief Loguea un mensaje con el siguiente formato - * [WARNING] hh:mm:ss:mmmm PROCESS_NAME/(PID:TID): MESSAGE + * `[WARNING] hh:mm:ss:mmmm PROCESS_NAME/(PID:TID): MESSAGE` * @relates t_log * */ @@ -98,7 +100,7 @@ /** * @brief Loguea un mensaje con el siguiente formato - * [ERROR] hh:mm:ss:mmmm PROCESS_NAME/(PID:TID): MESSAGE + * `[ERROR] hh:mm:ss:mmmm PROCESS_NAME/(PID:TID): MESSAGE` * @relates t_log * */ diff --git a/src/commons/memory.h b/src/commons/memory.h index f20cc57..6058d11 100644 --- a/src/commons/memory.h +++ b/src/commons/memory.h @@ -34,6 +34,7 @@ /** * @brief Devuelve un dump hexadecimal en formato string de una porción de memoria dada + * @return Un string con el dump hexadecimal. Debe ser liberado con free() * @relates memory */ char *mem_hexstring(void *source, size_t length); diff --git a/src/commons/process.h b/src/commons/process.h index 2e4eec9..d075dc1 100644 --- a/src/commons/process.h +++ b/src/commons/process.h @@ -23,15 +23,15 @@ */ /** -* @brief Obtiene el ID del thread actual -* @relates process -*/ + * @brief Obtiene el ID del thread actual + * @relates process + */ unsigned int process_get_thread_id(); /** -* @brief Obtiene el ID del proceso actual -* @relates process -*/ + * @brief Obtiene el ID del proceso actual + * @relates process + */ unsigned int process_getpid(); #endif /* PROCESS_H_ */ diff --git a/src/commons/string.h b/src/commons/string.h index 83f9b81..51fd892 100644 --- a/src/commons/string.h +++ b/src/commons/string.h @@ -26,181 +26,321 @@ */ /** - * @brief Crea un string vacio - * @relates string - */ - char* string_new(); + * @brief Crea un string vacio + * @return El string retornado debe ser liberado con free() + * @relates string + */ + char* string_new(void); /** - * @brief Crea un string a partir de un numero - * @relates string - */ + * @brief Crea un string en formato decimal a partir de un número + * @param[in] number: Número entero a convertir + * @return El string retornado debe ser liberado con free() + * @relates string + * + * @code + * char* numero = string_itoa(123); + * + * => numero = "123" + * @endcode + */ char* string_itoa(int number); /** - * @brief Crea un nuevo string a partir de un formato especificado - * @relates string - * - * @code - * char* saludo = string_from_format("Hola %s", "mundo"); - * - * => saludo = "Hola mundo" - * @endcode - */ + * @brief Crea un nuevo string a partir de un formato especificado + * @param[in] format: Formato a aplicar, igual que en printf() + * @return El string retornado debe ser liberado con free() + * @relates string + * + * @code + * char* saludo = string_from_format("Hola %s", "mundo"); + * + * => saludo = "Hola mundo" + * @endcode + */ char* string_from_format(const char* format, ...) __attribute__((format(printf, 1, 2))); /** - * @brief Crea un nuevo string a partir de un formato especificado - * pasando un va_list con los argumentos - * @relates string - */ + * @brief Crea un nuevo string a partir de un formato especificado + * pasando un `va_list` con los argumentos + * @param[in] format: Formato a aplicar, igual que en vprintf() + * @param[in] arguments: Lista de argumentos a aplicar, igual que en vprintf() + * @return Retorna un string que debe ser liberado con free() + * @relates string + */ char* string_from_vformat(const char* format, va_list arguments); /** - * @brief Crea un string de longitud 'count' con el mismo caracter. - * @relates string - * - * @code - * string_repeat('a', 5) = "aaaaa" - * @endcode - */ + * @brief Crea un string de longitud `count` con el mismo caracter. + * @param[in] ch: Caracter a repetir + * @param[in] count: Cantidad de veces a repetir el caracter + * @return El string retornado debe ser liberado con free() + * @relates string + * + * @code + * string_repeat('a', 5) = "aaaaa" + * @endcode + */ char* string_repeat(char ch, int count); /** - * @brief Agrega al primer string el segundo - * @relates string - * - * @code - * char *unaPalabra = string_new(); - * string_append(&unaPalabra, "HOLA "); - * string_append(&unaPalabra, "PEPE"); - * - * => unaPalabra = "HOLA PEPE" - * @endcode - */ + * @brief Agrega al primer string el segundo + * @param[in,out] original: Puntero al string al que se le va a concatenar el + * segundo. Debe apuntar a un puntero liberable con free() + * @param[in] string_to_add: String a concatenar. Admite todo tipo de strings + * @relates string + * + * @code + * char *unaPalabra = string_new(); + * string_append(&unaPalabra, "HOLA "); + * string_append(&unaPalabra, "PEPE"); + * + * => unaPalabra = "HOLA PEPE" + * @endcode + */ void string_append(char ** original, char * string_to_add); /** - * @brief Agrega al primer string un máximo de n caracteres - * del segundo. - * @relates string - * - * @code - * char *unaPalabra = string_new(); - * string_n_append(&unaPalabra, "HOLA ", 10); - * string_n_append(&unaPalabra, "PEPE", 3); - * - * => unaPalabra = "HOLA PEP" - * @endcode - */ + * @brief Agrega al primer string un máximo de n caracteres del segundo. + * @param[in,out] original: Puntero al string a modificar. Debe apuntar a un + * string liberable con free() + * @param[in] string_to_add: String a concatenar. Admite todo tipo de strings + * @param[in] n: Cantidad máxima de caracteres a concatenar + * @relates string + * + * @code + * char *unaPalabra = string_new(); + * string_n_append(&unaPalabra, "HOLA ", 10); + * string_n_append(&unaPalabra, "PEPE", 3); + * + * => unaPalabra = "HOLA PEP" + * @endcode + */ void string_n_append(char** original, char* string_to_add, int n); /** - * @brief Concatena al primer string el resultado de aplicar los parametros - * al formato especificado - * @relates string - * - * @code - * char *saludo = "HOLA "; - * char *nombre = "PEPE"; - * - * string_append_with_format(&saludo, "%s!", nombre); - * - * => saludo = "HOLA PEPE!" - * @endcode - */ + * @brief Concatena al primer string el resultado de aplicar los parametros + * al formato especificado + * @param[in,out] original: Puntero al string a modificar. Debe apuntar a un + * string liberable con free() + * @param[in] format: Formato a aplicar, igual que en printf() + * @relates string + * + * @code + * char *saludo = "HOLA "; + * char *nombre = "PEPE"; + * + * string_append_with_format(&saludo, "%s!", nombre); + * + * => saludo = "HOLA PEPE!" + * @endcode + */ void string_append_with_format(char **original, const char *format, ...) __attribute__((format(printf, 2, 3))); /** * @brief Retorna una copia del string pasado como argumento + * @param[in] original: String a duplicar. Admite todo tipo de strings + * @return El string retornado debe ser liberado con free() * @relates string + * + * @code + * char* copia = string_duplicate("hola"); + * @endcode */ char* string_duplicate(char* original); /** * @brief Pone en mayuscula todos los caracteres de un string + * @param[in,out] text: String a modificar. Debe apuntar a cualquier porción de + * memoria modificable (en el stack o en el heap) * @relates string + * + * @code + * char* heap_string = string_duplicate("hola"); + * string_to_upper(heap_string); => "HOLA" + * + * char[] stack_string = "hola"; + * string_to_upper(stack_string); => "HOLA" + * + * char* literal_string = "hola"; + * string_to_upper(literal_string); => Error! + * @endcode */ void string_to_upper(char * text); /** * @brief Pone en minuscula todos los caracteres de un string + * @param[in,out] text: String a modificar. Debe apuntar a cualquier porción de + * memoria modificable (en el stack o en el heap) * @relates string + * + * @code + * char* heap_string = string_duplicate("HOLA"); + * string_to_lower(heap_string); => "hola" + * + * char[] stack_string = "HOLA"; + * string_to_lower(stack_string); => "hola" + * + * char* literal_string = "HOLA"; + * string_to_lower(literal_string); => Error! + * @endcode */ void string_to_lower(char * text); /** * @brief Capitaliza un string + * @param[in,out] text: String a modificar. Debe apuntar a cualquier porción de + * memoria modificable (en el stack o en el heap) * @relates string + * + * @code + * char* heap_string = string_duplicate("hola"); + * string_capitalized(heap_string); => "Hola" + * + * char[] stack_string = "hola"; + * string_capitalized(stack_string); => "Hola" + * + * char* literal_string = "hola"; + * string_capitalized(literal_string); => Error! + * @endcode */ void string_capitalized(char * text); /** * @brief Remueve todos los caracteres vacios de la derecha y la izquierda + * @param[in,out] text: Puntero al string a modificar. Debe apuntar a un string + * liberable con free() * @relates string + * + * @code + * char* heap_string = string_duplicate(" hola "); + * string_trim(&heap_string); => "hola" + * + * char[] stack_string = " mundo "; + * string_trim(&stack_string); => Error! + * @endcode */ void string_trim(char ** text); /** * @brief Remueve todos los caracteres vacios de la izquierda + * @param[in,out] text: Puntero al string a modificar. Debe apuntar a un string + * liberable con free() * @relates string + * + * @code + * char* heap_string = string_duplicate(" hola"); + * string_trim_left(&heap_string); => "hola" + * + * char[] stack_string = " mundo"; + * string_trim_left(&stack_string); => Error! + * @endcode */ void string_trim_left(char ** text); /** * @brief Remueve todos los caracteres vacios de la derecha + * @param[in,out] text: Puntero al string a modificar. Debe apuntar a un string + * liberable con free() * @relates string + * + * @code + * char* heap_string = string_duplicate("hola "); + * string_trim_right(&heap_string); => "hola" + * + * char[] stack_string = "mundo "; + * string_trim_right(&stack_string); => Error! + * @endcode */ void string_trim_right(char ** text); /** * @brief Retorna la longitud del string + * @param[in] text: String a medir. Admite todo tipo de strings * @relates string + * + * @code + * string_length("hola") => 4 + * @endcode */ int string_length(char * text); /** * @brief Retorna si un string es "" + * @param[in] text: String a evaluar. Admite todo tipo de strings * @relates string + * + * @code + * string_is_empty("hola") => false + * string_is_empty("") => true + * @endcode */ bool string_is_empty(char * text); /** - * @brief Retorna un boolean que indica si un string comienza con el string - * pasado por parametro + * @brief Retorna un boolean que indica si el string `text` comienza con el + * string `begin` pasado por parametro + * @param[in] text: String a evaluar. Admite todo tipo de strings + * @param[in] begin: String a buscar. Admite todo tipo de strings * @relates string + * + * @code + * string_starts_with("hola mundo", "hola") => true + * string_starts_with("hola", "hola mundo") => false + * @endcode */ bool string_starts_with(char * text, char * begin); /** - * @brief Retorna un boolean que indica si un string finaliza con el string - * pasado por parametro + * @brief Retorna un boolean que indica si el string `text` finaliza con el + * string `end` pasado por parametro + * @param[in] text: String a evaluar. Admite todo tipo de strings + * @param[in] end: String a buscar. Admite todo tipo de strings * @relates string + * + * @code + * string_ends_with("hola mundo", "mundo") => true + * string_ends_with("mundo", "hola mundo") => false + * @endcode */ bool string_ends_with(char* text, char* end); /** * @brief Retorna si dos strings son iguales ignorando las mayusculas y * minusculas + * @param[in] actual: String a comparar. Admite todo tipo de strings + * @param[in] expected: String a comparar. Admite todo tipo de strings * @relates string + * + * @code + * string_equals_ignore_case("hola", "hola") => true + * string_equals_ignore_case("hola", "HOLA") => true + * string_equals_ignore_case("hola", "mundo") => false + * @endcode */ bool string_equals_ignore_case(char * actual, char * expected); /** * @brief Separa un string dado un separador + * @param[in] text: String a separar. Admite todo tipo de strings + * @param[in] separator: Separador a utilizar. Admite todo tipo de strings + * @return Retorna un array con cada palabra y en la última posición un NULL. + * Debe ser liberado con string_array_destroy() * @relates string * - * @return Retorna un array con cada palabra y en la última posición un NULL - * * @code - * string_split("hola, mundo", ",") => ["hola", " mundo", NULL] + * string_split("hola, mundo", ",") => {"hola", " mundo", NULL} * @endcode */ char** string_split(char * text, char * separator); - /** * @brief Separa un string tantas veces por su separador como n lo permita + * @param[in] text: String a separar. Admite todo tipo de strings + * @param[in] n: Cantidad máxima de veces que se puede separar + * @param[in] separator: String separador a utilizar. Admite todo tipo de strings + * @return Retorna un array de copias de los caracteres en text y en la última + * posición un NULL. Debe ser liberado con string_array_destroy() * @relates string * * @code @@ -212,47 +352,71 @@ char** string_n_split(char* text, int n, char* separator); /** - * @brief Retorna los length caracteres de text empezando en start - * en un nuevo string - * @relates string - */ + * @brief Retorna los length caracteres de text empezando en start + * en un nuevo string + * @param[in] text: String a partir del cual se obtiene el substring. Admite todo + * tipo de strings + * @param[in] start: Indice desde el cual se obtiene el substring + * @param[in] length: Cantidad de caracteres a obtener + * @return Retorna un nuevo string que debe ser liberado con free() + * @relates string + * + * @code + * string_substring("hola, mundo, bueno", 0, 4) => "hola" + * string_substring("hola, mundo, bueno", 7, 5) => "mundo" + * string_n_split("hola, mundo, bueno", 1, 3) => "ola" + * @endcode + */ char* string_substring(char* text, int start, int length); /** - * @brief Retorna el substring de text desde el indice start hasta - * el último de la palabra - * @relates string - */ + * @brief Retorna el substring de text desde el indice start hasta + * el último de la palabra + * @param[in] text: String a partir del cual se obtiene el substring. Admite todo + * tipo de strings + * @param[in] start: Indice desde el cual se obtiene el substring + * @return Retorna un nuevo string que debe ser liberado con free() + * @relates string + */ char* string_substring_from(char *text, int start); /** - * @brief Retorna los primeros length caracteres de text como un nuevo string - * @relates string - */ + * @brief Retorna los primeros length caracteres de text como un nuevo string + * @param[in] text: String a partir del cual se obtiene el substring. Admite todo + * tipo de strings + * @param[in] length: Cantidad de caracteres a obtener + * @return Retorna un nuevo string que debe ser liberado con free() + * @relates string + */ char* string_substring_until(char *text, int length); /** - * @brief Itera un array de strings aplicando - * el closure a cada string, hasta que encuentre un NULL - * @relates string - */ + * @brief Itera un array de strings y aplica la función closure a cada uno + * @param[in] strings: Array de strings a iterar + * @param[in] closure: Función a aplicar a cada string + * @relates string + */ void string_iterate_lines(char ** strings, void (*closure)(char *)); /** - * @brief Retorna una array separando los elementos - * de un string con formato de array - * @relates string - * - * @code - * char* array_string = "[1,2,3,4]" - * string_get_value_as_array(array_string) => ["1","2","3","4",NULL] - * @endcode - */ + * @brief Retorna un array de strings a partir de un string formateado como array + * @param[in] text: String a convertir. Admite todo tipo de strings + * @return Retorna un array de copias de los caracteres en text y en la última + * posición un NULL. Debe ser liberado con string_array_destroy() + * @relates string + * + * @code + * char* array_string = "[1,2,3,4]" + * string_get_value_as_array(array_string) => {"1", "2", "3", "4", NULL} + * @endcode + */ char** string_get_string_as_array(char* text); /** * @brief Retorna el texto invertido. No se maneja el caso de NULL, * si se pasa NULL su comportamiento no esta determinado. + * @param[in] text: String a invertir. Admite todo tipo de strings + * @return Retorna un nuevo string que debe ser liberado con free() * @relates string * * @code @@ -263,66 +427,100 @@ char* string_reverse(char* text); /** - * @brief Retorna una copia de un string con todas las ocurrencias - * de un substring no vacío siendo reemplazadas por otro string. - * @relates string - * - * @code - * char* original = "hello"; - * string_replace(original, "ello", "ola") => "hola" - * string_replace(original, "l", ""); => "heo" - * string_replace(original, "not a substring", "yay!"); => "hello" - * @endcode - */ + * @brief Retorna una copia de un string con todas las ocurrencias + * de un substring no vacío siendo reemplazadas por otro string. + * @param[in] text: String a modificar. Admite todo tipo de strings + * @param[in] substring: Substring a reemplazar. Admite todo tipo de strings + * @param[in] replacement: String a insertar. Admite todo tipo de strings + * @return Retorna un nuevo string que debe ser liberado con free() + * @relates string + * + * @code + * char* original = "hello"; + * string_replace(original, "ello", "ola") => "hola" + * string_replace(original, "l", ""); => "heo" + * string_replace(original, "not a substring", "yay!"); => "hello" + * @endcode + */ char* string_replace(char* text, char* substring, char* replacement); /** - * @brief Retorna un boolean que indica si text contiene o no - * a substring. + * @brief Retorna un boolean que indica si text contiene o no a substring. + * @param[in] text: String a evaluar. Admite todo tipo de strings + * @param[in] substring: Substring a buscar. Admite todo tipo de strings * @relates string */ bool string_contains(char* text, char *substring); + /** + * @struct string_array + * @brief Funciones para manipulación de arrays de strings. + */ + /** * @brief Crea un array de strings vacio - * @relates string + * @return El array retornado debe ser liberado con string_array_destroy() + * @relates string_array */ char** string_array_new(); /** * @brief Destruye un array con sus strings - * @relates string + * @param[in,out] array: Puntero al array a destruir. Debe apuntar a un array + * de strings liberables con free() y terminado en NULL + * @relates string_array */ void string_array_destroy(char** array); /** * @brief Retorna la cantidad de líneas del array de strings - * @relates string + * @param[in] array: Array de strings terminado en NULL + * @relates string_array */ int string_array_size(char** array); /** * @brief Verifica si el array de strings está vacío - * @relates string + * @param[in] array: Array de strings terminado en NULL + * @relates string_array */ bool string_array_is_empty(char** array); /** * @brief Agrega un string al final del array - * @relates string + * @param[in,out] array: Puntero al array a modificar. Debe apuntar a un array + * de strings modificable y terminado en NULL + * @param[in] text: String a agregar. Debe ser liberable con free(), pero pasa + * a formar parte del array, por lo que no debe ser liberado + * @relates string_array + * + * @code + * char** array = string_array_new(); => {NULL} + * string_array_push(&array, "hola"); => {"hola", NULL} + * string_array_push(&array, "mundo"); => {"hola", "mundo", NULL} + * @endcode */ void string_array_push(char*** array, char* text); /** - * @brief Reemplaza un string en un array por otro, retornando - * el anterior - * @relates string + * @brief Reemplaza un string en un array por otro + * @param[in,out] array: Array a modificar. Debe apuntar a un array de strings + * terminado en NULL + * @param[in] pos: Posición del string a reemplazar + * @param[in] text: Nuevo string a insertar. Debe ser liberable con free(), pero + * pasa a formar parte del array, por lo que no debe ser liberado + * @return El string reemplazado. Debe ser liberado con free() + * @relates string_array */ char* string_array_replace(char** array, int pos, char* text); /** * @brief Quita el último string del array y lo retorna - * @relates string + * @param[in,out] array: Array a modificar. Debe apuntar a un array de strings + * terminado en NULL + * @return El string quitado. Deja de pertenecer al array, por lo que debe ser + * liberado con free() + * @relates string_array */ char* string_array_pop(char** array); diff --git a/src/commons/temporal.h b/src/commons/temporal.h index 2bc1e44..17c0f20 100644 --- a/src/commons/temporal.h +++ b/src/commons/temporal.h @@ -29,9 +29,9 @@ } t_temporal_status; /** - * @struct t_temporal - * @brief Manejo de tiempo con cronómetro - */ + * @struct t_temporal + * @brief Manejo de tiempo con cronómetro + */ typedef struct { struct timespec current; int64_t elapsed_ms; @@ -39,11 +39,10 @@ } t_temporal; /** - * @brief Retorna un string con la hora actual, con el formato recibido por - * parámetro. + * @brief Retorna un string con la hora actual con el formato recibido por parámetro. + * @return El string retornado debe ser liberado con free() al dejar de usarse. * @relates t_temporal * - * * @code * temporal_get_string_time("%d/%m/%y") => "30/09/20" * temporal_get_string_time("%H:%M:%S:%MS") => "12:51:59:331" @@ -54,50 +53,46 @@ /** * @brief Crea una variable temporal e inicia su cronómetro. + * @return La variable temporal creada debe ser liberada con temporal_destroy(). * @relates t_temporal */ t_temporal* temporal_create(void); /** * @brief Destruye una variable temporal. - * @relates t_temporal - * * @param temporal: Variable temporal a destruir. + * @relates t_temporal */ void temporal_destroy(t_temporal* temporal); /** * @brief Retorna el tiempo total transcurrido mientras el cronómetro estuvo * activo en milisegundos. - * @relates t_temporal - * * @param temporal: Variable temporal. + * @relates t_temporal */ int64_t temporal_gettime(t_temporal* temporal); /** * @brief Detiene el cronómetro de una variable temporal. - * @relates t_temporal - * * @param temporal: Variable temporal a frenar. + * @relates t_temporal */ void temporal_stop(t_temporal* temporal); /** * @brief Reanuda el cronómetro de una variable temporal. - * @relates t_temporal - * * @param temporal: Variable temporal a reanudar. + * @relates t_temporal */ void temporal_resume(t_temporal* temporal); /** * @brief Retorna la diferencia del tiempo total transcurrido entre dos * variables temporales en milisegundos - * @relates t_temporal - * * @param temporal_1: Primera variable temporal. * @param temporal_2: Segunda variable temporal. + * @relates t_temporal */ int64_t temporal_diff(t_temporal* temporal_1, t_temporal* temporal_2); diff --git a/src/commons/txt.h b/src/commons/txt.h index e43fe44..317b90b 100644 --- a/src/commons/txt.h +++ b/src/commons/txt.h @@ -23,6 +23,7 @@ /** * @brief Abre un archivo para agregarle contenido al final +* @note El mismo se debe cerrar con txt_close_file() */ FILE* txt_open_for_append(char* path);