Mail Archives: cygwin/2010/11/02/16:52:35
X-Recipient: | archive-cygwin AT delorie DOT com
|
X-SWARE-Spam-Status: | No, hits=-1.5 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,T_TO_NO_BRKTS_FREEMAIL
|
X-Spam-Check-By: | sourceware.org
|
Message-Id: | <20101102205043.339395100@gmail.com>
|
User-Agent: | quilt/0.48-1
|
Date: | Tue, 02 Nov 2010 13:49:03 -0700
|
From: | dan DOT colascione AT gmail DOT com
|
To: | cygwin AT cygwin DOT com
|
Subject: | [patch 8/8] Convert between Windows and Unix paths directly on command line
|
References: | <20101102204855 DOT 153395100 AT gmail DOT com>
|
X-IsSubscribed: | yes
|
Mailing-List: | contact cygwin-help AT cygwin DOT com; run by ezmlm
|
List-Id: | <cygwin.cygwin.com>
|
List-Subscribe: | <mailto:cygwin-subscribe AT cygwin DOT com>
|
List-Archive: | <http://sourceware.org/ml/cygwin/>
|
List-Post: | <mailto:cygwin AT cygwin DOT com>
|
List-Help: | <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
|
Sender: | cygwin-owner AT cygwin DOT com
|
Mail-Followup-To: | cygwin AT cygwin DOT com
|
Delivered-To: | mailing list cygwin AT cygwin DOT com
|
Index: bash-3.2/bashline.c
===================================================================
--- bash-3.2.orig/bashline.c
+++ bash-3.2/bashline.c
@@ -37,6 +37,10 @@
# include <netdb.h>
#endif
+#if __CYGWIN__
+# include <sys/cygwin.h>
+#endif
+
#include <stdio.h>
#include "chartypes.h"
#include "bashansi.h"
@@ -342,6 +346,248 @@ enable_hostname_completion (on_or_off)
return (old_value);
}
+#if __CYGWIN__
+
+typedef enum cg_path_kind
+ {
+ CG_PATH_UNKNOWN,
+ CG_PATH_WINDOWS,
+ CG_PATH_UNIX
+ } CG_PATH_KIND;
+
+static void
+xprintwords(WORD_LIST* wl, FILE* out)
+{
+ while (wl)
+ {
+ fprintf(out, "(%d)\"%s\"", wl->word->flags, wl->word->word);
+ wl = wl->next;
+ if (wl) {
+ fprintf(out, ", ");
+ }
+ }
+}
+
+/*
+ * Guess what kind of path the given word is
+ */
+static CG_PATH_KIND
+cg_guess_path_kind (wdesc)
+ WORD_DESC *wdesc;
+{
+ char* w = wdesc->word;
+ char prev, cur, next;
+
+ /* If a filename contains a forward slash, it's probably a unix
+ path */
+ if (strchr(w, '/'))
+ return CG_PATH_UNIX;
+
+ /* Skip leading quote characters */
+ while (w[0] == '\'' || w[0] == '"')
+ ++w;
+
+ /* UNC absolute path */
+ if (w[0] == '\\' && w[1] == '\\')
+ return CG_PATH_WINDOWS;
+
+ /* Drive-letter-relative path */
+ if (isalpha (w[0]) && w[1] == ':' && w[2] == '\\')
+ return CG_PATH_WINDOWS;
+
+ prev = '\0';
+ cur = w[0];
+ next = cur ? w[1] : '\0';
+
+ /* If a filename contains a Windows-like backslash,
+ it's probably Windows */
+ while (next)
+ {
+ if (cur == '/' && isalnum (prev) && isalnum (next))
+ return CG_PATH_WINDOWS;
+
+ prev = cur;
+ cur = next;
+ next = *(w++);
+ }
+
+ return CG_PATH_UNKNOWN;
+}
+
+static WORD_LIST*
+cg_dwim_expand_words (wl)
+ WORD_LIST *wl;
+{
+ WORD_LIST *out = NULL;
+ WORD_LIST *it;
+
+ wl = copy_word_list (wl);
+
+ for (it = wl; it; it = it->next)
+ {
+ char* w = it->word->word;
+
+ /* If w has suspicious-looking backslahes, single-quote the
+ whole word. */
+ CG_PATH_KIND tkind = cg_guess_path_kind(it->word);
+
+ if (tkind == CG_PATH_WINDOWS &&
+ w[0] != '\'' && w[0] != '"')
+ {
+ it->word->word = sh_single_quote(w);
+ free(w);
+ }
+ }
+
+ out = expand_words (wl);
+ dispose_words (wl);
+ return out;
+}
+
+static CG_PATH_KIND
+cg_guess_conv_target(wl)
+ WORD_LIST *wl;
+{
+ for (; wl; wl = wl->next)
+ {
+ switch (cg_guess_path_kind(wl->word))
+ {
+ case CG_PATH_WINDOWS:
+ return CG_PATH_UNIX;
+
+ case CG_PATH_UNIX:
+ return CG_PATH_WINDOWS;
+
+ default:
+ ;
+ }
+ }
+
+ return CG_PATH_UNKNOWN;
+}
+
+/* Replace text between POS_BEG and POS_END with result of converting
+ all words in DATA to TARGET and joining them with a space.
+
+ Return the length of the replacement string. */
+static int
+cg_do_conv (data, target, pos_beg, pos_end)
+ WORD_LIST *data;
+ CG_PATH_KIND target;
+ int pos_beg;
+ int pos_end;
+{
+ cygwin_conv_path_t conv_dir =
+ (target == CG_PATH_WINDOWS)
+ ? CCP_POSIX_TO_WIN_A
+ : CCP_WIN_A_TO_POSIX;
+
+ rl_begin_undo_group();
+ rl_delete_text(pos_beg, pos_end);
+ rl_point = pos_beg;
+
+ conv_dir |= CCP_RELATIVE;
+
+ for (; data; data = data->next)
+ {
+ char *s = cygwin_create_path(conv_dir, data->word->word);
+ char *quoted;
+
+ if (s)
+ {
+ quoted = sh_single_quote(s);
+ rl_insert_text (quoted);
+
+ if (data->next)
+ {
+ rl_insert_text (" ");
+ }
+ }
+
+ free(s);
+ free(quoted);
+ }
+
+ rl_end_undo_group();
+
+ return rl_point - pos_beg;
+}
+
+/* Let user toggle between unix and windows path representations */
+static int
+cg_dwim (count, ignore)
+ int count, ignore;
+{
+ static CG_PATH_KIND cg_conv_target;
+ static WORD_LIST *lw_data;
+ static int pos_beg;
+ static int pos_end;
+
+ if (lw_data && rl_last_func == &cg_dwim)
+ {
+ /* Reuse information from last run and just toggle the
+ conversion direction */
+ if (cg_conv_target == CG_PATH_UNIX)
+ cg_conv_target = CG_PATH_WINDOWS;
+ else
+ cg_conv_target = CG_PATH_UNIX;
+ }
+ else
+ {
+ int orig_pos;
+ char *ss = NULL;
+ WORD_LIST *lw = NULL;
+ int pos2;
+
+ /* Slurp up words */
+ while (rl_point > 0 && whitespace (rl_line_buffer[rl_point - 1]))
+ --rl_point;
+
+ orig_pos = rl_point;
+
+ do {
+ bash_backward_shellword (1, -1);
+ pos2 = rl_point;
+
+ while (pos2 < orig_pos && whitespace (rl_line_buffer[pos2]))
+ ++pos2;
+
+ dispose_words (lw);
+ free (ss);
+
+ ss = substring (rl_line_buffer, pos2, orig_pos);
+ lw = list_string_with_quotes (ss);
+
+ } while(list_length (lw) < count && rl_point > 0);
+
+ if (lw == NULL)
+ {
+ free (ss);
+ return 0;
+ }
+
+ rl_point = pos2;
+
+ pos_beg = rl_point;
+ pos_end = orig_pos;
+
+ dispose_words (lw_data);
+ lw_data = cg_dwim_expand_words(lw);
+
+ cg_conv_target = cg_guess_conv_target(lw_data);
+
+ if (cg_conv_target == CG_PATH_UNKNOWN)
+ cg_conv_target = CG_PATH_WINDOWS; /* Arbitrary default */
+ }
+
+ pos_end =
+ pos_beg +
+ cg_do_conv(lw_data, cg_conv_target, pos_beg, pos_end);
+ return 0;
+}
+
+#endif /* __CYGWIN __ */
+
/* Called once from parse.y if we are going to use readline. */
void
initialize_readline ()
@@ -379,6 +625,10 @@ initialize_readline ()
# endif
#endif
+#if __CYGWIN__
+ rl_add_defun ("cygpath-dwim", cg_dwim, -1);
+#endif
+
/* Backwards compatibility. */
rl_add_defun ("insert-last-argument", rl_yank_last_arg, -1);
@@ -439,6 +689,10 @@ initialize_readline ()
rl_unbind_key_in_map (CTRL('E'), vi_movement_keymap);
#endif
+#if __CYGWIN__
+ rl_bind_key_if_unbound_in_map (CTRL('W'), cg_dwim, emacs_ctlx_keymap);
+#endif
+
#if defined (BRACE_COMPLETION)
rl_bind_key_if_unbound_in_map ('{', bash_brace_completion, emacs_meta_keymap); /*}*/
#endif /* BRACE_COMPLETION */
Index: bash-3.2/subst.c
===================================================================
--- bash-3.2.orig/subst.c
+++ bash-3.2/subst.c
@@ -2271,8 +2271,6 @@ strip_trailing_ifs_whitespace (string, s
return string;
}
-#if 0
-/* UNUSED */
/* Split STRING into words at whitespace. Obeys shell-style quoting with
backslashes, single and double quotes. */
WORD_LIST *
@@ -2324,7 +2322,6 @@ list_string_with_quotes (string)
}
return (REVERSE_LIST (list, WORD_LIST *));
}
-#endif
/********************************************************/
/* */
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
- Raw text -