=== shmake_add_module.sh ===
#!/bin/sh

# shmake_module.sh - Module creation for shmake
# Author: Emilia Marigold

add_module()
{
        check_project_root

        if [ $# -lt 1 ]; then
                printf "Usage: %s module [name]\n" "$SCRIPT_NAME"
                exit 1
        fi

        MODULE_NAME="$1"
        MODULE_DIR="source_code/MODULE_${MODULE_NAME}"
        MODULE_NAME_UPPER=$(printf "%s" "$MODULE_NAME" | tr '[:lower:]' '[:upper:]')

        printf "Creating module '%s'...\n" "$MODULE_NAME"

        mkdir -p "$MODULE_DIR"
        mkdir -p "$MODULE_DIR/internal"
        mkdir -p "$MODULE_DIR/tests"

        cat > "$MODULE_DIR/${MODULE_NAME}.h" << EOF
#ifndef ${MODULE_NAME_UPPER}_H
#define ${MODULE_NAME_UPPER}_H

/* Function declarations */

#endif /* ${MODULE_NAME_UPPER}_H */
EOF

        cat > "$MODULE_DIR/${MODULE_NAME}.c" << EOF
#include "${MODULE_NAME}.h"

/* Function implementations */

EOF

        cat > "$MODULE_DIR/internal/${MODULE_NAME}_internal.h" << EOF
#ifndef ${MODULE_NAME_UPPER}_INTERNAL_H
#define ${MODULE_NAME_UPPER}_INTERNAL_H

/* Internal function declarations (not exposed in public header) */

#endif /* ${MODULE_NAME_UPPER}_INTERNAL_H */
EOF

        cat > "$MODULE_DIR/internal/${MODULE_NAME}_internal.c" << EOF
#include "${MODULE_NAME}_internal.h"
#include "../${MODULE_NAME}.h"

/* Internal function implementations */

EOF

        cat > "$MODULE_DIR/tests/${MODULE_NAME}_test.h" << EOF
#ifndef ${MODULE_NAME_UPPER}_TEST_H
#define ${MODULE_NAME_UPPER}_TEST_H

/* Test function declarations */

#endif /* ${MODULE_NAME_UPPER}_TEST_H */
EOF

        cat > "$MODULE_DIR/tests/${MODULE_NAME}_test.c" << EOF
#include "${MODULE_NAME}_test.h"
#include "../${MODULE_NAME}.h"

/* Test implementations */

EOF

        printf "Module '%s' created successfully!\n" "$MODULE_NAME"
        printf "  Location: %s\n" "$MODULE_DIR"
        printf "  Next: Add your implementation to the .c files.\n"
        printf "  Run 'shmake sync' after adding source files to update Makefile.\n"
}
=== shmake_clone_test_library.sh ===
#!/bin/sh

# shmake_testlib.sh - Test library cloning for shmake
# Author: Emilia Marigold

clone_test_library()
{
        test_lib="$1"
        LIBRARY_DIR="external_code/test_only/source_code"
        LIB_URL=""
        LIB_NAME=""

        case "$test_lib" in
                Unity|unity)
                        LIB_URL="https://github.com/ThrowTheSwitch/Unity.git"
                        LIB_NAME="Unity"
                        ;;
                CMocka|cmocka|CMOCKA)
                        LIB_URL="https://github.com/clibs/cmocka.git"
                        LIB_NAME="cmocka"
                        ;;
                Check|check)
                        LIB_URL="https://github.com/libcheck/check.git"
                        LIB_NAME="check"
                        ;;
                None|none)
                        return 0
                        ;;
                *)
                        printf "Warning: Unknown test library '%s'. Skipping auto-clone.\n" "$test_lib"
                        return 0
                        ;;
        esac

        printf "\nAuto-cloning test library '%s' to %s...\n" "$test_lib" "$LIBRARY_DIR"

        if ! command -v git >/dev/null 2>&1; then
                printf "Warning: 'git' not found. Library '%s' will need to be added manually.\n" "$test_lib"
                printf "URL: %s\n" "$LIB_URL"
                mkdir -p "shmake_config"
                printf "%s\n" "$LIB_URL" > "shmake_config/project_external_libraries.config"
                return 1
        fi

        if [ -d "$LIBRARY_DIR/$LIB_NAME" ]; then
                printf "Note: '%s' already exists in %s\n" "$LIB_NAME" "$LIBRARY_DIR"
                printf "Overwrite? [y/N]: "
                read -r overwrite
                case "$overwrite" in
                        y|Y)
                                rm -rf "$LIBRARY_DIR/$LIB_NAME"
                                ;;
                        *)
                                printf "Keeping existing installation.\n"
                                printf "%s\n" "$LIB_URL" > "shmake_config/project_external_libraries.config"
                                return 0
                                ;;
                esac
        fi

        mkdir -p "$LIBRARY_DIR"
        printf "Cloning %s (shallow)...\n" "$LIB_NAME"
        if git clone "$LIB_URL" "$LIBRARY_DIR/$LIB_NAME"; then
                printf "Test library '%s' cloned successfully!\n" "$test_lib"
                printf "%s\n" "$LIB_URL" > "shmake_config/project_external_libraries.config"
        else
                printf "Warning: Failed to clone '%s'. You may need to add it manually.\n" "$test_lib"
                printf "URL: %s\n" "$LIB_URL"
                printf "%s\n" "$LIB_URL" > "shmake_config/project_external_libraries.config"
                return 1
        fi
}
=== shmake_download_library.sh ===
#!/bin/sh

# shmake_library.sh - External library addition for shmake
# Author: Emilia Marigold - 2026

