1#! /bin/sh
2#
3# c2z - environment conversion tool
4# Contributed by Bart Schaefer
5# (Tweaked a bit by Paul Falstad)
6# (Tweaked again by Bart Schaefer)
7#
8# This is a quick script to convert csh aliases to zsh aliases/functions.
9# It also converts the csh environment and local variables to zsh.  c2z
10# uses the csh to parse its own dot-files, then processes csh output to
11# convert the csh settings to zsh.
12#
13# When run as a zsh fuction, c2z runs csh as if it were an interactive
14# shell whenever the parent zsh is interactive.  When run as a shell
15# script, the -i switch can be used to force this behavior.
16#
17# The -l (login) switch causes csh to run as if it were a login shell.
18# This is done "properly" if c2z is used as a zsh function, otherwise
19# it's faked by explicitly sourcing .login.  Use with caution if your
20# .login initializes an X server or does other one-time-only startup
21# procedures.
22#
23# usage:
24#	c2z [-i | -l | filename]
25#
26# You can use this script in your .zshrc or .zlogin files to load your
27# regular csh environment into zsh; for example, in .zlogin:
28#
29#	. =(c2z -l)
30#
31# This is not perfect, but it gets most common aliases and variables.
32# It's also rather time-consuming to do this every time you log in.
33# However, if you're moving from csh to zsh for the first time, this
34# can get you started with a familiar environment right away.
35#
36# In case your mailer eats tabs, $T is set to expand to a tab.
37#
38T="`echo x | tr x '\011'`"
39
40# If we're zsh, we can run "- csh" to get the complete environment.
41#
42MINUS=""
43LOADFILE=""
44INTERACT=""
45CSH=csh
46case "$ZSH_NAME$ZSH_VERSION$VERSION" in
47zsh*)
48    case $1 in
49    -l*) MINUS="-" ;;
50    -i*) INTERACT="-i" ;;
51    *) LOADFILE="source $1" CSH="csh -f";;
52    esac
53    if [[ -o INTERACTIVE ]]; then INTERACT="-i"; fi
54    setopt nobanghist
55    ;;
56*)
57    case $1 in
58    -l*) LOADFILE="source ~/.login" ;;
59    -i*) INTERACT="-i" ;;
60    *) LOADFILE="source $1" CSH="csh -f";;
61    esac
62    ;;
63esac
64
65( eval $MINUS $CSH $INTERACT ) <<EOF 2>&1 >/dev/null
66$LOADFILE
67alias >! /tmp/cz$$.a
68setenv >! /tmp/cz$$.e
69set >! /tmp/cz$$.v
70EOF
71
72# save stdin
73exec 9<&0
74
75# First convert aliases
76exec < /tmp/cz$$.a
77
78# Taken straight from ctoz except for $T and "alias --"
79sed -e 's/'"$T"'(\(.*\))/'"$T"'\1/' >/tmp/cz$$.1
80grep ! /tmp/cz$$.1 >/tmp/cz$$.2
81grep -v ! /tmp/cz$$.1 >/tmp/cz$$.3
82sed -e "s/'/'"\\\\"''"/g \
83    -e 's/^\([^'"$T"']*\)'"$T"'\(.*\)$/alias -- \1='"'\2'/" \
84    /tmp/cz$$.3
85sed -e 's/>\(&*\)!/>\1|/g' \
86    -e 's/!\*:q/"$@"/g' \
87    -e 's/\(![:#]*[^'"$T"']*\):q/"\1"/g' \
88    -e 's/!\([-0-9][0-9]*\)\(:x\)*/$\2(fc -nl \1)/g' \
89    -e 's/\$:x(fc/$=(fc/g' \
90    -e 's/![:#]*\([^'"$T"']\)/$==\1/g' \
91    -e 's/\$=\(=[^'"$T"']*\):x/$\1/g' \
92    -e 's/\$cwd/$PWD/' \
93    -e 's/^\([^'"$T"']*\)'"$T"'\(.*\)$/\1 () { \2 }/' \
94    /tmp/cz$$.2
95
96# Next, convert environment variables
97exec < /tmp/cz$$.e
98
99# Would be nice to deal with embedded newlines, e.g. in TERMCAP, but ...
100sed -e '/^SHLVL/d' \
101    -e '/^PWD/d' \
102    -e '/^_=/d' \
103    -e "s/'/'"\\\\"''"/g \
104    -e "s/^\([A-Za-z0-9_]*=\)/export \1'/" \
105    -e "s/$/'/"
106
107# Finally, convert local variables
108exec < /tmp/cz$$.v
109
110sed -e 's/'"$T"'/=/' \
111    -e "s/'/'"\\\\"''"/g \
112    -e '/^[A-Za-z0-9_]*=[^(]/{
113	s/=/='"'/"'
114	s/$/'"'/"'
115	}' |
116sed -e '/^argv=/d' -e '/^cwd=/d' -e '/^filec=/d' -e '/^status=/d' \
117	 -e '/^autolist=/s/.*/setopt autolist/' \
118	 -e '/^correct=all/s//setopt correctall/' \
119	 -e '/^correct=/s//setopt correct/' \
120	 -e '/^histchars=/s//HISTCHARS=/' \
121	 -e '/^history=/s//HISTSIZE=/' \
122	 -e '/^home=/s//HOME=/' \
123	 -e '/^ignoreeof=/s/.*/setopt ignoreeof/' \
124	 -e '/^noclobber=/s/.*/setopt noclobber/' \
125	 -e '/^notify=/d' \
126	 -e '/^prompt=/s/!/%h/' \
127	 -e 's/^prompt/PROMPT/' \
128	 -e '/^showdots=/s/.*/setopt globdots/' \
129	 -e '/^savehist=/s//HISTFILE=\~\/.zhistory SAVEHIST=/' \
130	 -e '/^who=/s//WATCHFMT=/'
131
132
133exec 0<&9
134
135rm /tmp/cz$$.?
136exit
137