{"id":25854781,"url":"https://github.com/jchristopherson/fcore","last_synced_at":"2025-03-01T16:18:09.497Z","repository":{"id":49055384,"uuid":"270711999","full_name":"jchristopherson/fcore","owner":"jchristopherson","description":"A Fortran library containing string handling, i/o routines, etc.","archived":false,"fork":false,"pushed_at":"2021-07-22T14:43:29.000Z","size":1218,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-03-01T15:41:03.394Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Fortran","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jchristopherson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-08T15:04:00.000Z","updated_at":"2022-04-02T11:06:58.000Z","dependencies_parsed_at":"2022-07-25T05:30:04.957Z","dependency_job_id":null,"html_url":"https://github.com/jchristopherson/fcore","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristopherson%2Ffcore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristopherson%2Ffcore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristopherson%2Ffcore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristopherson%2Ffcore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jchristopherson","download_url":"https://codeload.github.com/jchristopherson/fcore/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241389134,"owners_count":19955107,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-01T16:18:08.695Z","updated_at":"2025-03-01T16:18:09.471Z","avatar_url":"https://github.com/jchristopherson.png","language":"Fortran","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fcore\nA Fortran library containing string handling, i/o routines, etc.\n\n## String Handling Example\nThe following example illustrates some of the string handling abilities within the library.\n```fortran\nprogram main\n    use iso_fortran_env\n    use strings\n    use regular_expressions\n    implicit none\n\n    ! Local Variables\n    integer(int32) :: i\n    type(string) :: str1, strUp, strDn\n    type(string), allocatable :: matches(:)\n\n    ! Create a simple string\n    str1 = \"This is an example string containing letters and numbers: 1.2345\"\n    print '(A)', \"Example String 1: \" // str1%str\n    print '(AI0)', \"String Length: \", str1%length()\n    \n    ! Convert to all upper case\n    strUp = str1%to_upper()\n    print '(A)', \"Converted to upper case: \" // strUp%str\n\n    ! Convert to all lower case\n    strDn = str1%to_lower()\n    print '(A)', \"Converted to lower case: \" // strDn%str\n\n    ! Look for numeric values using regular expressions\n    matches = regex_search(str1%str, \"\\d.+\")\n    print '(AI0A)', \"Found \", size(matches), \" matches\"\n    do i = 1, size(matches)\n        print '(AI0A)', \"Match \", i, \": \" // matches(i)%str\n    end do\nend program\n```\nThe output of the above program is as follows.\n```text\nExample String 1: This is an example string containing letters and numbers: 1.2345\nString Length: 64\nConverted to upper case: THIS IS AN EXAMPLE STRING CONTAINING LETTERS AND NUMBERS: 1.2345\nConverted to lower case: this is an example string containing letters and numbers: 1.2345\nFound 1 matches\nMatch 1: 1.2345\n```\n\n## Text I/O Example\nThe following example illustrates some of the text file read/write functionallity within the library.\n```fortran\nprogram main\n    use file_io\n    implicit none\n\n    ! Parameters\n    character(len = *), parameter :: fname = \"test_text_file.txt\"\n\n    ! Local Variables\n    type(text_writer) :: writer\n    type(text_reader) :: reader\n    character(len = :), allocatable :: buffer\n\n    ! Let's write a file by first opening a file object to write to\n    call writer%open(fname)\n    \n    ! Write some stuff (line-by-line)\n    call writer%write_line(\"This is line 1.\")\n    call writer%write_line(\"This is line 2.\")\n    call writer%write_line(\"This,is,a,comma,delimited,string.\")\n\n    ! Write without advancing to the next line\n    call writer%write(\"Just trying to write without advancing lines. \")\n    call writer%write(\"Here's some more text. \")\n    call writer%write_line(\"Here's the end of the line.\")\n\n    ! Close the file.  The object's finalizer would normally take care of this\n    ! action, but the intent here is to use this file again before the writer\n    ! object would be cleaned up; therefore, it's worth manually closing the\n    ! file.\n    call writer%close()\n\n    ! Read in the file by first opening it for reading.\n    call reader%open(fname)\n\n    ! Read in lines, and print them\n    print '(A)', reader%read_line()\n    print '(A)', reader%read_line()\n    print '(A)', reader%read_line()\n    print '(A)', reader%read_line()\n\n    ! Close the file\n    call reader%close()\n\n    ! Alternatively, a more efficient means of reading the file would be to\n    ! read in the entire contents into a single string.  The string could then\n    ! be manipulated as desired.  This can be accomplished as follows.\n    call reader%open(fname)\n    buffer = reader%read_all()\n    print '(A)', buffer\n\n    ! This time we'll delete the file as part of the close operation\n    call reader%close(.true.)\nend program\n```\nThe output of the above program is as follows.\n```text\nThis is line 1.\nThis is line 2.\nThis,is,a,comma,delimited,string.\nJust trying to write without advancing lines. Here's some more text. Here's the end of the line.\nThis is line 1.\nThis is line 2.\nThis,is,a,comma,delimited,string.\nJust trying to write without advancing lines. Here's some more text. Here's the end of the line.\n```\n\n## File System Example\nThe following example illustrates some of the file system operations available in this library.\n```fortran\nprogram main\n    use iso_fortran_env\n    use file_io\n    use strings\n    implicit none\n\n    ! Local Variables\n    integer(int32) :: i\n    character(len = 256) :: cwd\n    type(folder_contents) :: contents\n    type(string), allocatable :: textFiles(:)\n    type(file_path) :: path\n\n    ! Get the current working directory\n    call getcwd(cwd)\n    print '(A)', \"Working Directory: \" // trim(cwd)\n\n    ! Obtain a list of the directory contents\n    contents = get_folder_contents(trim(cwd))\n    print '(AI0)', \"Folder Count: \", size(contents%folders)\n    print '(AI0)', \"File Count: \", size(contents%files)\n\n    ! Print out all folders\n    if (size(contents%folders) \u003e 0) print '(A)', new_line('a') // \"Folders: \"\n    do i = 1, size(contents%folders)\n        print '(AI0A)', \"Folder \", i, \": \" // contents%folders(i)%str\n    end do\n\n    ! Print out all files\n    if (size(contents%files) \u003e 0) print '(A)', new_line('a') // \"Files: \"\n    do i = 1, size(contents%files)\n        print '(AI0A)', \"File \", i, \": \" // contents%files(i)%str\n    end do\n\n    ! Get a list of all text files within the directory and any sub-folders.\n    ! Searching the sub-folders requires us to tell the routine (.true. \n    ! argument) as the default is to not search sub-folders.\n    textFiles = find_all_files(trim(cwd), \".txt\", .true.)\n    print '(AI0A)', new_line('a') // \"Found \", size(textFiles), \" text files.\"\n    do i = 1, size(textFiles)\n        print '(AI0A)', \"File: \", i, \": \" // textFiles(i)%str\n    end do\n\n    ! Split up the path into drive, filename, path, and extension\n    path = split_path(textFiles(1)%str)\n    print '(A)', new_line('a') // \"Path Splitting:\"\n    print '(A)', \"Drive: \" // path%drive\n    print '(A)', \"Directory: \" // path%directory\n    print '(A)', \"Filename: \" // path%filename\n    print '(A)', \"Extension: \" // path%extension\nend program\n```\nThe output of the above program is as follows.  Notice, the file paths have been altered as my personal directory structure is not relevant for the purposes of this example.\n```text\nWorking Directory: C:\\~\\Documents\\github\\fcore\nFolder Count: 9\nFile Count: 6\n\nFolders:\nFolder 1: C:\\~\\Documents\\github\\fcore\\.git\nFolder 2: C:\\~\\Documents\\github\\fcore\\.vscode\nFolder 3: C:\\~\\Documents\\github\\fcore\\bin\nFolder 4: C:\\~\\Documents\\github\\fcore\\build\nFolder 5: C:\\~\\Documents\\github\\fcore\\examples\nFolder 6: C:\\~\\Documents\\github\\fcore\\include\nFolder 7: C:\\~\\Documents\\github\\fcore\\lib\nFolder 8: C:\\~\\Documents\\github\\fcore\\src\nFolder 9: C:\\~\\Documents\\github\\fcore\\tests\n\nFiles:\nFile 1: C:\\~\\Documents\\github\\fcore\\.gitignore\nFile 2: C:\\~\\Documents\\github\\fcore\\.travis.yml\nFile 3: C:\\~\\Documents\\github\\fcore\\CMakeLists.txt\nFile 4: C:\\~\\Documents\\github\\fcore\\fcoreConfig.cmake.in\nFile 5: C:\\~\\Documents\\github\\fcore\\LICENSE\nFile 6: C:\\~\\Documents\\github\\fcore\\README.md\n\nFound 13 text files.\nFile: 1: C:\\~\\Documents\\github\\fcore\\CMakeLists.txt\nFile: 2: C:\\~\\Documents\\github\\fcore\\build\\CMakeCache.txt\nFile: 3: C:\\~\\Documents\\github\\fcore\\build\\CMakeFiles\\CMakeRuleHashes.txt\nFile: 4: C:\\~\\Documents\\github\\fcore\\build\\CMakeFiles\\TargetDirectories.txt\nFile: 5: C:\\~\\Documents\\github\\fcore\\build\\examples\\CMakeFiles\\folder_ops_example.dir\\link.txt\nFile: 6: C:\\~\\Documents\\github\\fcore\\build\\examples\\CMakeFiles\\strings_example.dir\\link.txt\nFile: 7: C:\\~\\Documents\\github\\fcore\\build\\examples\\CMakeFiles\\text_io_example.dir\\link.txt\nFile: 8: C:\\~\\Documents\\github\\fcore\\build\\src\\CMakeFiles\\fcore.dir\\link.txt\nFile: 9: C:\\~\\Documents\\github\\fcore\\build\\tests\\test_text_1.txt\nFile: 10: C:\\~\\Documents\\github\\fcore\\build\\tests\\CMakeFiles\\fcore_tests.dir\\link.txt\nFile: 11: C:\\~\\Documents\\github\\fcore\\examples\\CMakeLists.txt\nFile: 12: C:\\~\\Documents\\github\\fcore\\src\\CMakeLists.txt\nFile: 13: C:\\~\\Documents\\github\\fcore\\tests\\CMakeLists.txt\n\nPath Splitting:\nDrive: C:\nDirectory: \\~\\Documents\\github\\fcore\\\nFilename: CMakeLists\nExtension: .txt\n```\n\n## Dialog Example\nThe following example illustrates how to interact with the user with OS-specific dialog boxes.\n```fortran\nprogram main\n    use ui_dialogs\n    implicit none\n\n    ! Local Variables\n    logical :: check\n    type(dialog_result) :: mbox\n    type(text_output_dialog_result) :: openfile, savefile, folder\n    type(file_filter) :: filters(2)\n\n    ! Initialize the UI environment\n    check = initialize_ui_environment()\n    if (.not.check) then\n        print '(A)', \"Could not initialize the UI environement.  Good bye.\"\n        return\n    end if\n\n    ! Show the user a message box\n    mbox = show_message_box(\"Testing...\", \"Example\", MSGBX_BTN_OK_CANCEL, \u0026\n        MSGBX_ICON_INFORMATION)\n    if (mbox%result == DIALOG_RESULT_OK) then\n        print '(A)', \"The user pressed OK.\"\n    else if (mbox%result == DIALOG_RESULT_CANCEL) then\n        print '(A)', \"The user pressed Cancel.\"\n    else\n        print '(AI0A)', \"The user pressed an unknown button with result: \", \u0026\n            mbox%result, \".\"\n    end if\n\n    ! Set up file filters\n    filters(1)%name = \"Text Files (*.txt)\"\n    filters(1)%pattern = \"*.txt\"\n\n    filters(2)%name = \"All Files (*.*)\"\n    filters(2)%pattern = \"*.*\"\n\n    ! Open an file\n    openfile = show_open_file_dialog(filters)\n    if (openfile%result == DIALOG_RESULT_OK) then\n        print '(A)', \"The user selected file: \" // openfile%string_list(1)%str\n    end if\n\n    ! Save a file\n    savefile = show_save_file_dialog(\"txt\", filters)\n    if (savefile%result == DIALOG_RESULT_OK) then\n        print '(A)', \"The user wishes to save file: \" // \u0026\n            savefile%string_list(1)%str\n    end if\n\n    ! Locate a directory\n    folder = show_browse_folder_dialog()\n    if (folder%result == DIALOG_RESULT_OK) then\n        print '(A)', \"Selected Folder: \" // folder%string_list(1)%str\n    end if\n\n    ! Be sure to clean up\n    call clean_up_ui_environment()\nend program\n```\nThe dialogs shown appear as follows on a Windows machine.\n![](images/message_box.PNG?raw=true)\n![](images/open_file_dialog.PNG?raw=true)\n![](images/save_file_dialog.PNG?raw=true)\n![](images/folder_dialog.PNG?raw=true)\n\nThe command-line output of the program is as follows.\n```text\nThe user pressed OK.\nThe user selected file: C:\\~\\Documents\\github\\fcore\\CMakeLists.txt\nThe user wishes to save file: C:\\~\\Documents\\github\\fcore\\test.txt\nSelected Folder: C:\\~\\Documents\\github\\fcore\\include\n```\n\n## Building FCORE\nThis library can be built using CMake.  For instructions see [Running CMake](https://cmake.org/runningcmake/).\n\n## External Libraries\nThe FCORE library depends upon the following libraries.\n- [FERROR](https://github.com/jchristopherson/ferror)\n\n## TO DO\n- The UI specific code is only for Windows at this time.  Add support for other OS's.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjchristopherson%2Ffcore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjchristopherson%2Ffcore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjchristopherson%2Ffcore/lists"}