download_library()
{
        check_project_root

        if [ $# -lt 1 ]; then
                printf "Usage: %s library [url]\n" "$SCRIPT_NAME"
                exit 1
        fi

        LIBRARY_URL="$1"
        LIBRARY_DIR="external_code/shared_libraries/source_code"

        printf "Adding library from '%s' to %s...\n" "$LIBRARY_URL" "$LIBRARY_DIR"

        LIBRARY_NAME=$(printf "%s" "$LIBRARY_URL" | sed 's|.*/||' | sed 's|.git$||')

        if [ -d "$LIBRARY_DIR/$LIBRARY_NAME" ]; then
                printf "Warning: '%s' already exists in %s\n" "$LIBRARY_NAME" "$LIBRARY_DIR"
                printf "Overwrite? [y/N]: "
                read -r overwrite

                case "$overwrite" in
                        y|Y)
                                rm -rf "$LIBRARY_DIR/$LIBRARY_NAME"
                                ;;
                        *)
                                printf "Aborted.\n" && exit 0
                                ;;
                esac
        fi

        case "$LIBRARY_URL" in
                *.git)
                        printf "Detected Git repository. Using git clone (shallow)...\n"
                        if command -v git >/dev/null 2>&1; then
                                mkdir -p "$LIBRARY_DIR"
                                git clone "$LIBRARY_URL" "$LIBRARY_DIR/$LIBRARY_NAME"
                                if [ $? -eq 0 ]; then
                                        printf "Library '%s' cloned successfully!\n" "$LIBRARY_NAME"
                                        printf "%s\n" "$LIBRARY_URL" >> "shmake_config/project_external_libraries.config"
                                else
                                        printf "Error: Git clone failed.\n"
                                        exit 1
                                fi
                        else
                                printf "Error: 'git' not found. Please install git.\n"
                                exit 1
                        fi
                ;;
                *)
                        printf "Detected file download. Trying wget/curl...\n"
                        if command -v wget >/dev/null 2>&1; then
                                printf "Using wget...\n"
                                mkdir -p "$LIBRARY_DIR"
                                wget "$LIBRARY_URL" -O "$LIBRARY_DIR/${LIBRARY_NAME}.tar.gz" 2>/dev/null
                                if [ $? -eq 0 ]; then
                                        tar -xzf "$LIBRARY_DIR/${LIBRARY_NAME}.tar.gz" -C "$LIBRARY_DIR" 2>/dev/null
                                        rm "$LIBRARY_DIR/${LIBRARY_NAME}.tar.gz"
                                        printf "Library '%s' downloaded successfully!\n" "$LIBRARY_NAME"
                                        printf "%s\n" "$LIBRARY_URL" >> "shmake_config/project_external_libraries.config"
                                else
                                        printf "Error: wget download failed.\n"
                                        exit 1
                                fi
                        elif command -v curl >/dev/null 2>&1; then
                                printf "Using curl...\n"
                                mkdir -p "$LIBRARY_DIR"
                                curl -L "$LIBRARY_URL" -o "$LIBRARY_DIR/${LIBRARY_NAME}.tar.gz" 2>/dev/null
                                if [ $? -eq 0 ]; then
                                        tar -xzf "$LIBRARY_DIR/${LIBRARY_NAME}.tar.gz" -C "$LIBRARY_DIR" 2>/dev/null
                                        rm "$LIBRARY_DIR/${LIBRARY_NAME}.tar.gz"
                                        printf "Library '%s' downloaded successfully!\n" "$LIBRARY_NAME"
                                        printf "%s\n" "$LIBRARY_URL" >> "shmake_config/project_external_libraries.config"
                                else
                                        printf "Error: curl download failed.\n"
                                        exit 1
                                fi
                        else
                                printf "Error: Neither 'wget' nor 'curl' found. Please install one.\n"
                                exit 1
                        fi
                        ;;
        esac
}
=== shmake_help_message.sh ===
#!/bin/sh

# shmake_help.sh - Help message for shmake
# Author: Emilia Marigold

help_message()
{
        printf "USAGE:\n"
        printf "  %s [command] [options]\n\n" "$SCRIPT_NAME"
        printf "COMMANDS:\n"
        printf "  help          Show this help menu\n"
        printf "  init          Initialize a new C project structure\n"
        printf "  module [name] Create a new module in source_code/MODULE_name/\n"
        printf "  library [url] Add a library from URL (git clone or wget/curl)\n"
        printf "  link [libs]   Add linked libraries (e.g., 'link X11 pthread m')\n"
        printf "  sync          Auto-generate Build Configs from source files\n\n"
        printf "BUILD MODES (via make BUILD_MODE=...):\n"
        printf "  debug         Build with debug symbols and debug_only sources\n"
        printf "  release       Build with optimizations and release_only sources\n"
        printf "  test          Build with test flags and test_only sources\n"
        printf "  (Default: release)\n\n"
        printf "EXAMPLES:\n"
        printf "  %s\n" "$SCRIPT_NAME"
        printf "  %s init\n" "$SCRIPT_NAME"
        printf "  %s module my_feature\n" "$SCRIPT_NAME"
        printf "  %s library https://github.com/user/repo.git\n" "$SCRIPT_NAME"
        printf "  %s link X11 pthread m\n" "$SCRIPT_NAME"
        printf "  %s sync\n" "$SCRIPT_NAME"
        printf "  make BUILD_MODE=debug\n"
}
=== shmake_init_project.sh ===
#!/bin/sh

# shmake_init.sh - Project initialization for shmake
# Author: Emilia Marigold

