Add ability to inject arbitrary environment variables (#354)

diff --git a/README.md b/README.md
index 1376e4f..fd77337 100644
--- a/README.md
+++ b/README.md
@@ -65,6 +65,7 @@
         -c, --detect                 only detect if the device is connected
         -b, --bundle <bundle.app>    the path to the app bundle to be installed
         -a, --args <args>            command line arguments to pass to the app when launching it
+        -s, --envs <envs>            environment variables, space separated key-value pairs, to pass to the app when launching it
         -t, --timeout <timeout>      number of seconds to wait for a device to be connected
         -u, --unbuffered             don't buffer stdout
         -n, --nostart                do not start the app when debugging
@@ -95,6 +96,9 @@
     // deploy and debug your app to a connected device
     ios-deploy --debug --bundle my.app
 
+    // deploy, debug and pass environment variables to a connected device
+    ios-deploy --debug --envs DYLD_PRINT_STATISTICS=1 --bundle my.app
+
     // deploy and debug your app to a connected device, skipping any wi-fi connection (use USB)
     ios-deploy --debug --bundle my.app --no-wifi
 
diff --git a/src/ios-deploy/ios-deploy.m b/src/ios-deploy/ios-deploy.m
index 3efd346..f06b01a 100644
--- a/src/ios-deploy/ios-deploy.m
+++ b/src/ios-deploy/ios-deploy.m
@@ -86,6 +86,7 @@
 char *app_path = NULL;
 char *device_id = NULL;
 char *args = NULL;
+char *envs = NULL;
 char *list_root = NULL;
 int _timeout = 0;
 int _detectDeadlockTimeout = 0;
@@ -651,6 +652,22 @@
         //printf("write_lldb_prep_cmds: [%s][%s]\n", CFStringGetCStringPtr (cmds,kCFStringEncodingMacRoman),
         //    CFStringGetCStringPtr(pmodule, kCFStringEncodingMacRoman));
     }
+
+    if (envs) {
+        CFStringRef cf_envs = CFStringCreateWithCString(NULL, envs, kCFStringEncodingUTF8);
+        CFStringFindAndReplace(cmds, CFSTR("{envs}"), cf_envs, range, 0);
+        rangeLLDB.length = CFStringGetLength(pmodule);
+        CFStringFindAndReplace(pmodule, CFSTR("{envs}"), cf_envs, rangeLLDB, 0);
+
+        //printf("write_lldb_prep_cmds:envs: [%s][%s]\n", CFStringGetCStringPtr (cmds,kCFStringEncodingMacRoman),
+        //    CFStringGetCStringPtr(pmodule, kCFStringEncodingMacRoman));
+        CFRelease(cf_envs);
+    } else {
+        CFStringFindAndReplace(cmds, CFSTR("{envs}"), CFSTR(""), range, 0);
+        CFStringFindAndReplace(pmodule, CFSTR("{envs}"), CFSTR(""), rangeLLDB, 0);
+        //printf("write_lldb_prep_cmds: [%s][%s]\n", CFStringGetCStringPtr (cmds,kCFStringEncodingMacRoman),
+        //    CFStringGetCStringPtr(pmodule, kCFStringEncodingMacRoman));
+    }
     range.length = CFStringGetLength(cmds);
 
     CFStringRef bundle_identifier = copy_disk_app_identifier(disk_app_url);
@@ -1731,6 +1748,7 @@
         @"  -c, --detect                 only detect if the device is connected\n"
         @"  -b, --bundle <bundle.app>    the path to the app bundle to be installed\n"
         @"  -a, --args <args>            command line arguments to pass to the app when launching it\n"
+        @"  -s, --envs <envs>            environment variables, space separated key-value pairs, to pass to the app when launching it\n"
         @"  -t, --timeout <timeout>      number of seconds to wait for a device to be connected\n"
         @"  -u, --unbuffered             don't buffer stdout\n"
         @"  -n, --nostart                do not start the app when debugging\n"
@@ -1776,6 +1794,7 @@
         { "id", required_argument, NULL, 'i' },
         { "bundle", required_argument, NULL, 'b' },
         { "args", required_argument, NULL, 'a' },
+        { "envs", required_argument, NULL, 's' },
         { "verbose", no_argument, NULL, 'v' },
         { "timeout", required_argument, NULL, 't' },
         { "unbuffered", no_argument, NULL, 'u' },
@@ -1804,7 +1823,7 @@
     };
     int ch;
 
-    while ((ch = getopt_long(argc, argv, "VmcdvunNrILeD:R:i:b:a:t:g:x:p:1:2:o:l::w::9::B::W", longopts, NULL)) != -1)
+    while ((ch = getopt_long(argc, argv, "VmcdvunNrILeD:R:i:b:a:s:t:g:x:p:1:2:o:l::w::9::B::W", longopts, NULL)) != -1)
     {
         switch (ch) {
         case 'm':
@@ -1823,6 +1842,9 @@
         case 'a':
             args = optarg;
             break;
+        case 's':
+            envs = optarg;
+            break;
         case 'v':
             verbose = true;
             break;
diff --git a/src/scripts/lldb.py b/src/scripts/lldb.py
index 3e149aa..81f1df9 100644
--- a/src/scripts/lldb.py
+++ b/src/scripts/lldb.py
@@ -55,6 +55,12 @@
     #This env variable makes NSLog, CFLog and os_log messages get mirrored to stderr
     #https://stackoverflow.com/a/39581193 
     launchInfo.SetEnvironmentEntries(['OS_ACTIVITY_DT_MODE=enable'], True)
+
+    envs_arr = []
+    if len(args) > 1:
+        envs_arr = shlex.split(args[1])
+    envs_arr = envs_arr + shlex.split('{envs}')
+    launchInfo.SetEnvironmentEntries(envs_arr, True)
     
     lldb.target.Launch(launchInfo, error)
     lockedstr = ': Locked'