diff --git a/etc/getVariables.py b/etc/getVariables.py new file mode 100755 index 000000000..64a9e2a0a --- /dev/null +++ b/etc/getVariables.py @@ -0,0 +1,225 @@ +#! /usr/bin/env python + +# This file sources the etc bashrc, finds the differences to the old +# configuration and makes them available in a format that the calling +# shell can understand +# + +import sys + +# This part is lifted from six.py (https://pythonhosted.org/six/) to +# make sure that this script runs with Python 2 and Python 3 + +# True if we are running on Python 3. +PY3 = sys.version_info[0] == 3 + +if PY3: + import builtins + print_ = getattr(builtins, "print") + del builtins +else: + def print_(*args, **kwargs): + """The new-style print function.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + def write(data): + if not isinstance(data, basestring): + data = str(data) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) + +# the actual work starts here +from os import environ,path + +if sys.version_info<(2,6): + from popen2 import popen4 +else: + from subprocess import Popen,PIPE,STDOUT + +verbose="FOAM_NEW_STARTUP_DEBUG" in environ +here=path.dirname(path.abspath(sys.argv[0])) +if verbose: + print_("Using scripts in",here) +destShell=sys.argv[1] +additional=sys.argv[2:] +if verbose: + print("Target shell",destShell) + print("Additional settings:",additional) + +# Certain bashrc-s fail if these are set +for v in ["FOAM_INST_DIR", + "WM_THIRD_PARTY_DIR", + "WM_PROJECT_USER_DIR", + "OPAL_PREFIX"]: + try: + del environ[v] + except KeyError: + pass + +cmd ='echo "=== Export pre";export;echo "=== Alias pre";alias;' +cmd+='echo "=== Script";. '+path.join(here,"bashrc")+' '+' '.join(additional)+';' +cmd+='echo "=== Export post";export;echo "=== Alias post";alias;' +cmd+='echo "=== End"' + +if verbose: + print_("Cmd:",cmd) + +if sys.version_info<(2,6): + raus,rein = popen4(cmd) +else: + p = Popen(cmd, shell=True, + stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) + (rein,raus)=(p.stdin,p.stdout) + +lines=[l.strip().decode() for l in raus.readlines()] +rein.close() +raus.close() + +if verbose: + print_("========= Script output start") + for l in lines: + print_(l) + print_("========= Script output end") + +def extractVariables(lines): + vars={} + for l in lines: + pos=l.find("=") + name=l[len("export "):pos] + if pos>0: + val=l[pos+1:] + if val[0]=='"' and val[-1]=='"': + val=val[1:-1] + else: + val="" + vars[name]=val + + return vars + +def extractAliases(lines): + aliases={} + for l in lines: + pos=l.find("=") + aliases[l[:pos]]=l[pos+2:-1] + + return aliases + +def changedVars(old,new): + changed={} + for k in new: + if k not in old: + changed[k]=new[k] + elif old[k]!=new[k]: + changed[k]=new[k] + return changed + +def splitPaths(orig): + new={} + for k in orig.keys(): + if k.find("PATH")>=0 and orig[k].find(":")>=0: + new[k]=orig[k].split(":") + else: + new[k]=orig[k] + return new + +vars=splitPaths( + changedVars(extractVariables(lines[lines.index("=== Export pre")+1: + lines.index("=== Alias pre")]), + extractVariables(lines[lines.index("=== Export post")+1: + lines.index("=== Alias post")]))) +aliases=changedVars(extractAliases(lines[lines.index("=== Alias post")+1: + lines.index("=== Script")]), + extractAliases(lines[lines.index("=== Alias post")+1: + lines.index("=== End")])) + +scriptOutput=lines[lines.index("=== Script")+1: + lines.index("=== Export post")] + +if len(scriptOutput)>0: + for l in scriptOutput: + print_("Script output:",l,file=sys.stderr) + +class ShellConvert(object): + def __call__(self,vars,aliases): + for v in sorted(vars.keys()): + print_(self.toVar(v,vars[v])) + for a in sorted(aliases.keys()): + print_(self.toAlias(a,aliases[a])) + +class BashConvert(ShellConvert): + def toVar(self,n,v): + if type(v)==list: + val=":".join(v) + else: + val=v + return 'export %s=%s' % (n,val) + + def toAlias(self,n,v): + return "alias %s='%s'" % (n,v) + +class CshConvert(ShellConvert): + def toVar(self,n,v): + if type(v)==list: + val=":".join(v) + else: + val=v + result='setenv %s "%s"' % (n,val) + if n=="PATH": + result+="\nset path (%s)" % " ".join(v) + return result + + def toAlias(self,n,v): + val=v.replace(" . ","source ").replace("bash","csh") + if val.find("unset ")>=0: + val=val.replace("unset ","unsetenv ") + # Make sure that more than one export is possible and no wrong = is replaced + while val.find("export ")>=0: + pos=val.find("export ") + val=val.replace("export ","setenv ",1) + val=val[:pos]+val[pos:].replace("="," ",1) + return "alias %s '%s'" % (n,val) + +class ZshConvert(BashConvert): + def toAlias(self,n,v): + return BashConvert.toAlias(self,n,v).replace("bash","zsh") + +shells={"bash":BashConvert, + "zsh":ZshConvert, + "csh":CshConvert} + +shells[destShell]()(vars,aliases) diff --git a/etc/zshrc b/etc/zshrc new file mode 100755 index 000000000..4031ece29 --- /dev/null +++ b/etc/zshrc @@ -0,0 +1,40 @@ +#! /usr/bin/env zsh +#----------------------------------*-sh-*-------------------------------------- +# ========= | +# \\ / F ield | foam-extend: Open Source CFD +# \\ / O peration | +# \\ / A nd | For copyright notice see file Copyright +# \\/ M anipulation | +#------------------------------------------------------------------------------ +# License +# This file is part of foam-extend. +# +# foam-extend is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# foam-extend is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with foam-extend. If not, see . +# +# Script +# etc/zshrc +# +# Description +# Startup file for OpenFOAM +# Sourced from ~/.zprofile or ~/.zshrc +# Should be usable by any POSIX-compliant shell but actually used as a +# proof-of-concept for the new shell-scripts +# +#------------------------------------------------------------------------------ + +thisScript=$0 +thisDir=`python -c "from os.path import *;import sys;sys.stdout.write(dirname(abspath(join(curdir,'$thisScript'))))"` +source <($thisDir/getVariables.py zsh $*) + +# -----------------------------------------------------------------------------