.. SPDX-FileCopyrightText: 1992-2026 NWO-I/SRON Space Research Organisation Netherlands .. .. SPDX-License-Identifier: CC-BY-4.0 Dynamic String Lists (lists) ============================== **Module**: ``utils_list`` Overview -------- Provides a linked list implementation for managing collections of character strings. Useful for building dynamic lists of filenames, commands, or other text data. Key Features ------------ - Dynamic memory allocation for list elements - Linked list implementation for efficient insertion - Fixed maximum string length (80 characters) - Simple API for common list operations API Reference ------------- Types ~~~~~ **list_element** Individual element of the linked list: .. list-table:: :widths: 20 30 50 :header-rows: 1 * - Component - Type - Description * - ``list_entry`` - character(len=80) - The string data (max 80 chars) * - ``next_entry`` - type(list_element), pointer - Pointer to next element in list **list** The main list container: .. list-table:: :widths: 20 30 50 :header-rows: 1 * - Component - Type - Description * - ``head`` - type(list_element), pointer - First element of the list * - ``nelements`` - integer - Number of elements in list * - ``maxl`` - integer - Maximum string length (80) Methods ~~~~~~~ **append** .. function:: list%append(string) Add a string to the end of the list :param string: Character string to add (character(*)) :return: None Allocates memory for new element and appends to list. **get** .. function:: list%get(elem, string) Retrieve a string from the list :param elem: Element index (1-based) (integer) :param string: Output string (character(len=80)) :return: None Returns the string at position elem. Stops if elem > nelements. **tail** .. function:: list%tail(lend) Get pointer to last element :param lend: Output pointer to last element :return: None Used internally for append operations. **final** .. function:: list%final() Clean up and deallocate list :return: None Deallocates all list elements and resets counters. Usage Examples -------------- **Basic List Operations** .. code-block:: fortran use utils_list type(list) :: my_list character(len=80) :: retrieved_string integer :: i ! Add items to the list call my_list%append('file1.fits') call my_list%append('file2.fits') call my_list%append('file3.fits') write(*,*) 'List contains ', my_list%nelements, ' elements' ! Retrieve items do i = 1, my_list%nelements call my_list%get(i, retrieved_string) write(*,*) 'Element ', i, ': ', trim(retrieved_string) enddo **File Processing Example** .. code-block:: fortran use utils_list use utils_files type(list) :: file_list type(files) :: file_handler character(len=80) :: filename integer :: i, status, file_type, file_status ! Build list of files to process call file_list%append('data1.fits') call file_list%append('data2.fits') call file_list%append('data3.fits') ! Process each file do i = 1, file_list%nelements call file_list%get(i, filename) ! Open file with proper parameters file_type = 1 ! Type of file file_status = 1 ! Status: 1=old (existing file) call file_handler%open(trim(filename), '', file_type, file_status, status) if (status == 0) then ! Process file... call file_handler%close(status) endif enddo **Command History Example** .. code-block:: fortran use utils_list type(list) :: command_history character(len=80) :: command, retrieved_cmd integer :: i ! Simulate command history call command_history%append('data file.spo') call command_history%append('comp po') call command_history%append('fit') ! Display recent commands write(*,*) 'Command history:' do i = 1, command_history%nelements call command_history%get(i, retrieved_cmd) write(*,*) i, ': ', trim(retrieved_cmd) enddo **Cleanup Example** .. code-block:: fortran use utils_list type(list) :: temp_list ! Use the list... call temp_list%append('temporary data') ! Clean up when done call temp_list%final() write(*,*) 'List cleaned up, nelements = ', temp_list%nelements Notes ----- **Memory Management** - List automatically allocates memory for new elements - Always call ``final()`` when done to prevent memory leaks - Each element allocation increases ``nelements`` counter **Limitations** - Fixed maximum string length (80 characters) - No automatic resizing of strings - No built-in sorting or searching - Stops execution on errors (no graceful error handling) **Performance Considerations** - O(n) for get operations (linear search) - O(1) for append operations - Memory overhead per element: ~80 bytes + pointer - Not suitable for very large lists (>10,000 elements) **Error Handling** - Stops execution if string exceeds maximum length - Stops execution if accessing beyond list bounds - Consider wrapping in error handling for production use **Best Practices** 1. Always call ``final()`` when done with a list 2. Check string lengths before adding to list 3. Use ``trim()`` when retrieving strings 4. For large datasets, consider arrays instead 5. Document list contents for maintainability See Also -------- - :doc:`../core/memory` - Alternative memory management approaches - :doc:`../utils/strings` - String processing utilities - :doc:`../io/files` - File operations for list contents