init_project()
{
        printf "Initializing new project...\n\n"
        read_input "Project Name" "" PROJECT_NAME

        if [ -z "$PROJECT_NAME" ]; then
                printf "Error: Project Name cannot be empty.\n"
                exit 1
        fi

        read_input "C Compiler (gcc, clang, tcc, cc)" "gcc" COMPILER
        read_input "C Standard (C99, C11, C17, C23)" "C11" C_VERSION
        read_input "Test Library (Unity, Check, CMOCKA, None)" "None" TEST_LIB

        printf "\nSelect License:\n"
        printf "  1) 0BSD\n"
        printf "  2) AGPL-3.0\n"
        printf "  3) Apache-2.0\n"
        printf "  4) BSD-2-Clause\n"
        printf "  5) BSD-3-Clause\n"
        printf "  6) BSD-3-Clause-Clear\n"
        printf "  7) BSL-1.0\n"
        printf "  8) CC0-1.0\n"
        printf "  9) CC-BY-4.0\n"
        printf " 10) CC-BY-SA-4.0\n"
        printf " 11) EPL-1.0\n"
        printf " 12) EPL-2.0\n"
        printf " 13) EUPL-1.2\n"
        printf " 14) GPL-2.0\n"
        printf " 15) GPL-3.0\n"
        printf " 16) ISC\n"
        printf " 17) LGPL-2.1\n"
        printf " 18) LGPL-3.0\n"
        printf " 19) MIT\n"
        printf " 20) MIT-0\n"
        printf " 21) MPL-2.0\n"
        printf " 22) MulanPSL-2.0\n"
        printf " 23) OFL-1.1\n"
        printf " 24) OSL-3.0\n"
        printf " 25) Unlicense\n"
        printf " 26) UPL-1.0\n"
        printf " 27) WTFPL\n"
        printf " 28) Zlib\n"
        printf " 29) Custom/None\n"
        printf "\nOption [1-29]: "
        read -r LICENSE_CHOICE

        case "$LICENSE_CHOICE" in
                1)  LICENSE="0BSD" ;;
                2)  LICENSE="AGPL-3.0" ;;
                3)  LICENSE="Apache-2.0" ;;
                4)  LICENSE="BSD-2-Clause" ;;
                5)  LICENSE="BSD-3-Clause" ;;
                6)  LICENSE="BSD-3-Clause-Clear" ;;
                7)  LICENSE="BSL-1.0" ;;
                8)  LICENSE="CC0-1.0" ;;
                9)  LICENSE="CC-BY-4.0" ;;
                10) LICENSE="CC-BY-SA-4.0" ;;
                11) LICENSE="EPL-1.0" ;;
                12) LICENSE="EPL-2.0" ;;
                13) LICENSE="EUPL-1.2" ;;
                14) LICENSE="GPL-2.0" ;;
                15) LICENSE="GPL-3.0" ;;
                16) LICENSE="ISC" ;;
                17) LICENSE="LGPL-2.1" ;;
                18) LICENSE="LGPL-3.0" ;;
                19) LICENSE="MIT" ;;
                20) LICENSE="MIT-0" ;;
                21) LICENSE="MPL-2.0" ;;
                22) LICENSE="MulanPSL-2.0" ;;
                23) LICENSE="OFL-1.1" ;;
                24) LICENSE="OSL-3.0" ;;
                25) LICENSE="Unlicense" ;;
                26) LICENSE="UPL-1.0" ;;
                27) LICENSE="WTFPL" ;;
                28) LICENSE="Zlib" ;;
                29)
                        printf "Enter license name: "
                        read -r LICENSE
                        [ -z "$LICENSE" ] && LICENSE="Custom"
                        ;;
                *)
                        printf "Invalid selection. Defaulting to Custom\n"
                        LICENSE="Custom"
                        ;;
        esac

        TARGETS="linux macos windows bsd ios ipados android"
        ENABLED_TARGETS=""

        printf "\nSelect Build Targets (y/n for each):\n"
        for target in $TARGETS; do
                printf "  Enable %s? [y/n]: " "$target"
                read -r choice
                case "$choice" in
                        y|Y) ENABLED_TARGETS="$ENABLED_TARGETS $target" ;;
                esac
        done

        [ -z "$ENABLED_TARGETS" ] && printf "No targets selected. Defaulting to linux.\n" && ENABLED_TARGETS=" linux"

        printf "\nDo you need a resources folder? [y/n]: "
        read -r NEED_RESOURCES
        ENABLED_RESOURCES=""

        if [ "$NEED_RESOURCES" = "y" ] || [ "$NEED_RESOURCES" = "Y" ]; then
                printf "\nSelect Resource Sub-directories (y/n for each):\n"
                RESOURCE_TYPES="fonts images models music sound_effects text textures"
                for resource in $RESOURCE_TYPES; do
                        printf "  Enable %s? [y/n]: " "$resource"
                        read -r choice
                        case "$choice" in
                                y|Y) ENABLED_RESOURCES="$ENABLED_RESOURCES $resource" ;;
                        esac
                done
                [ -z "$ENABLED_RESOURCES" ] && printf "No resources selected. Enabling all by default.\n" && ENABLED_RESOURCES=" fonts images models music sound_effects text textures"
        fi

        printf "\nVersion Control (git, hg, svn, fossil, bzr, darcs, none): "
        read -r VCS
        [ -z "$VCS" ] && VCS="git"

        VERSION=$(date +"%y.%j.%H%M")

        printf "\nCreating project folder '%s'...\n" "$PROJECT_NAME"
        mkdir -p "$PROJECT_NAME"
        cd "$PROJECT_NAME" || exit 1

        printf "Creating subdirectories...\n"
        mkdir -p "source_code"
        mkdir -p "external_code/shared_libraries/source_code"
        mkdir -p "external_code/shared_libraries/binary"
        mkdir -p "external_code/test_only/source_code"
        mkdir -p "external_code/test_only/binary"
        mkdir -p "external_code/debug_only/source_code"
        mkdir -p "external_code/debug_only/binary"
        mkdir -p "external_code/release_only/source_code"
        mkdir -p "external_code/release_only/binary"
        mkdir -p "build_output"
        mkdir -p "intermediate_code"
        mkdir -p "shmake_config"
        mkdir -p "shmake_config/shmake_cache"

        for resource in $ENABLED_RESOURCES; do
                mkdir -p "resources/$resource"
        done

        if [ "$LICENSE_CHOICE" != "29" ]; then
                process_license "$PROJECT_NAME" "$LICENSE"
        else
                printf "Custom license selected. Creating stub...\n"
                cat > "LICENSE" << EOF
