####################################################################### BioSimSpace: Making biomolecular simulation a breeze!## Copyright: 2017-2024## Authors: Christopher Woods <chryswoods@hey.com>## BioSimSpace 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.## BioSimSpace 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 BioSimSpace. If not, see <http://www.gnu.org/licenses/>.#####################################################################"""Custom context managers."""__author__="Christopher Woods"__email__="chryswoods@hey.com"__all__=["command_split"]
[docs]defcommand_split(command):""" Cross platform version of 'shlex.split'. This will split the passed command into parts, doing the right thing on Linux, MacOS and Windows. """importsysifsys.platform!="win32":# We can just use shlex.split - it is only windows that is annoying!importshlexreturnshlex.split(command)# thanks for inspiration to kxr on this stackoverflow post# https://stackoverflow.com/questions/33560364/python-windows-parsing-command-lines-with-shleximportreregex=r""""((?:""|\\["\\]|[^"])*)"?()|(\\\\(?=\\*")|\\")|(&&?|\|\|?|\d?>|[<])|([^\s"&|<>]+)|(\s+)|(.)"""args=[]accumulated=Noneforqs,qss,esc,pipe,word,white,failinre.findall(regex,command):ifword:pass# most frequentelifesc:word=esc[1]elifwhiteorpipe:ifaccumulatedisnotNone:args.append(accumulated)ifpipe:args.append(pipe)accumulated=Nonecontinueeliffail:raiseValueError("invalid or incomplete shell string")elifqs:word=qs.replace('\\"','"').replace("\\\\","\\")word=word.replace('""','"')else:word=qss# may be even empty; must be lastaccumulated=(accumulatedor"")+wordifaccumulatedisnotNone:args.append(accumulated)returnargs