From 5d683ebd33442d744ea52a836a4fa9ea0e2ba317 Mon Sep 17 00:00:00 2001
From: Egor Tensin <Egor.Tensin@gmail.com>
Date: Sat, 13 Aug 2016 13:21:52 +0200
Subject: add fix_nt_symbol_path.sh

---
 .gitattributes        |   3 +
 LICENSE.txt           |  21 ++++++
 README.md             |  13 ++++
 fix_nt_symbol_path.sh | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 241 insertions(+)
 create mode 100644 .gitattributes
 create mode 100644 LICENSE.txt
 create mode 100644 README.md
 create mode 100644 fix_nt_symbol_path.sh

diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..d76765e
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,3 @@
+* text=auto
+
+*.sh text eol=lf
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..80c5e0a
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2016 Egor Tensin <Egor.Tensin@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1c8609f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+Windows `tmp` directory
+=======================
+
+This is my directory for temporary Windows (mostly C++) project files (symbol
+files, project databases, etc.).
+
+License
+-------
+
+Distributed under the MIT License.
+See [LICENSE.txt] for details.
+
+[LICENSE.txt]: LICENSE.txt
diff --git a/fix_nt_symbol_path.sh b/fix_nt_symbol_path.sh
new file mode 100644
index 0000000..3767cd5
--- /dev/null
+++ b/fix_nt_symbol_path.sh
@@ -0,0 +1,204 @@
+#!/usr/bin/env bash
+
+# Copyright (c) 2016 Egor Tensin <Egor.Tensin@gmail.com>
+# This file is part of the "Windows tmp directory" project.
+# For details, see https://github.com/egor-tensin/windows-tmp.
+# Distributed under the MIT License.
+
+# "Fixes" the value of _NT_SYMBOL_PATH environment variable by
+#
+# * including the path to the "pdbs" directory in this repository,
+# * adding the "symbols" directory as a local "symbol store", mirroring
+# Microsoft's http://msdl.microsoft.com/download/symbols.
+
+# usage: ./fix_nt_symbol_path.sh [-h|--help] [-y|--yes] [-d|--dir TMP_DIR]
+
+dump() {
+    local prefix="${FUNCNAME[0]}"
+    if [ "${#FUNCNAME[@]}" -gt 1 ]; then
+        prefix="${FUNCNAME[1]}"
+    fi
+    while [ "$#" -ne 0 ]; do
+        echo "$prefix: $1"
+        shift
+    done
+}
+
+str_tolower() {
+    while [ "$#" -ne 0 ]; do
+        echo "$1" | tr '[:upper:]' '[:lower:]'
+        shift
+    done
+}
+
+str_contains() {
+    if [ "$#" -ne 2 ]; then
+        echo "usage: ${FUNCNAME[0]} STR SUB"
+        return 1
+    fi
+    local str="$1"
+    local sub="$( printf '%q' "$2" )"
+    test "$str" != "${str#*$sub}"
+}
+
+path_separator=';'
+
+path_contains() {
+    if [ "$#" -ne 2 ]; then
+        echo "usage: ${FUNCNAME[0]} ENV_VALUE DIR_PATH"
+        return 1
+    fi
+    local env_value="$( str_tolower "$1" )"
+    local path_to_add="$( str_tolower "$2" )"
+    local -a env_paths=()
+    IFS="$path_separator" read -ra env_paths <<< "$env_value"
+    local env_path
+    for env_path in "${env_paths[@]+"${env_paths[@]}"}"; do
+        if [ "$env_path" == "$path_to_add" ]; then
+            return 0
+        fi
+    done
+    return 1
+}
+
+path_append() {
+    if [ "$#" -ne 2 ]; then
+        echo "usage: ${FUNCNAME[0]} ENV_VALUE DIR_PATH"
+        return 1
+    fi
+    local env_value="$1"
+    local path_to_add="$2"
+    if ! path_contains "$env_value" "$path_to_add"; then
+        if [ -z "$env_value" ]; then
+            echo "$path_to_add"
+        else
+            echo "$path_separator$path_to_add"
+        fi
+    fi
+}
+
+prompt_to_continue() {
+    local prefix="${FUNCNAME[0]}"
+    if [ "${#FUNCNAME[@]}" -gt 1 ]; then
+        prefix="${FUNCNAME[1]}"
+    fi
+
+    local prompt_reply
+    while true; do
+        echo -n "$prefix: continue? (y/n) "
+        read -r prompt_reply
+        prompt_reply="$( str_tolower "$prompt_reply" )"
+        case "$prompt_reply" in
+            y|yes) return 0 ;;
+            n|no)  return 1 ;;
+            *)     continue ;;
+        esac
+    done
+}
+
+ensure_reg_available() {
+    if command -v reg.exe > /dev/null; then
+        return 0
+    else
+        dump "reg.exe could not be found" >&2
+        return 1
+    fi
+}
+
+registry_set_string() (
+    if [ "$#" -ne 3 ]; then
+        echo "usage: ${FUNCNAME[0]} KEY_PATH VALUE_NAME VALUE_DATA"
+        return 1
+    fi
+
+    set -o errexit
+
+    ensure_reg_available
+
+    local key_path="$1"
+    local value_name="$2"
+    local value_data="$3"
+
+    reg.exe add "$key_path" /v "$value_name" /t REG_SZ /d "$value_data" /f > /dev/null
+)
+
+fix_nt_symbol_path() (
+    set -o errexit
+
+    local tmp_dir="$( cygpath -aw "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" )"
+
+    while [ "$#" -ne 0 ]; do
+        local option="$1"
+        shift
+
+        case "$option" in
+            -y|--yes)
+                local skip_prompt=
+                continue
+                ;;
+
+            -h|--help)
+                local exit_with_usage=0
+                break
+                ;;
+        esac
+
+        if [ "$#" -eq 0 ]; then
+            dump "usage error: missing argument for parameter: $option" >&2
+            local exit_with_usage=1
+            break
+        fi
+
+        case "$option" in
+            -d|--dir)
+                tmp_dir="$( cygpath -aw "$1" )"
+                shift
+                ;;
+
+            *)
+                dump "usage error: unknown parameter: $option" >&2
+                local exit_with_usage=1
+                break
+                ;;
+        esac
+    done
+
+    if [ -n "${exit_with_usage+x}" ]; then
+        echo "usage: ${FUNCNAME[0]} [-h|--help] [-y|--yes] [-d|--dir TMP_DIR]"
+        return "${exit_with_usage:-0}"
+    fi
+
+    dump "temporary directory path: $tmp_dir"
+
+    if [ -z "${skip_prompt+x}" ]; then
+        prompt_to_continue || return 0
+    fi
+
+    local pdbs_dir="$tmp_dir\\pdbs"
+    local symbols_dir="$tmp_dir\\symbols"
+    local srv_str="SRV*$symbols_dir*http://msdl.microsoft.com/download/symbols"
+    local vscache_dir="$tmp_dir\\vscache"
+
+    dump "directories:"
+    dump "    custom PDB files: $pdbs_dir"
+    dump "    symbol store: $symbols_dir"
+    dump "    Visual Studio project cache files: $vscache_dir"
+
+    local old_value="${_NT_SYMBOL_PATH-}"
+    dump "old _NT_SYMBOL_PATH value: $old_value"
+    local new_value="$old_value"
+
+    new_value+="$( path_append "$new_value" "$pdbs_dir" )"
+    new_value+="$( path_append "$new_value" "$srv_str" )"
+
+    [ "$new_value" == "$old_value" ] && return 0
+    dump "new _NT_SYMBOL_PATH value: $new_value"
+
+    if [ -z "${skip_prompt+x}" ]; then
+        prompt_to_continue || return 0
+    fi
+
+    registry_set_string 'HKCU\Environment' '_NT_SYMBOL_PATH' "$new_value"
+)
+
+fix_nt_symbol_path "$@"
-- 
cgit v1.2.3