$LICENSE License

Copyright (c) $(date +%Y) $PROJECT_NAME

Permission is hereby granted...
EOF
        fi

        if [ "$TEST_LIB" != "None" ] && [ "$TEST_LIB" != "none" ]; then
                clone_test_library "$TEST_LIB"
        fi

        printf "Creating files...\n"

        cat > "shmake_config/project.conf" << EOF
PROJECT_NAME=$PROJECT_NAME
COMPILER=$COMPILER
C_VERSION=$C_VERSION
TEST_LIB=$TEST_LIB
LICENSE=$LICENSE
VCS=$VCS
VERSION=$VERSION
ENABLED_RESOURCES=$ENABLED_RESOURCES
EOF

        cat > "README.md" << EOF
# $PROJECT_NAME

A C project built with **shmake**.

## Requirements
- C Compiler: $COMPILER
- C Standard: $C_VERSION Support
- Test Library: $TEST_LIB

## License
$LICENSE

## Build
Run \`./shmake sync\` to generate Makefile configs, then \`make\` to build.

## Build Modes
- \`make\` (Default: Release)
- \`make BUILD_MODE=debug\`
- \`make BUILD_MODE=test\`

## Version
$VERSION

## Resources
        $(for res in $ENABLED_RESOURCES; do printf "- %s\n" "$res"; done)
EOF

        case "$VCS" in
                git)
                        cat > ".gitignore" << EOF
build_output/
intermediate_code/
external_code/
*.swp
*.swo
*~
.DS_Store
Thumbs.db
shmake_config/
EOF
                        ;;
                hg)
                        cat > ".hgignore" << EOF
syntax: glob
build_output/
intermediate_code/
external_code/
*.swp
*.swo
*~
.DS_Store
Thumbs.db
shmake_config/
EOF
                        ;;
                svn)
                        cat > ".svnignore" << EOF
build_output
intermediate_code
external_code
*.swp
*.swo
*~
.DS_Store
Thumbs.db
shmake_config
EOF
                        ;;
                *)
                        cat > ".gitignore" << EOF
build_output/
intermediate_code/
external_code/
*.swp
*.swo
*~
.DS_Store
shmake_config/
EOF
                ;;
        esac

        cat > "source_code/main.c" << EOF
#include <stdio.h>

int main(void) {
    printf("Hello, %s!\\n", "$PROJECT_NAME");
    printf("Version: %s\\n", "$VERSION");
    return 0;
}
EOF

        for conf in makefile.conf makefile_test.conf makefile_debug.conf makefile_release.conf makefile_clean.conf; do
                printf "# %s - Initialized by shmake\n" "$conf" > "shmake_config/$conf"
        done

        cat > "shmake_config/linked.conf" << 'EOF'
# --- shmake Linked Libraries Configuration ---
# Format: library names (automatically converted to -l flags)
# Example: LINKED_LIBS = -lX11 -lpthread -lm
LINKED_LIBS = 
EOF

        cat > "Makefile" << EOF
# Generated by shmake init
# Run 'shmake sync' to populate build configurations.
# Portable: Works on GNU Make, bmake, BSD Make (macOS)

include shmake_config/makefile.conf

PROJECT_NAME = $PROJECT_NAME

.PHONY: all clean

all:
    @echo "Please run 'shmake sync' to generate build rules."
    @echo "Then run 'make' to build."

clean:
    rm -rf build_output intermediate_code
EOF

        printf "\nProject '%s' initialized successfully!\n" "$PROJECT_NAME"
        printf "  Version: %s\n" "$VERSION"
        printf "  Build Targets: %s\n" "$ENABLED_TARGETS"
        printf "  Resources: %s\n" "$ENABLED_RESOURCES"
        printf "  License: %s\n" "$LICENSE"
        printf "  Test Library: %s\n" "$TEST_LIB"
        [ "$TEST_LIB" != "None" ] && [ "$TEST_LIB" != "none" ] && printf "  Test Library Location: external_code/test_only/source_code/\n"
        printf "  Next steps:\n"
        printf "  1. Add your source files to source_code/\n"
        printf "  2. Run 'shmake sync' to generate Makefile build rules\n"
        printf "  3. Run 'make' to build\n"
        printf "  4. Use 'make BUILD_MODE=test' for test builds\n"
        printf "  5. Use 'shmake link X11 pthread m' to add linked libraries\n"
}
=== shmake_link_library.sh ===
#!/bin/sh

# shmake_link.sh - Linked library configuration for shmake
# Author: Emilia Marigold

add_linked_library()
{
        check_project_root

        if [ $# -lt 1 ]; then
                printf "Usage: %s link [library_names]\n" "$SCRIPT_NAME"
                printf "Example: %s link X11 pthread m\n" "$SCRIPT_NAME"
                exit 1
        fi

        LIB_NAMES="$*"

        LIB_FLAGS=""
        for lib in $LIB_NAMES; do
                if [ -z "$LIB_FLAGS" ]; then
                        LIB_FLAGS="-l$lib"
                else
                        LIB_FLAGS="$LIB_FLAGS -l$lib"
                fi
        done

        printf "Adding linked libraries: %s\n" "$LIB_FLAGS"

        mkdir -p "shmake_config"

        if [ -f "shmake_config/linked.conf" ]; then
                printf "Note: 'linked.conf' already exists.\n"
                printf "Current linked libraries:\n"
                cat "shmake_config/linked.conf"
                printf "\nAppend? [y/N]: "
                read -r append_choice
                       case "$append_choice" in
                                y|Y)
                                        old_libs=$(grep '^LINKED_LIBS' "shmake_config/linked.conf" | sed 's/^LINKED_LIBS = //')
                                        new_libs="$old_libs $LIB_FLAGS"
                                        sed -i '/^LINKED_LIBS/d' "shmake_config/linked.conf"
                                        printf "LINKED_LIBS = %s\n" "$new_libs" >> "shmake_config/linked.conf"
                                        printf "Linked libraries appended successfully!\n"
                                        ;;
                                *)
                                        sed -i '/^LINKED_LIBS/d' "shmake_config/linked.conf"
                                        printf "LINKED_LIBS = %s\n" "$LIB_FLAGS" >> "shmake_config/linked.conf"
                                        printf "Linked libraries overwritten successfully!\n"
                                        ;;
                        esac
        else
                cat > "shmake_config/linked.conf" << EOF
# --- shmake Linked Libraries Configuration ---
# Format: library names (automatically converted to -l flags)
# Example: LINKED_LIBS = -lX11 -lpthread -lm
LINKED_LIBS = $LIB_FLAGS
EOF
                printf "Linked libraries configured successfully!\n"
        fi

        printf "\nRun 'shmake sync' to update Makefile with these libraries.\n"
}
=== shmake_process_license.sh ===
#!/bin/sh

# shmake_license.sh - License processing for shmake
# Author: Emilia Marigold

process_license()
{
        project_name="$1"
        license_name="$2"

        script_dir=$(get_script_dir)
        licenses_dir="$script_dir/../../licenses"

        printf "Processing license: %s...\n" "$license_name"

        if [ ! -d "$licenses_dir" ]; then
                printf "Error: Licenses directory not found at '%s'.\n" "$licenses_dir"
                printf "Ensure 'shmake' is installed with its 'licenses' folder alongside it.\n"
                exit 1
        fi

        if [ ! -f "$licenses_dir/$license_name" ]; then
                printf "Warning: License file '%s' not found in script directory. Creating stub.\n" "$license_name"
                cat > "LICENSE" << EOF
                $license_name License

Copyright (c) $(date +%Y) $project_name

Permission is hereby granted... (See full text for $license_name)
EOF
                return 0
        fi

        cp "$licenses_dir/$license_name" "LICENSE"

        printf "\nEnter your name (for copyright): "
        read -r user_name
        [ -z "$user_name" ] && user_name="Your Name"

        printf "Enter organization (optional, press Enter to skip): "
        read -r user_org
        [ -z "$user_org" ] && user_org="None"

        printf "Enter project start year: "
        read -r project_year
        [ -z "$project_year" ] && project_year=$(date +%Y)

        current_year=$(date +%Y)

        escaped_name=$(printf "%s" "$user_name" | sed 's/[&/\]/\\&/g')
        escaped_org=$(printf "%s" "$user_org" | sed 's/[&/\]/\\&/g')

        tmp_file=$(mktemp)

        sed \
                -e "s|(name)|$escaped_name|g" \
                -e "s|(year)|$current_year|g" \
                -e "s|(year1)|$project_year|g" \
                -e "s|(year2)|$current_year|g" \
                -e "s|(project_name)|$project_name|g" \
                -e "s|(org)|$escaped_org|g" \
                "LICENSE" > "$tmp_file"

        mv "$tmp_file" "LICENSE"

        printf "License '%s' applied successfully!\n" "$license_name"
}
=== shmake.sh ===
#!/bin/sh

# shmake - the "Simple helpful make system" aka "the shell make system"
# A POSIX-compliant build system for C projects
# Author: Emilia Marigold
# License: AGPL-3.0

set -u

SCRIPT_NAME="shmake"

# Get script directory once
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)

# Source all utility scripts
. "$SCRIPT_DIR/shmake_source/shmake_utils.sh"
. "$SCRIPT_DIR/shmake_source/shmake_help_message.sh"
. "$SCRIPT_DIR/shmake_source/shmake_init_project.sh"
. "$SCRIPT_DIR/shmake_source/shmake_add_module.sh"
. "$SCRIPT_DIR/shmake_source/shmake_download_library.sh"
. "$SCRIPT_DIR/shmake_source/shmake_link_library.sh"
. "$SCRIPT_DIR/shmake_source/shmake_sync_makefile.sh"
. "$SCRIPT_DIR/shmake_source/shmake_process_license.sh"

#=========================================================================================
# Main Entry Point
#=========================================================================================
main()
{
        if [ $# -eq 0 ]; then
                help_message
                exit 0
        fi

        case "$1" in
                help|--help|-h)
                        help_message
                        ;;
                init)
                        init_project
                        ;;
                module)
                        shift
                        add_module "$@"
                        ;;
                library)
                        shift
                        add_library "$@"
                        ;;
                link)
                        shift
                        add_linked_library "$@"
                        ;;
                sync)
                        sync_project
                        ;;
                *)
                        printf "Command unknown: %s\n" "$1"
                        printf "Run '%s help' for usage.\n" "$SCRIPT_NAME"
                        exit 1
                        ;;
        esac
}

main "$@"
=== shmake_sync_makefile.sh ===
#!/bin/sh

# shmake_sync.sh - Project synchronization for shmake
# Author: Emilia Marigold

sync_project()
{
        check_project_root
        printf "Syncing project files...\n"

        SOURCE_FILES_LIST=$(mktemp)
        SHARED_SOURCE_LIST=$(mktemp)
        SHARED_BINARY_LIST=$(mktemp)
        TEST_SOURCE_LIST=$(mktemp)
        TEST_BINARY_LIST=$(mktemp)
        DEBUG_SOURCE_LIST=$(mktemp)
        DEBUG_BINARY_LIST=$(mktemp)
        RELEASE_SOURCE_LIST=$(mktemp)
        RELEASE_BINARY_LIST=$(mktemp)
        INCLUDE_DIRS_LIST=$(mktemp)
        LINKED_LIBS_LIST=$(mktemp)

        trap 'rm -f "$SOURCE_FILES_LIST" "$SHARED_SOURCE_LIST" "$SHARED_BINARY_LIST" "$TEST_SOURCE_LIST" "$TEST_BINARY_LIST" "$DEBUG_SOURCE_LIST" "$DEBUG_BINARY_LIST" "$RELEASE_SOURCE_LIST" "$RELEASE_BINARY_LIST" "$INCLUDE_DIRS_LIST" "$LINKED_LIBS_LIST"' EXIT

        printf "Scanning source_code/ for source files...\n"
        [ -d "source_code" ] && find source_code -type f -name '*.c' 2>/dev/null | while read -r f; do
                printf '%s\n' "$f" >> "$SOURCE_FILES_LIST"
        done

        printf "Scanning external_code/shared_libraries/ for source files...\n"
        [ -d "external_code/shared_libraries/source_code" ] && find external_code/shared_libraries/source_code -type f -name '*.c' 2>/dev/null | while read -r f; do
                case "$f" in
                        *example*) printf "Skipping %s (example code)\n" "$f" >&2 ;;
                        *) printf '%s\n' "$f" >> "$SHARED_SOURCE_LIST" ;;
                esac
        done

        printf "Scanning external_code/shared_libraries/binary/ for binary libraries...\n"
        [ -d "external_code/shared_libraries/binary" ] && find external_code/shared_libraries/binary -type f \( -name '*.a' -o -name '*.so' -o -name '*.lib' -o -name '*.dylib' \) 2>/dev/null | while read -r f; do
                printf '%s\n' "$f" >> "$SHARED_BINARY_LIST"
        done

        printf "Scanning external_code/test_only/ for source files...\n"
        [ -d "external_code/test_only/source_code" ] && find external_code/test_only/source_code -type f -name '*.c' 2>/dev/null | while read -r f; do
                case "$f" in
                        *example*) printf "Skipping %s (example code)\n" "$f" >&2 ;;
                        *) printf '%s\n' "$f" >> "$TEST_SOURCE_LIST" ;;
                esac
        done

        printf "Scanning external_code/debug_only/ for source files...\n"
        [ -d "external_code/debug_only/source_code" ] && find external_code/debug_only/source_code -type f -name '*.c' 2>/dev/null | while read -r f; do
                case "$f" in
                        *example*) printf "Skipping %s (example code)\n" "$f" >&2 ;;
                        *) printf '%s\n' "$f" >> "$DEBUG_SOURCE_LIST" ;;
                esac
        done
        [ -d "external_code/debug_only/binary" ] && find external_code/debug_only/binary -type f \( -name '*.a' -o -name '*.so' -o -name '*.lib' -o -name '*.dylib' \) 2>/dev/null | while read -r f; do
                printf '%s\n' "$f" >> "$DEBUG_BINARY_LIST"
        done

        printf "Scanning external_code/release_only/ for source files...\n"
        [ -d "external_code/release_only/source_code" ] && find external_code/release_only/source_code -type f -name '*.c' 2>/dev/null | while read -r f; do
                case "$f" in
                        *example*) printf "Skipping %s (example code)\n" "$f" >&2 ;;
                        *) printf '%s\n' "$f" >> "$RELEASE_SOURCE_LIST" ;;
                esac
        done
        [ -d "external_code/release_only/binary" ] && find external_code/release_only/binary -type f \( -name '*.a' -o -name '*.so' -o -name '*.lib' -o -name '*.dylib' \) 2>/dev/null | while read -r f; do
                printf '%s\n' "$f" >> "$RELEASE_BINARY_LIST"
        done

        printf "Auto-detecting include directories across entire project...\n"
        find . -type d ! -path "*/internal*" ! -path "./.git*" ! -path "./build_output*" ! -path "./intermediate_code*" ! -path "*/examples*" ! -path "*/example*" ! -path "./shmake_config*" 2>/dev/null | while read -r dir; do
                clean_dir=$(printf "%s" "$dir" | sed 's|^\./||')
                [ -z "$clean_dir" ] && continue
                [ "$clean_dir" = "." ] && continue
                find "$clean_dir" -maxdepth 1 -type f -name '*.h' 2>/dev/null | grep -q . && printf '%s\n' "$clean_dir" >> "$INCLUDE_DIRS_LIST"
        done

        printf "Reading linked libraries from shmake_config/linked.conf...\n"
        [ -f "shmake_config/linked.conf" ] && grep '^LINKED_LIBS' "shmake_config/linked.conf" | sed 's/^LINKED_LIBS = //' | while read -r line; do
                printf '%s\n' "$line" >> "$LINKED_LIBS_LIST"
        done

        printf "Sorting and deduplicating file lists...\n"
        sort -u "$SOURCE_FILES_LIST" -o "$SOURCE_FILES_LIST"
        sort -u "$SHARED_SOURCE_LIST" -o "$SHARED_SOURCE_LIST"
        sort -u "$SHARED_BINARY_LIST" -o "$SHARED_BINARY_LIST"
        sort -u "$TEST_SOURCE_LIST" -o "$TEST_SOURCE_LIST"
        sort -u "$TEST_BINARY_LIST" -o "$TEST_BINARY_LIST"
        sort -u "$DEBUG_SOURCE_LIST" -o "$DEBUG_SOURCE_LIST"
        sort -u "$DEBUG_BINARY_LIST" -o "$DEBUG_BINARY_LIST"
        sort -u "$RELEASE_SOURCE_LIST" -o "$RELEASE_SOURCE_LIST"
        sort -u "$RELEASE_BINARY_LIST" -o "$RELEASE_BINARY_LIST"
        sort -u "$INCLUDE_DIRS_LIST" -o "$INCLUDE_DIRS_LIST"
        sort -u "$LINKED_LIBS_LIST" -o "$LINKED_LIBS_LIST"

        printf "Reading project configuration...\n"
        if [ -f "shmake_config/project.conf" ]; then
                . "shmake_config/project.conf"
                C_VERSION_LOWER=$(printf "%s" "$C_VERSION" | tr '[:upper:]' '[:lower:]')
        else
                C_VERSION_LOWER="c11"
        fi

        printf "Generating makefile.conf...\n"
        cat > "shmake_config/makefile.conf" << 'CONF_HEADER'
# --- shmake Base Configuration (Always Included) ---
CONF_HEADER
        printf 'CFLAGS = -std=%s\n' "$C_VERSION_LOWER" >> "shmake_config/makefile.conf"
        printf 'PROJECT_SOURCES = \\\n' >> "shmake_config/makefile.conf"
        while IFS= read -r file; do
                [ -n "$file" ] && printf '    %s \\\n' "$file" >> "shmake_config/makefile.conf"
        done < "$SOURCE_FILES_LIST"
        printf '\n' >> "shmake_config/makefile.conf"
        printf 'SHARED_SOURCES = \\\n' >> "shmake_config/makefile.conf"
        while IFS= read -r file; do
                [ -n "$file" ] && printf '    %s \\\n' "$file" >> "shmake_config/makefile.conf"
        done < "$SHARED_SOURCE_LIST"
        printf '\n' >> "shmake_config/makefile.conf"
        printf 'SHARED_LIBS = \\\n' >> "shmake_config/makefile.conf"
        while IFS= read -r file; do
                [ -n "$file" ] && printf '    %s \\\n' "$file" >> "shmake_config/makefile.conf"
        done < "$SHARED_BINARY_LIST"
        printf '\n' >> "shmake_config/makefile.conf"
        printf 'INCLUDE_DIRS = \\\n' >> "shmake_config/makefile.conf"
        while IFS= read -r dir; do
                [ -n "$dir" ] && printf '    -I%s \\\n' "$dir" >> "shmake_config/makefile.conf"
        done < "$INCLUDE_DIRS_LIST"
        sed -i '$ s/ \\$//' "shmake_config/makefile.conf"

        printf "Generating makefile_test.conf...\n"
        cat > "shmake_config/makefile_test.conf" << 'CONF_HEADER'
# --- shmake Test Configuration (Included only if BUILD_MODE=test) ---
CONF_HEADER
        printf 'TEST_SOURCES = \\\n' >> "shmake_config/makefile_test.conf"
        while IFS= read -r file; do
                [ -n "$file" ] && printf '    %s \\\n' "$file" >> "shmake_config/makefile_test.conf"
        done < "$TEST_SOURCE_LIST"
        printf '\n' >> "shmake_config/makefile_test.conf"
        printf 'TEST_LIBS = \\\n' >> "shmake_config/makefile_test.conf"
        while IFS= read -r file; do
                [ -n "$file" ] && printf '    %s \\\n' "$file" >> "shmake_config/makefile_test.conf"
        done < "$TEST_BINARY_LIST"
        printf '\n' >> "shmake_config/makefile_test.conf"

        printf "Generating makefile_debug.conf...\n"
        cat > "shmake_config/makefile_debug.conf" << 'CONF_HEADER'
# --- shmake Debug Configuration (Included only if BUILD_MODE=debug) ---
CONF_HEADER
        printf 'DEBUG_SOURCES = \\\n' >> "shmake_config/makefile_debug.conf"
        while IFS= read -r file; do
                [ -n "$file" ] && printf '    %s \\\n' "$file" >> "shmake_config/makefile_debug.conf"
        done < "$DEBUG_SOURCE_LIST"
        printf '\n' >> "shmake_config/makefile_debug.conf"
        printf 'DEBUG_LIBS = \\\n' >> "shmake_config/makefile_debug.conf"
        while IFS= read -r file; do
                [ -n "$file" ] && printf '    %s \\\n' "$file" >> "shmake_config/makefile_debug.conf"
        done < "$DEBUG_BINARY_LIST"
        printf '\n' >> "shmake_config/makefile_debug.conf"

        printf "Generating makefile_release.conf...\n"
        cat > "shmake_config/makefile_release.conf" << 'CONF_HEADER'
# --- shmake Release Configuration (Included only if BUILD_MODE=release) ---
CONF_HEADER
        printf 'RELEASE_SOURCES = \\\n' >> "shmake_config/makefile_release.conf"
        while IFS= read -r file; do
                [ -n "$file" ] && printf '    %s \\\n' "$file" >> "shmake_config/makefile_release.conf"
        done < "$RELEASE_SOURCE_LIST"
        printf '\n' >> "shmake_config/makefile_release.conf"
        printf 'RELEASE_LIBS = \\\n' >> "shmake_config/makefile_release.conf"
        while IFS= read -r file; do
                [ -n "$file" ] && printf '    %s \\\n' "$file" >> "shmake_config/makefile_release.conf"
        done < "$RELEASE_BINARY_LIST"
        printf '\n' >> "shmake_config/makefile_release.conf"

        printf "Generating makefile_clean.conf...\n"
        cat > "shmake_config/makefile_clean.conf" << 'CONF_HEADER'
# --- shmake Clean Configuration ---
CONF_HEADER
        printf 'CLEAN_TARGETS = build_output\n' >> "shmake_config/makefile_clean.conf"
        printf 'EXTRA_CLEAN = intermediate_code\n' >> "shmake_config/makefile_clean.conf"

        printf "Updating Root Makefile...\n"
        cat > "Makefile" << 'MAKEFILE_TEMPLATE'
# --- shmake Root Makefile ---
# Generated/Updated by shmake sync
# Portable: Works on GNU Make, bmake, BSD Make (macOS), and other POSIX-compliant makes
#
# Usage:
#   make                    # Build with release mode (default)
#   make BUILD_MODE=debug   # Build with debug mode
#   make BUILD_MODE=test    # Build with test mode
#   make clean              # Clean build artifacts

# Include project configuration (for PROJECT_NAME)
-include shmake_config/project.conf

# Include base build configuration (always included)
include shmake_config/makefile.conf

# Include linked libraries configuration (if exists)
-include shmake_config/linked.conf

# Determine Build Mode (default: release)
BUILD_MODE ?= release

# Include mode-specific configuration based on BUILD_MODE
ifeq ($(BUILD_MODE),test)
    include shmake_config/makefile_test.conf
endif

ifeq ($(BUILD_MODE),debug)
    include shmake_config/makefile_debug.conf
endif

ifeq ($(BUILD_MODE),release)
    include shmake_config/makefile_release.conf
endif

# --- Variable Merging ---
ALL_SOURCES = $(PROJECT_SOURCES) $(SHARED_SOURCES)
ifdef TEST_SOURCES
    ALL_SOURCES += $(TEST_SOURCES)
endif
ifdef DEBUG_SOURCES
    ALL_SOURCES += $(DEBUG_SOURCES)
endif
ifdef RELEASE_SOURCES
    ALL_SOURCES += $(RELEASE_SOURCES)
endif

ALL_LIBS = $(SHARED_LIBS) $(LINKED_LIBS)
ifdef TEST_LIBS
    ALL_LIBS += $(TEST_LIBS)
endif
ifdef DEBUG_LIBS
    ALL_LIBS += $(DEBUG_LIBS)
endif
ifdef RELEASE_LIBS
    ALL_LIBS += $(RELEASE_LIBS)
endif

ALL_OBJECTS = $(ALL_SOURCES:.c=.o)
OUTPUT_DIR = build_output
OBJ_DIR = intermediate_code
CC = gcc
CFLAGS += $(INCLUDE_DIRS)

.PHONY: all clean distclean

all: $(PROJECT_NAME)

$(PROJECT_NAME): $(ALL_OBJECTS)
    @mkdir -p $(OUTPUT_DIR)
    $(CC) $(CFLAGS) -o $(OUTPUT_DIR)/$(PROJECT_NAME) $(ALL_OBJECTS) $(ALL_LIBS)

$(OBJ_DIR)/%.o: %.c
    @mkdir -p $(OBJ_DIR)/$(dir $<)
    $(CC) $(CFLAGS) -c $< -o $@

include shmake_config/makefile_clean.conf

clean:
    rm -rf $(CLEAN_TARGETS) $(EXTRA_CLEAN)

distclean: clean
    rm -rf $(OBJ_DIR)
MAKEFILE_TEMPLATE

        printf "\nSync complete!\n"
        printf "  Updated shmake_config/makefile.conf\n"
        printf "  Updated shmake_config/makefile_test.conf\n"
        printf "  Updated shmake_config/makefile_debug.conf\n"
        printf "  Updated shmake_config/makefile_release.conf\n"
        printf "  Updated shmake_config/makefile_clean.conf\n"
        printf "  Updated Makefile\n"
        [ -f "shmake_config/linked.conf" ] && printf "  Included shmake_config/linked.conf\n"
        printf "\nFound %d source files\n" "$(wc -l < "$SOURCE_FILES_LIST" | tr -d ' ')"
        printf "Found %d shared library sources (always included)\n" "$(wc -l < "$SHARED_SOURCE_LIST" | tr -d ' ')"
        printf "Found %d test sources (BUILD_MODE=test only)\n" "$(wc -l < "$TEST_SOURCE_LIST" | tr -d ' ')"
        printf "Found %d debug sources (BUILD_MODE=debug only)\n" "$(wc -l < "$DEBUG_SOURCE_LIST" | tr -d ' ')"
        printf "Found %d release sources (BUILD_MODE=release only)\n" "$(wc -l < "$RELEASE_SOURCE_LIST" | tr -d ' ')"
        printf "\nAuto-detected %d include directories:\n" "$(wc -l < "$INCLUDE_DIRS_LIST" | tr -d ' ')"
        while IFS= read -r dir; do
                printf "  -I%s\n" "$dir"
        done < "$INCLUDE_DIRS_LIST"
        if [ -s "$LINKED_LIBS_LIST" ]; then
                printf "\nLinked libraries from linked.conf:\n"
                while IFS= read -r lib; do
                        printf "  %s\n" "$lib"
                done < "$LINKED_LIBS_LIST"
        else
                printf "\nNo linked libraries configured.\n"
        fi
        printf "\nUse 'make BUILD_MODE=test' to build with test sources.\n"
        printf "Use 'make BUILD_MODE=debug' to build with debug sources.\n"
}
=== shmake_utils.sh ===
#!/bin/sh

# shmake_utils.sh - Utility functions for shmake
# Author: Emilia Marigold

#=========================================================================================
# Get script directory (POSIX-compliant)
#=========================================================================================
get_script_dir()
{
        script_path="$0"

        case "$script_path" in
                */*) ;;
                *)
                        resolved=$(command -v "$0" 2>/dev/null)
                        if [ -n "$resolved" ]; then
                                script_path="$resolved"
                        fi
                        ;;
        esac

        case "$script_path" in
                /*) ;;
                *)  script_path="$(pwd)/$script_path" ;;
        esac

        printf "%s" "$(cd "$(dirname "$script_path")" && pwd)"
}

#=========================================================================================
# Safe input reading for POSIX sh
#=========================================================================================
read_input()
{
        prompt="$1"
        default="$2"
        variable_name="$3"

        if [ -n "$default" ]; then
                printf "%s [%s]: " "$prompt" "$default"
        else
                printf "%s: " "$prompt"
        fi

        read -r input_val

        if [ -z "$input_val" ]; then
                input_val="$default"
        fi

        eval "$variable_name='$input_val'"
}

#=========================================================================================
# Check if running from project root
#=========================================================================================
check_project_root()
{
        if [ ! -f "shmake_config/project.conf" ]; then
                printf "Error: Not in a shmake project directory.\n"
                printf "Run 'shmake init' first or cd into your project folder.\n"
                exit 1
        fi
}
