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:

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:

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

list%append(string)

Add a string to the end of the list

Parameters:

string – Character string to add (character(*))

Returns:

None

Allocates memory for new element and appends to list.

get

list%get(elem, string)

Retrieve a string from the list

Parameters:
  • elem – Element index (1-based) (integer)

  • string – Output string (character(len=80))

Returns:

None

Returns the string at position elem. Stops if elem > nelements.

tail

list%tail(lend)

Get pointer to last element

Parameters:

lend – Output pointer to last element

Returns:

None

Used internally for append operations.

final

list%final()

Clean up and deallocate list

Returns:

None

Deallocates all list elements and resets counters.

Usage Examples

Basic List Operations

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

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

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

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

  • ../core/memory - Alternative memory management approaches

  • ../utils/strings - String processing utilities

  • File Operations (files) - File operations for list contents