1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """ A file containing different extension of the cmd basic python library"""
16
17
18 import logging
19 import os
20 import pydoc
21 import re
22 import signal
23 import subprocess
24 import sys
25 import traceback
26 try:
27 import readline
28 GNU_SPLITTING = ('GNU' in readline.__doc__)
29 except:
30 readline = None
31 GNU_SPLITTING = True
32
33
34 logger = logging.getLogger('cmdprint')
35 logger_stderr = logging.getLogger('fatalerror')
36
37 try:
38 import madgraph.various.misc as misc
39 from madgraph import MG5DIR
40 MADEVENT = False
41 except ImportError, error:
42 try:
43 import internal.misc as misc
44 except:
45 raise error
46
47 MADEVENT = True
48
49
50 pjoin = os.path.join
53 """Class for run-time error"""
54
55 -def debug(debug_only=True):
56
57 def deco_debug(f):
58
59 if debug_only and not __debug__:
60 return f
61
62 def deco_f(*args, **opt):
63 try:
64 return f(*args, **opt)
65 except Exception, error:
66 logger.error(error)
67 logger.error(traceback.print_exc(file=sys.stdout))
68 return
69 return deco_f
70 return deco_debug
71
72 import string
73
74
75 __all__ = ["Cmd"]
76 PROMPT = '(Cmd) '
77 IDENTCHARS = string.ascii_letters + string.digits + '_'
79 """A simple framework for writing line-oriented command interpreters.
80
81 These are often useful for test harnesses, administrative tools, and
82 prototypes that will later be wrapped in a more sophisticated interface.
83
84 A Cmd instance or subclass instance is a line-oriented interpreter
85 framework. There is no good reason to instantiate Cmd itself; rather,
86 it's useful as a superclass of an interpreter class you define yourself
87 in order to inherit Cmd's methods and encapsulate action methods.
88
89 """
90 prompt = PROMPT
91 identchars = IDENTCHARS
92 ruler = '='
93 lastcmd = ''
94 intro = None
95 doc_leader = ""
96 doc_header = "Documented commands (type help <topic>):"
97 misc_header = "Miscellaneous help topics:"
98 undoc_header = "Undocumented commands:"
99 nohelp = "*** No help on %s"
100 use_rawinput = 1
101
102 - def __init__(self, completekey='tab', stdin=None, stdout=None,**opt):
103 """Instantiate a line-oriented interpreter framework.
104
105 The optional argument 'completekey' is the readline name of a
106 completion key; it defaults to the Tab key. If completekey is
107 not None and the readline module is available, command completion
108 is done automatically. The optional arguments stdin and stdout
109 specify alternate input and output file objects; if not specified,
110 sys.stdin and sys.stdout are used.
111
112 """
113 import sys
114 if stdin is not None:
115 self.stdin = stdin
116 else:
117 self.stdin = sys.stdin
118 if stdout is not None:
119 self.stdout = stdout
120 else:
121 self.stdout = sys.stdout
122 self.cmdqueue = []
123 self.completekey = completekey
124 self.cmd_options = opt
125
127 """Repeatedly issue a prompt, accept input, parse an initial prefix
128 off the received input, and dispatch to action methods, passing them
129 the remainder of the line as argument.
130
131 """
132
133 self.preloop()
134 if self.use_rawinput and self.completekey:
135 try:
136 import readline
137 self.old_completer = readline.get_completer()
138 readline.set_completer(self.complete)
139 readline.parse_and_bind(self.completekey+": complete")
140 except ImportError:
141 pass
142 try:
143 if intro is not None:
144 self.intro = intro
145 if self.intro:
146 self.stdout.write(str(self.intro)+"\n")
147 stop = None
148 while not stop:
149 if self.cmdqueue:
150 line = self.cmdqueue.pop(0)
151 else:
152 if self.use_rawinput:
153 try:
154 line = raw_input(self.prompt)
155 except EOFError:
156 line = 'EOF'
157 else:
158 self.stdout.write(self.prompt)
159 self.stdout.flush()
160 line = self.stdin.readline()
161 if not len(line):
162 line = 'EOF'
163 else:
164 line = line.rstrip('\r\n')
165 line = self.precmd(line)
166 stop = self.onecmd(line)
167 stop = self.postcmd(stop, line)
168 self.postloop()
169 finally:
170 if self.use_rawinput and self.completekey:
171 try:
172 import readline
173 readline.set_completer(self.old_completer)
174 except ImportError:
175 pass
176
177
179 """Hook method executed just before the command line is
180 interpreted, but after the input prompt is generated and issued.
181
182 """
183 return line
184
185 - def postcmd(self, stop, line):
186 """Hook method executed just after a command dispatch is finished."""
187 return stop
188
190 """Hook method executed once when the cmdloop() method is called."""
191 pass
192
193 - def postloop(self):
194 """Hook method executed once when the cmdloop() method is about to
195 return.
196
197 """
198 pass
199
201 """Parse the line into a command name and a string containing
202 the arguments. Returns a tuple containing (command, args, line).
203 'command' and 'args' may be None if the line couldn't be parsed.
204 """
205 line = line.strip()
206 if not line:
207 return None, None, line
208 elif line[0] == '?':
209 line = 'help ' + line[1:]
210 elif line[0] == '!':
211 if hasattr(self, 'do_shell'):
212 line = 'shell ' + line[1:]
213 else:
214 return None, None, line
215 i, n = 0, len(line)
216 while i < n and line[i] in self.identchars: i = i+1
217 cmd, arg = line[:i], line[i:].strip()
218 return cmd, arg, line
219
221 """Interpret the argument as though it had been typed in response
222 to the prompt.
223
224 This may be overridden, but should not normally need to be;
225 see the precmd() and postcmd() methods for useful execution hooks.
226 The return value is a flag indicating whether interpretation of
227 commands by the interpreter should stop.
228
229 """
230 cmd, arg, line = self.parseline(line)
231 if not line:
232 return self.emptyline()
233 if cmd is None:
234 return self.default(line)
235 self.lastcmd = line
236 if cmd == '':
237 return self.default(line)
238 else:
239 try:
240 func = getattr(self, 'do_' + cmd)
241 except AttributeError:
242 return self.default(line)
243 return func(arg)
244
246 """Called when an empty line is entered in response to the prompt.
247
248 If this method is not overridden, it repeats the last nonempty
249 command entered.
250
251 """
252 if self.lastcmd:
253 return self.onecmd(self.lastcmd)
254
256 """Called on an input line when the command prefix is not recognized.
257
258 If this method is not overridden, it prints an error message and
259 returns.
260
261 """
262 self.stdout.write('*** Unknown syntax: %s\n'%line)
263
265 """Method called to complete an input line when no command-specific
266 complete_*() method is available.
267
268 By default, it returns an empty list.
269
270 """
271 return []
272
274 dotext = 'do_'+text
275
276 done = set()
277
278 return [a[3:] for a in self.get_names()
279 if a.startswith(dotext) and a not in done and not done.add(a)]
280
282 """Return the next possible completion for 'text'.
283
284 If a command has not been entered, then complete against command list.
285 Otherwise try to call complete_<command> to get list of completions.
286 """
287 if state == 0:
288 import readline
289 origline = readline.get_line_buffer()
290 line = origline.lstrip()
291 stripped = len(origline) - len(line)
292 begidx = readline.get_begidx() - stripped
293 endidx = readline.get_endidx() - stripped
294 if begidx>0:
295 cmd, args, foo = self.parseline(line)
296 if cmd == '':
297 compfunc = self.completedefault
298 else:
299 try:
300 compfunc = getattr(self, 'complete_' + cmd)
301 except AttributeError:
302 compfunc = self.completedefault
303 else:
304 compfunc = self.completenames
305 self.completion_matches = compfunc(text, line, begidx, endidx)
306 try:
307 return self.completion_matches[state]
308 except IndexError:
309 return None
310
312
313
314 names = []
315 classes = [self.__class__]
316 while classes:
317 aclass = classes.pop(0)
318 if aclass.__bases__:
319 classes = classes + list(aclass.__bases__)
320 names = names + dir(aclass)
321 return names
322
325
327 if arg:
328
329 try:
330 func = getattr(self, 'help_' + arg)
331 except AttributeError:
332 try:
333 doc=getattr(self, 'do_' + arg).__doc__
334 if doc:
335 self.stdout.write("%s\n"%str(doc))
336 return
337 except AttributeError:
338 pass
339 self.stdout.write("%s\n"%str(self.nohelp % (arg,)))
340 return
341 func()
342 else:
343 names = self.get_names()
344 cmds_doc = []
345 cmds_undoc = []
346 help = {}
347 for name in names:
348 if name[:5] == 'help_':
349 help[name[5:]]=1
350 names.sort()
351
352 prevname = ''
353 for name in names:
354 if name[:3] == 'do_':
355 if name == prevname:
356 continue
357 prevname = name
358 cmd=name[3:]
359 if cmd in help:
360 cmds_doc.append(cmd)
361 del help[cmd]
362 elif getattr(self, name).__doc__:
363 cmds_doc.append(cmd)
364 else:
365 cmds_undoc.append(cmd)
366 self.stdout.write("%s\n"%str(self.doc_leader))
367 self.print_topics(self.doc_header, cmds_doc, 15,80)
368 self.print_topics(self.misc_header, help.keys(),15,80)
369 self.print_topics(self.undoc_header, cmds_undoc, 15,80)
370
378
380 """Display a list of strings as a compact set of columns.
381
382 Each column is only as wide as necessary.
383 Columns are separated by two spaces (one was not legible enough).
384 """
385 if not list:
386 self.stdout.write("<empty>\n")
387 return
388 nonstrings = [i for i in range(len(list))
389 if not isinstance(list[i], str)]
390 if nonstrings:
391 raise TypeError, ("list[i] not a string for i in %s" %
392 ", ".join(map(str, nonstrings)))
393 size = len(list)
394 if size == 1:
395 self.stdout.write('%s\n'%str(list[0]))
396 return
397
398 for nrows in range(1, len(list)):
399 ncols = (size+nrows-1) // nrows
400 colwidths = []
401 totwidth = -2
402 for col in range(ncols):
403 colwidth = 0
404 for row in range(nrows):
405 i = row + nrows*col
406 if i >= size:
407 break
408 x = list[i]
409 colwidth = max(colwidth, len(x))
410 colwidths.append(colwidth)
411 totwidth += colwidth + 2
412 if totwidth > displaywidth:
413 break
414 if totwidth <= displaywidth:
415 break
416 else:
417 nrows = len(list)
418 ncols = 1
419 colwidths = [0]
420 for row in range(nrows):
421 texts = []
422 for col in range(ncols):
423 i = row + nrows*col
424 if i >= size:
425 x = ""
426 else:
427 x = list[i]
428 texts.append(x)
429 while texts and not texts[-1]:
430 del texts[-1]
431 for col in range(len(texts)):
432 texts[col] = texts[col].ljust(colwidths[col])
433 self.stdout.write("%s\n"%str(" ".join(texts)))
434
435
436
437
438
439
440
441 -class BasicCmd(OriginalCmd):
442 """Simple extension for the readline"""
443
445 """ This has been refactorized here so that it can be called when another
446 program called by MG5 (such as MadAnalysis5) changes this attribute of readline"""
447 if readline and not 'libedit' in readline.__doc__:
448 readline.set_completion_display_matches_hook(self.print_suggestions)
449 else:
450 readline.set_completion_display_matches_hook()
451
455
457 """convert the multiple category in a formatted list understand by our
458 specific readline parser"""
459
460 if not formatting:
461 return dico
462
463 if 'libedit' in readline.__doc__:
464
465 out = []
466 for name, opt in dico.items():
467 out += opt
468 return out
469
470
471 if not forceCategory and all(len(s) <= 1 for s in dico.values() ):
472 values = set((s[0] for s in dico.values() if len(s)==1))
473 if len(values) == 1:
474 return values
475
476
477 out = []
478 valid=0
479
480 for name, opt in dico.items():
481 if not opt:
482 continue
483 name = name.replace(' ', '_')
484 valid += 1
485 out.append(opt[0].rstrip()+'@@'+name+'@@')
486
487 d = {}
488 for x in opt:
489 d[x] = 1
490 opt = list(d.keys())
491 opt.sort()
492 out += opt
493
494 if not forceCategory and valid == 1:
495 out = out[1:]
496
497 return out
498
499 @debug()
501 """print auto-completions by category"""
502 if not hasattr(self, 'completion_prefix'):
503 self.completion_prefix = ''
504 longest_match_length += len(self.completion_prefix)
505 try:
506 if len(matches) == 1:
507 self.stdout.write(matches[0]+' ')
508 return
509 self.stdout.write('\n')
510 l2 = [a[-2:] for a in matches]
511 if '@@' in l2:
512 nb_column = self.getTerminalSize()//(longest_match_length+1)
513 pos=0
514 for val in self.completion_matches:
515 if val.endswith('@@'):
516 category = val.rsplit('@@',2)[1]
517 category = category.replace('_',' ')
518 self.stdout.write('\n %s:\n%s\n' % (category, '=' * (len(category)+2)))
519 start = 0
520 pos = 0
521 continue
522 elif pos and pos % nb_column ==0:
523 self.stdout.write('\n')
524 self.stdout.write(self.completion_prefix + val + \
525 ' ' * (longest_match_length +1 -len(val)))
526 pos +=1
527 self.stdout.write('\n')
528 else:
529
530 nb_column = self.getTerminalSize()//(longest_match_length+1)
531 for i,val in enumerate(matches):
532 if i and i%nb_column ==0:
533 self.stdout.write('\n')
534 self.stdout.write(self.completion_prefix + val + \
535 ' ' * (longest_match_length +1 -len(val)))
536 self.stdout.write('\n')
537
538 self.stdout.write(self.prompt+readline.get_line_buffer())
539 self.stdout.flush()
540 except Exception, error:
541 if __debug__:
542 logger.error(error)
543
545 def ioctl_GWINSZ(fd):
546 try:
547 import fcntl, termios, struct
548 cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
549 '1234'))
550 except Exception:
551 return None
552 return cr
553 cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
554 if not cr:
555 try:
556 fd = os.open(os.ctermid(), os.O_RDONLY)
557 cr = ioctl_GWINSZ(fd)
558 os.close(fd)
559 except Exception:
560 pass
561 if not cr:
562 try:
563 cr = (os.environ['LINES'], os.environ['COLUMNS'])
564 except Exception:
565 cr = (25, 80)
566 return int(cr[1])
567
569 """Return the next possible completion for 'text'.
570 If a command has not been entered, then complete against command list.
571 Otherwise try to call complete_<command> to get list of completions.
572 """
573 if state == 0:
574 import readline
575 origline = readline.get_line_buffer()
576 line = origline.lstrip()
577 stripped = len(origline) - len(line)
578 begidx = readline.get_begidx() - stripped
579 endidx = readline.get_endidx() - stripped
580
581 if ';' in line:
582 begin, line = line.rsplit(';',1)
583 begidx = begidx - len(begin) - 1
584 endidx = endidx - len(begin) - 1
585 if line[:begidx] == ' ' * begidx:
586 begidx=0
587
588 if begidx>0:
589 cmd, args, foo = self.parseline(line)
590 if cmd == '':
591 compfunc = self.completedefault
592 else:
593 try:
594 compfunc = getattr(self, 'complete_' + cmd)
595 except AttributeError, error:
596 compfunc = self.completedefault
597 except Exception, error:
598 misc.sprint(error)
599 else:
600 compfunc = self.completenames
601
602
603 if line and begidx > 2 and line[begidx-2:begidx] == '\ ':
604 Ntext = line.split(os.path.sep)[-1]
605 self.completion_prefix = Ntext.rsplit('\ ', 1)[0] + '\ '
606 to_rm = len(self.completion_prefix) - 1
607 Nbegidx = len(line.rsplit(os.path.sep, 1)[0]) + 1
608 data = compfunc(Ntext.replace('\ ', ' '), line, Nbegidx, endidx)
609 self.completion_matches = [p[to_rm:] for p in data
610 if len(p)>to_rm]
611
612 elif line and line[begidx-1] in ['-',"=",':']:
613 try:
614 sep = line[begidx-1]
615 Ntext = line.split()[-1]
616 self.completion_prefix = Ntext.rsplit(sep,1)[0] + sep
617 to_rm = len(self.completion_prefix)
618 Nbegidx = len(line.rsplit(None, 1)[0])
619 data = compfunc(Ntext, line, Nbegidx, endidx)
620 self.completion_matches = [p[to_rm:] for p in data
621 if len(p)>to_rm]
622 except Exception, error:
623 print error
624 else:
625 self.completion_prefix = ''
626 self.completion_matches = compfunc(text, line, begidx, endidx)
627
628 self.completion_matches = [ l if l[-1] in [' ','@','=',os.path.sep]
629 else ((l + ' ') if not l.endswith('\\$') else l[:-2])
630 for l in self.completion_matches if l]
631
632 try:
633 return self.completion_matches[state]
634 except IndexError, error:
635
636
637
638 return None
639
640 @staticmethod
642 """Split a line of arguments"""
643
644 split = line.split()
645 out=[]
646 tmp=''
647 for data in split:
648 if data[-1] == '\\':
649 tmp += data[:-1]+' '
650 elif tmp:
651 tmp += data
652 tmp = os.path.expanduser(os.path.expandvars(tmp))
653 out.append(tmp)
654
655
656 tmp = ''
657 else:
658 out.append(data)
659 return out
660
661 @staticmethod
663 """Propose completions of text in list"""
664
665 if not text:
666 completions = list
667 else:
668 completions = [ f
669 for f in list
670 if f.startswith(text)
671 ]
672
673 return completions
674
675
676 @staticmethod
677 - def path_completion(text, base_dir = None, only_dirs = False,
678 relative=True):
679 """Propose completions of text to compose a valid path"""
680
681 if base_dir is None:
682 base_dir = os.getcwd()
683 base_dir = os.path.expanduser(os.path.expandvars(base_dir))
684
685 if text == '~':
686 text = '~/'
687 prefix, text = os.path.split(text)
688 prefix = os.path.expanduser(os.path.expandvars(prefix))
689 base_dir = os.path.join(base_dir, prefix)
690 if prefix:
691 prefix += os.path.sep
692
693 if only_dirs:
694 completion = [prefix + f + os.path.sep
695 for f in os.listdir(base_dir)
696 if f.startswith(text) and \
697 os.path.isdir(os.path.join(base_dir, f)) and \
698 (not f.startswith('.') or text.startswith('.'))
699 ]
700 else:
701 completion = [ prefix + f
702 for f in os.listdir(base_dir)
703 if f.startswith(text) and \
704 os.path.isfile(os.path.join(base_dir, f)) and \
705 (not f.startswith('.') or text.startswith('.'))
706 ]
707
708 completion = completion + \
709 [prefix + f + os.path.sep
710 for f in os.listdir(base_dir)
711 if f.startswith(text) and \
712 os.path.isdir(os.path.join(base_dir, f)) and \
713 (not f.startswith('.') or text.startswith('.'))
714 ]
715
716 if relative:
717 completion += [prefix + f for f in ['.'+os.path.sep, '..'+os.path.sep] if \
718 f.startswith(text) and not prefix.startswith('.')]
719
720 completion = [a.replace(' ','\ ') for a in completion]
721 return completion
722
727 """Extension of the cmd object for only the check command"""
728
729 - def check_history(self, args):
730 """check the validity of line"""
731
732 if len(args) > 1:
733 self.help_history()
734 raise self.InvalidCmd('\"history\" command takes at most one argument')
735
736 if not len(args):
737 return
738
739 if args[0] =='.':
740 if not self._export_dir:
741 raise self.InvalidCmd("No default directory is defined for \'.\' option")
742 elif args[0] != 'clean':
743 dirpath = os.path.dirname(args[0])
744 if dirpath and not os.path.exists(dirpath) or \
745 os.path.isdir(args[0]):
746 raise self.InvalidCmd("invalid path %s " % dirpath)
747
749 """check that the line is compatible with save options"""
750
751 if len(args) > 2:
752 self.help_save()
753 raise self.InvalidCmd, 'too many arguments for save command.'
754
755 if len(args) == 2:
756 if args[0] != 'options':
757 self.help_save()
758 raise self.InvalidCmd, '\'%s\' is not recognized as first argument.' % \
759 args[0]
760 else:
761 args.pop(0)
762
764 """Extension of the cmd object for only the help command"""
765
767 logger.info("-- terminates the application",'$MG:color:BLUE')
768 logger.info("syntax: quit",'$MG:color:BLACK')
769
770 help_EOF = help_quit
771
772 - def help_history(self):
773 logger.info("-- interact with the command history.",'$MG:color:BLUE')
774 logger.info("syntax: history [FILEPATH|clean|.] ",'$MG:color:BLACK')
775 logger.info(" > If FILEPATH is \'.\' and \'output\' is done,")
776 logger.info(" Cards/proc_card_mg5.dat will be used.")
777 logger.info(" > If FILEPATH is omitted, the history will be output to stdout.")
778 logger.info(" \"clean\" will remove all entries from the history.")
779
781 logger.info("-- access to the in-line help",'$MG:color:BLUE')
782 logger.info("syntax: help",'$MG:color:BLACK')
783
785 """help text for save"""
786 logger.info("-- save options configuration to filepath.",'$MG:color:BLUE')
787 logger.info("syntax: save [options] [FILEPATH]",'$MG:color:BLACK')
788
790 """help for display command"""
791 logger.info("-- display a the status of various internal state variables",'$MG:color:BLUE')
792 logger.info("syntax: display " + "|".join(self._display_opts),'$MG:color:BLACK')
793
802
803 - def complete_history(self, text, line, begidx, endidx):
804 "Complete the history command"
805
806 args = self.split_arg(line[0:begidx])
807
808
809 if args[-1].endswith(os.path.sep):
810 return self.path_completion(text,
811 os.path.join('.',*[a for a in args \
812 if a.endswith(os.path.sep)]))
813
814 if len(args) == 1:
815 return self.path_completion(text)
816
818 "Complete the save command"
819
820 args = self.split_arg(line[0:begidx])
821
822
823 if len(args) == 1:
824 return self.list_completion(text, ['options'])
825
826
827 if args[-1].endswith(os.path.sep):
828 return self.path_completion(text,
829 pjoin('.',*[a for a in args if a.endswith(os.path.sep)]),
830 only_dirs = True)
831
832
833 if len(args) == 2:
834 return self.path_completion(text)
835
836 -class Cmd(CheckCmd, HelpCmd, CompleteCmd, BasicCmd):
837 """Extension of the cmd.Cmd command line.
838 This extensions supports line breaking, history, comments,
839 internal call to cmdline, path completion,...
840 this class should be MG5 independent"""
841
842
843 next_possibility = {}
844 history_header = ""
845
846 _display_opts = ['options','variable']
847 allow_notification_center = True
848
850 """expected error for wrong command"""
851 pass
852
853 ConfigurationError = InvalidCmd
854
855 debug_output = 'debug'
856 error_debug = """Please report this bug to developers\n
857 More information is found in '%(debug)s'.\n
858 Please attach this file to your report."""
859 config_debug = error_debug
860
861 keyboard_stop_msg = """stopping all current operation
862 in order to quit the program please enter exit"""
863
864
865 if MADEVENT:
866 plugin_path = []
867 else:
868 plugin_path = [pjoin(MG5DIR, 'PLUGIN')]
869 if 'PYTHONPATH' in os.environ:
870 for PluginCandidate in os.environ['PYTHONPATH'].split(':'):
871 try:
872 dirlist = os.listdir(PluginCandidate)
873 except OSError:
874 continue
875 for onedir in dirlist:
876 if onedir == 'MG5aMC_PLUGIN':
877 plugin_path.append(pjoin(PluginCandidate, 'MG5aMC_PLUGIN'))
878 break
879 else:
880 continue
881 break
882
884 """Init history and line continuation"""
885
886 self.log = True
887 self.history = []
888 self.save_line = ''
889 super(Cmd, self).__init__(*arg, **opt)
890 self.__initpos = os.path.abspath(os.getcwd())
891 self.child = None
892 self.mother = None
893 self.inputfile = None
894 self.haspiping = not sys.stdin.isatty()
895 self.stored_line = ''
896
897 if not hasattr(self, 'helporder'):
898 self.helporder = ['Documented commands']
899
901 """Hook method executed once when the cmdloop() method is called."""
902 if self.completekey:
903 try:
904 import readline
905 self.old_completer = readline.get_completer()
906 readline.set_completer(self.complete)
907 readline.parse_and_bind(self.completekey+": complete")
908 except ImportError:
909 pass
910 if readline and not 'libedit' in readline.__doc__:
911 readline.set_completion_display_matches_hook(self.print_suggestions)
912
913
915
916 self.preloop()
917 if intro is not None:
918 self.intro = intro
919 if self.intro:
920 print self.intro
921 stop = None
922 while not stop:
923 if self.cmdqueue:
924 line = self.cmdqueue[0]
925 del self.cmdqueue[0]
926 else:
927 if self.use_rawinput:
928 try:
929 line = raw_input(self.prompt)
930 except EOFError:
931 line = 'EOF'
932 else:
933 sys.stdout.write(self.prompt)
934 sys.stdout.flush()
935 line = sys.stdin.readline()
936 if not len(line):
937 line = 'EOF'
938 else:
939 line = line[:-1]
940 try:
941 line = self.precmd(line)
942 stop = self.onecmd(line)
943 except BaseException, error:
944 self.error_handling(error, line)
945 if isinstance(error, KeyboardInterrupt):
946 stop = True
947 finally:
948 stop = self.postcmd(stop, line)
949 self.postloop()
950
952 """avoid to have html opening / notification"""
953 self.allow_notification_center = False
954 try:
955 self.options['automatic_html_opening'] = False
956 self.options['notification_center'] = False
957
958 except:
959 pass
960
961
963 """ A suite of additional function needed for in the cmd
964 this implement history, line breaking, comment treatment,...
965 """
966
967 if not line:
968 return line
969
970
971 if self.save_line:
972 line = self.save_line + line
973 self.save_line = ''
974
975 line = line.lstrip()
976
977 if line.endswith('\\'):
978 self.save_line = line[:-1]
979 return ''
980
981
982 if '#' in line:
983 line = line.split('#')[0]
984
985
986 if ';' in line:
987 lines = line.split(';')
988 for subline in lines:
989 if not (subline.startswith("history") or subline.startswith('help') \
990 or subline.startswith('#*')):
991 self.history.append(subline)
992 stop = self.onecmd_orig(subline)
993 stop = self.postcmd(stop, subline)
994 return ''
995
996
997 self.history.append(line)
998 return line
999
1000 - def postcmd(self,stop, line):
1001 """ finishing a command
1002 This looks if the command add a special post part."""
1003
1004 if line.strip():
1005 try:
1006 cmd, subline = line.split(None, 1)
1007 except ValueError:
1008 pass
1009 else:
1010 if hasattr(self,'post_%s' %cmd):
1011 stop = getattr(self, 'post_%s' % cmd)(stop, subline)
1012 return stop
1013
1037
1038
1039
1040
1041 - def ask(self, question, default, choices=[], path_msg=None,
1042 timeout = True, fct_timeout=None, ask_class=None, alias={},
1043 first_cmd=None, text_format='4', **opt):
1044 """ ask a question with some pre-define possibility
1045 path info is
1046 """
1047
1048 if path_msg:
1049 path_msg = [path_msg]
1050 else:
1051 path_msg = []
1052
1053 if timeout is True:
1054 try:
1055 timeout = self.options['timeout']
1056 except Exception:
1057 pass
1058
1059
1060 if choices + path_msg:
1061 question += ' ['
1062 question += "\033[%sm%s\033[0m, " % (text_format, default)
1063 for data in choices[:9] + path_msg:
1064 if default == data:
1065 continue
1066 else:
1067 question += "%s, " % data
1068
1069 if len(choices) > 9:
1070 question += '... , '
1071 question = question[:-2]+']'
1072 else:
1073 question += "[\033[%sm%s\033[0m] " % (text_format, default)
1074 if ask_class:
1075 obj = ask_class
1076 elif path_msg:
1077 obj = OneLinePathCompletion
1078 else:
1079 obj = SmartQuestion
1080
1081 if alias:
1082 choices += alias.keys()
1083
1084 question_instance = obj(question, allow_arg=choices, default=default,
1085 mother_interface=self, **opt)
1086
1087 if first_cmd:
1088 if isinstance(first_cmd, str):
1089 question_instance.onecmd(first_cmd)
1090 else:
1091 for line in first_cmd:
1092 question_instance.onecmd(line)
1093 if not self.haspiping:
1094 if hasattr(obj, "haspiping"):
1095 obj.haspiping = self.haspiping
1096
1097
1098
1099
1100 answer = self.check_answer_in_input_file(question_instance, default, path_msg)
1101 if answer is not None:
1102 if answer in alias:
1103 answer = alias[answer]
1104 if ask_class:
1105 line=answer
1106 answer = question_instance.default(line)
1107 question_instance.postcmd(answer, line)
1108 return question_instance.answer
1109 if hasattr(question_instance, 'check_answer_consistency'):
1110 question_instance.check_answer_consistency()
1111 return answer
1112
1113 question = question_instance.question
1114 value = Cmd.timed_input(question, default, timeout=timeout,
1115 fct=question_instance, fct_timeout=fct_timeout)
1116
1117 try:
1118 if value in alias:
1119 value = alias[value]
1120 except TypeError:
1121 pass
1122
1123 if value == default and ask_class:
1124 value = question_instance.default(default)
1125 return value
1126
1136
1138 """check import command"""
1139
1140 if '-f' in args:
1141 self.force = True
1142 args.remove('-f')
1143 if args[0] != 'command':
1144 args.set(0, 'command')
1145 if len(args) != 2:
1146 raise self.InvalidCmd('import command requires one filepath argument')
1147 if not os.path.exists(args[1]):
1148 raise 'No such file or directory %s' % args[1]
1149
1150
1210
1212 """store a line of the input file which should be executed by the higher mother"""
1213
1214 if self.mother:
1215 self.mother.store_line(line)
1216 else:
1217 self.stored_line = line
1218
1220 """return stored line and clean it"""
1221 if self.mother:
1222 value = self.mother.get_stored_line()
1223 self.mother.stored_line = None
1224 else:
1225 value = self.stored_line
1226 self.stored_line = None
1227 return value
1228
1229
1230
1232 """ """
1233
1234 if self.child:
1235 return self.child.nice_error_handling(error, line)
1236
1237 os.chdir(self.__initpos)
1238
1239 self.log = False
1240 if os.path.exists(self.debug_output):
1241 os.remove(self.debug_output)
1242 try:
1243 super(Cmd,self).onecmd('history %s' % self.debug_output.replace(' ', '\ '))
1244 except Exception, error:
1245 logger.error(error)
1246
1247 debug_file = open(self.debug_output, 'a')
1248 traceback.print_exc(file=debug_file)
1249 if hasattr(error, 'filename'):
1250 debug_file.write("Related File: %s\n" % error.filename)
1251
1252 if self.history and line == self.history[-1]:
1253 error_text = 'Command \"%s\" interrupted with error:\n' % line
1254 elif self.history:
1255 error_text = 'Command \"%s\" interrupted in sub-command:\n' %line
1256 error_text += '\"%s\" with error:\n' % self.history[-1]
1257 else:
1258 error_text = ''
1259 error_text += '%s : %s\n' % (error.__class__.__name__,
1260 str(error).replace('\n','\n\t'))
1261 error_text += self.error_debug % {'debug':self.debug_output}
1262 logger_stderr.critical(error_text)
1263
1264
1265
1266 try:
1267 self.do_display('options', debug_file)
1268 except Exception, error:
1269 debug_file.write('Fail to write options with error %s' % error)
1270
1271
1272 for card in ['proc_card_mg5.dat','param_card.dat', 'run_card.dat']:
1273 try:
1274 ff = open(pjoin(self.me_dir, 'Cards', card))
1275 debug_file.write(ff.read())
1276 ff.close()
1277 except Exception:
1278 pass
1279
1280
1281 if self.use_rawinput == False:
1282 return True
1283 return False
1284
1285
1286
1288 if self.child:
1289 return self.child.nice_user_error(error, line)
1290
1291 os.chdir(self.__initpos)
1292 if not self.history or line == self.history[-1]:
1293 error_text = 'Command \"%s\" interrupted with error:\n' % line
1294 else:
1295 error_text = 'Command \"%s\" interrupted in sub-command:\n' %line
1296 error_text += '\"%s\" with error:\n' % self.history[-1]
1297 error_text += '%s : %s' % (error.__class__.__name__,
1298 str(error).replace('\n','\n\t'))
1299 logger_stderr.error(error_text)
1300
1301 if self.use_rawinput == False:
1302 return True
1303
1304 self.history.pop()
1305 return False
1306
1338
1340 """Interpret the argument as though it had been typed in response
1341 to the prompt.
1342
1343 The return value is a flag indicating whether interpretation of
1344 commands by the interpreter should stop.
1345
1346 This allow to pass extra argument for internal call.
1347 """
1348 if '~/' in line and os.environ.has_key('HOME'):
1349 line = line.replace('~/', '%s/' % os.environ['HOME'])
1350 if '#' in line:
1351 line = line.split('#')[0]
1352
1353 line = os.path.expandvars(line)
1354 cmd, arg, line = self.parseline(line)
1355 if not line:
1356 return self.emptyline()
1357 if cmd is None:
1358 return self.default(line)
1359 self.lastcmd = line
1360 if cmd == '':
1361 return self.default(line)
1362 else:
1363 try:
1364 func = getattr(self, 'do_' + cmd)
1365 except AttributeError:
1366 return self.default(line)
1367 return func(arg, **opt)
1368
1405
1406
1407
1408 - def onecmd(self, line, **opt):
1409 """catch all error and stop properly command accordingly"""
1410
1411 try:
1412 return self.onecmd_orig(line, **opt)
1413 except BaseException, error:
1414 self.error_handling(error, line)
1415
1416
1418 """action to perform to close nicely on a keyboard interupt"""
1419 pass
1420
1421 - def exec_cmd(self, line, errorhandling=False, printcmd=True,
1422 precmd=False, postcmd=True,
1423 child=True, **opt):
1443
1445 """for third party call, call the line with pre and postfix treatment
1446 with global error handling"""
1447
1448 return self.exec_cmd(line, errorhandling=True, precmd=True)
1449
1451 """If empty line, do nothing. Default is repeat previous command."""
1452 pass
1453
1454 - def default(self, line, log=True):
1455 """Default action if line is not recognized"""
1456
1457
1458 if log:
1459 logger.warning("Command \"%s\" not recognized, please try again" % \
1460 line.split()[0])
1461 if line.strip() in ['q', '.q', 'stop']:
1462 logger.info("If you want to quit mg5 please type \"exit\".")
1463
1464 if self.history and self.history[-1] == line:
1465 self.history.pop()
1466
1467
1468 - def do_history(self, line):
1469 """write in a file the suite of command that was used"""
1470
1471 args = self.split_arg(line)
1472
1473 self.check_history(args)
1474
1475 if len(args) == 0:
1476 logger.info('\n'.join(self.history))
1477 return
1478 elif args[0] == 'clean':
1479 self.history = []
1480 logger.info('History is cleaned')
1481 return
1482 elif args[0] == '.':
1483 output_file = os.path.join(self._export_dir, 'Cards', \
1484 'proc_card_mg5.dat')
1485 output_file = open(output_file, 'w')
1486 else:
1487 output_file = open(args[0], 'w')
1488
1489
1490 text = self.get_history_header()
1491 text += ('\n'.join(self.history) + '\n')
1492
1493
1494 output_file.write(text)
1495 output_file.close()
1496
1497 if self.log:
1498 logger.info("History written to " + output_file.name)
1499
1500 - def compile(self, *args, **opts):
1504
1505 - def avoid_history_duplicate(self, line, no_break=[]):
1506 """remove all line in history (but the last) starting with line.
1507 up to the point when a line didn't start by something in no_break.
1508 (reading in reverse order)"""
1509
1510 new_history = []
1511 for i in range(1, len(self.history)+1):
1512 cur_line = self.history[-i]
1513 if i == 1:
1514 new_history.append(cur_line)
1515 elif not any((cur_line.startswith(text) for text in no_break)):
1516 to_add = self.history[:-i+1]
1517 to_add.reverse()
1518 new_history += to_add
1519 break
1520 elif cur_line.startswith(line):
1521 continue
1522 else:
1523 new_history.append(cur_line)
1524
1525 new_history.reverse()
1526 self.history[:] = new_history
1527
1528
1530
1531 if self.history:
1532 self.history.pop()
1533
1534
1535 previous_store_line = self.get_stored_line()
1536
1537
1538 if isinstance(filepath, str):
1539 commandline = open(filepath).readlines()
1540 else:
1541 commandline = filepath
1542 oldinputfile = self.inputfile
1543 oldraw = self.use_rawinput
1544 self.inputfile = (l for l in commandline)
1545 self.use_rawinput = False
1546
1547
1548
1549 for line in self.inputfile:
1550
1551 line = line.replace('\n', '').strip()
1552
1553 if line:
1554 self.exec_cmd(line, precmd=True)
1555 stored = self.get_stored_line()
1556 while stored:
1557 line = stored
1558 self.exec_cmd(line, precmd=True)
1559 stored = self.get_stored_line()
1560
1561
1562 if self.child:
1563 self.child.exec_cmd('quit')
1564 self.inputfile = oldinputfile
1565 self.use_rawinput = oldraw
1566
1567
1568 cmd = self
1569 while hasattr(cmd, 'mother') and cmd.mother:
1570 cmd = cmd.mother
1571 cmd.stored_line = previous_store_line
1572 return
1573
1575 """Default history header"""
1576
1577 return self.history_header
1578
1579 - def postloop(self):
1580 """ """
1581
1582 if self.use_rawinput and self.completekey:
1583 try:
1584 import readline
1585 readline.set_completer(self.old_completer)
1586 del self.old_completer
1587 except ImportError:
1588 pass
1589 except AttributeError:
1590 pass
1591
1592 args = self.split_arg(self.lastcmd)
1593 if args and args[0] in ['quit','exit']:
1594 if 'all' in args:
1595 return True
1596 if len(args) >1 and args[1].isdigit():
1597 if args[1] not in ['0', '1']:
1598 return True
1599
1600 return False
1601
1602
1603
1604
1605 @staticmethod
1612
1613 signal.signal(signal.SIGALRM, handle_alarm)
1614
1615 if fct is None:
1616 fct = raw_input
1617
1618 if timeout:
1619 signal.alarm(timeout)
1620 question += '[%ss to answer] ' % (timeout)
1621 try:
1622 result = fct(question)
1623 except TimeOutError:
1624 if noerror:
1625 logger.info('\nuse %s' % default)
1626 if fct_timeout:
1627 fct_timeout(True)
1628 return default
1629 else:
1630 signal.alarm(0)
1631 raise
1632 finally:
1633 signal.alarm(0)
1634 if fct_timeout:
1635 fct_timeout(False)
1636 return result
1637
1638
1639
1640
1641
1642
1643
1645 """Not in help: exit the mainloop() """
1646
1647 if self.child:
1648 self.child.exec_cmd('quit ' + line, printcmd=False)
1649 return
1650 elif self.mother:
1651 self.mother.child = None
1652 if line == 'all':
1653 pass
1654 elif line:
1655 level = int(line) - 1
1656 if level:
1657 self.mother.lastcmd = 'quit %s' % level
1658 logger.info(' ')
1659 return True
1660
1661
1662 do_EOF = do_quit
1663 do_exit = do_quit
1664
1666 """Not in help: propose some usefull possible action """
1667
1668
1669 if line:
1670 return super(Cmd, self).do_help(line)
1671
1672
1673 names = self.get_names()
1674 cmds = {}
1675 names.sort()
1676
1677 prevname = ''
1678 for name in names:
1679 if name[:3] == 'do_':
1680 if name == prevname:
1681 continue
1682 prevname = name
1683 cmdname=name[3:]
1684 try:
1685 doc = getattr(self.cmd, name).__doc__
1686 except Exception:
1687 doc = None
1688 if not doc:
1689 doc = getattr(self, name).__doc__
1690 if not doc:
1691 tag = "Documented commands"
1692 elif ':' in doc:
1693 tag = doc.split(':',1)[0]
1694 else:
1695 tag = "Documented commands"
1696 if tag in cmds:
1697 cmds[tag].append(cmdname)
1698 else:
1699 cmds[tag] = [cmdname]
1700
1701 self.stdout.write("%s\n"%str(self.doc_leader))
1702 for tag in self.helporder:
1703 if tag not in cmds:
1704 continue
1705 header = "%s (type help <topic>):" % tag
1706 self.print_topics(header, cmds[tag], 15,80)
1707 for name, item in cmds.items():
1708 if name in self.helporder:
1709 continue
1710 if name == "Not in help":
1711 continue
1712 header = "%s (type help <topic>):" % name
1713 self.print_topics(header, item, 15,80)
1714
1715
1716
1717 if len(self.history) == 0:
1718 last_action_2 = last_action = 'start'
1719 else:
1720 last_action_2 = last_action = 'none'
1721
1722 pos = 0
1723 authorize = self.next_possibility.keys()
1724 while last_action_2 not in authorize and last_action not in authorize:
1725 pos += 1
1726 if pos > len(self.history):
1727 last_action_2 = last_action = 'start'
1728 break
1729
1730 args = self.history[-1 * pos].split()
1731 last_action = args[0]
1732 if len(args)>1:
1733 last_action_2 = '%s %s' % (last_action, args[1])
1734 else:
1735 last_action_2 = 'none'
1736
1737 logger.info('Contextual Help')
1738 logger.info('===============')
1739 if last_action_2 in authorize:
1740 options = self.next_possibility[last_action_2]
1741 elif last_action in authorize:
1742 options = self.next_possibility[last_action]
1743 else:
1744 return
1745 text = 'The following command(s) may be useful in order to continue.\n'
1746 for option in options:
1747 text+='\t %s \n' % option
1748 logger.info(text)
1749
1751 """Advanced commands: basic display"""
1752
1753 args = self.split_arg(line)
1754
1755
1756 if len(args) == 0:
1757 self.help_display()
1758 raise self.InvalidCmd, 'display require at least one argument'
1759
1760 if args[0] == "options":
1761 outstr = "Value of current Options:\n"
1762 for key, value in self.options.items():
1763 outstr += '%25s \t:\t%s\n' %(key,value)
1764 output.write(outstr)
1765
1766 elif args[0] == "variable":
1767 outstr = "Value of Internal Variable:\n"
1768 try:
1769 var = eval(args[1])
1770 except Exception:
1771 outstr += 'GLOBAL:\nVariable %s is not a global variable\n' % args[1]
1772 else:
1773 outstr += 'GLOBAL:\n'
1774 outstr += misc.nice_representation(var, nb_space=4)
1775
1776 try:
1777 var = eval('self.%s' % args[1])
1778 except Exception:
1779 outstr += 'LOCAL:\nVariable %s is not a local variable\n' % args[1]
1780 else:
1781 outstr += 'LOCAL:\n'
1782 outstr += misc.nice_representation(var, nb_space=4)
1783 split = args[1].split('.')
1784 for i, name in enumerate(split):
1785 try:
1786 __import__('.'.join(split[:i+1]))
1787 exec('%s=sys.modules[\'%s\']' % (split[i], '.'.join(split[:i+1])))
1788 except ImportError:
1789 try:
1790 var = eval(args[1])
1791 except Exception, error:
1792 outstr += 'EXTERNAL:\nVariable %s is not a external variable\n' % args[1]
1793 break
1794 else:
1795 outstr += 'EXTERNAL:\n'
1796 outstr += misc.nice_representation(var, nb_space=4)
1797 else:
1798 var = eval(args[1])
1799 outstr += 'EXTERNAL:\n'
1800 outstr += misc.nice_representation(var, nb_space=4)
1801
1802 pydoc.pager(outstr)
1803
1804
1805 - def do_save(self, line, check=True):
1806 """Save the configuration file"""
1807
1808 args = self.split_arg(line)
1809
1810 if check:
1811 Cmd.check_save(self, args)
1812
1813
1814 if 'HOME' in os.environ and os.environ['HOME'] and \
1815 os.path.exists(pjoin(os.environ['HOME'], '.mg5', 'mg5_configuration.txt')):
1816 base = pjoin(os.environ['HOME'], '.mg5', 'mg5_configuration.txt')
1817 if hasattr(self, 'me_dir'):
1818 basedir = self.me_dir
1819 elif not MADEVENT:
1820 basedir = MG5DIR
1821 else:
1822 basedir = os.getcwd()
1823 elif MADEVENT:
1824
1825 for config_file in ['me5_configuration.txt', 'amcatnlo_configuration.txt']:
1826 if os.path.exists(pjoin(self.me_dir, 'Cards', config_file)):
1827 base = pjoin(self.me_dir, 'Cards', config_file)
1828 basedir = self.me_dir
1829 else:
1830 if hasattr(self, 'me_dir'):
1831 base = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
1832 if len(args) == 0 and os.path.exists(base):
1833 self.write_configuration(base, base, self.me_dir)
1834 base = pjoin(MG5DIR, 'input', 'mg5_configuration.txt')
1835 basedir = MG5DIR
1836
1837 if len(args) == 0:
1838 args.append(base)
1839 self.write_configuration(args[0], base, basedir, self.options)
1840
1842 """Write the configuration file"""
1843
1844
1845
1846
1847 logger.info('save configuration file to %s' % filepath)
1848 to_write = to_keep.keys()
1849 text = ""
1850 has_mg5_path = False
1851
1852 for line in file(basefile):
1853 if '=' in line:
1854 data, value = line.split('=',1)
1855 else:
1856 text += line
1857 continue
1858 data = data.strip()
1859 if data.startswith('#'):
1860 key = data[1:].strip()
1861 else:
1862 key = data
1863 if '#' in value:
1864 value, comment = value.split('#',1)
1865 else:
1866 comment = ''
1867 if key in to_keep:
1868 value = str(to_keep[key])
1869 else:
1870 text += line
1871 continue
1872 if key == 'mg5_path':
1873 has_mg5_path = True
1874 try:
1875 to_write.remove(key)
1876 except Exception:
1877 pass
1878 if '_path' in key:
1879
1880
1881 if not os.path.isabs(value):
1882 value = os.path.realpath(os.path.join(basedir, value))
1883 text += '%s = %s # %s \n' % (key, value, comment)
1884
1885 for key in to_write:
1886 if key in to_keep:
1887 text += '%s = %s \n' % (key, to_keep[key])
1888
1889 if not MADEVENT and not has_mg5_path:
1890 text += """\n# MG5 MAIN DIRECTORY\n"""
1891 text += "mg5_path = %s\n" % MG5DIR
1892
1893 writer = open(filepath,'w')
1894 writer.write(text)
1895 writer.close()
1896
1901 """CMD command with shell activate"""
1902
1903
1905 "Run a shell command"
1906
1907 if line.strip() is '':
1908 self.help_shell()
1909 else:
1910 logging.info("running shell command: " + line)
1911 subprocess.call(line, shell=True)
1912
1914 """ add path for shell """
1915
1916
1917
1918 if len(self.split_arg(line[0:begidx])) > 1 and line[begidx - 1] == os.path.sep:
1919 if not text:
1920 text = ''
1921 output = self.path_completion(text,
1922 base_dir=\
1923 self.split_arg(line[0:begidx])[-1])
1924 else:
1925 output = self.path_completion(text)
1926 return output
1927
1929 """help for the shell"""
1930 logger.info("-- run the shell command CMD and catch output",'$MG:color:BLUE')
1931 logger.info("syntax: shell CMD (or ! CMD)",'$MG:color:BLACK')
1932
1940 """ a class for answering a question with the path autocompletion"""
1941
1942 allowpath = False
1944 """Initializing before starting the main loop"""
1945 self.prompt = '>'
1946 self.value = None
1947 BasicCmd.preloop(self)
1948
1949 @property
1952
1953 - def __init__(self, question, allow_arg=[], default=None,
1954 mother_interface=None, *arg, **opt):
1955 self.question = question
1956 self.wrong_answer = 0
1957 self.allow_arg = [str(a) for a in allow_arg]
1958 self.history_header = ''
1959 self.default_value = str(default)
1960 self.mother_interface = mother_interface
1961
1962 if 'case' in opt:
1963 self.casesensitive = opt['case']
1964 del opt['case']
1965 elif 'casesensitive' in opt:
1966 self.casesensitive = opt['casesensitive']
1967 del opt['casesensitive']
1968 else:
1969 self.casesensistive = True
1970 super(SmartQuestion, self).__init__(*arg, **opt)
1971
1972 - def __call__(self, question, reprint_opt=True, **opts):
1973
1974 self.question = question
1975 for key,value in opts:
1976 setattr(self, key, value)
1977 if reprint_opt:
1978 print question
1979 return self.cmdloop()
1980
1981
1983 prev_timer = signal.alarm(0)
1984 if prev_timer:
1985 nb_back = len(line)
1986 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
1987 self.stdout.write(line)
1988 self.stdout.flush()
1989 try:
1990 out = {}
1991 out[' Options'] = Cmd.list_completion(text, self.allow_arg)
1992 out[' Recognized command'] = BasicCmd.completenames(self, text)
1993
1994 return self.deal_multiple_categories(out)
1995 except Exception, error:
1996 print error
1997
1998 completedefault = completenames
1999
2001
2002
2003 return dir(self)
2004
2005 - def onecmd(self, line, **opt):
2006 """catch all error and stop properly command accordingly
2007 Interpret the argument as though it had been typed in response
2008 to the prompt.
2009
2010 The return value is a flag indicating whether interpretation of
2011 commands by the interpreter should stop.
2012
2013 This allow to pass extra argument for internal call.
2014 """
2015 try:
2016 if '~/' in line and os.environ.has_key('HOME'):
2017 line = line.replace('~/', '%s/' % os.environ['HOME'])
2018 line = os.path.expandvars(line)
2019 cmd, arg, line = self.parseline(line)
2020 if not line:
2021 return self.emptyline()
2022 if cmd is None:
2023 return self.default(line)
2024 self.lastcmd = line
2025 if cmd == '':
2026 return self.default(line)
2027 else:
2028 try:
2029 func = getattr(self, 'do_' + cmd)
2030 except AttributeError:
2031 return self.default(line)
2032 return func(arg, **opt)
2033 except Exception as error:
2034 logger.warning(error)
2035 if __debug__:
2036 raise
2037
2038 - def reask(self, reprint_opt=True):
2039 pat = re.compile('\[(\d*)s to answer\]')
2040 prev_timer = signal.alarm(0)
2041
2042 if prev_timer:
2043 if pat.search(self.question):
2044 timeout = int(pat.search(self.question).groups()[0])
2045 else:
2046 timeout=20
2047 print
2048 signal.alarm(timeout)
2049 if reprint_opt:
2050 if not prev_timer:
2051 self.question = pat.sub('',self.question)
2052 print self.question
2053
2054 if self.mother_interface:
2055 answer = self.mother_interface.check_answer_in_input_file(self, 'EOF',
2056 path=self.allowpath)
2057 if answer:
2058 stop = self.default(answer)
2059 self.postcmd(stop, answer)
2060 return False
2061
2062 return False
2063
2065
2066 text=line
2067 out ={}
2068 out['Options'] = Cmd.list_completion(text, self.allow_arg)
2069 out['command'] = BasicCmd.completenames(self, text)
2070
2071 if not text:
2072 if out['Options']:
2073 logger.info( "Here is the list of all valid options:", '$MG:color:BLACK')
2074 logger.info( " "+ "\n ".join(out['Options']))
2075 if out['command']:
2076 logger.info( "Here is the list of command available:", '$MG:color:BLACK')
2077 logger.info( " "+ "\n ".join(out['command']))
2078 else:
2079 if out['Options']:
2080 logger.info( "Here is the list of all valid options starting with \'%s\'" % text, '$MG:color:BLACK')
2081 logger.info( " "+ "\n ".join(out['Options']))
2082 if out['command']:
2083 logger.info( "Here is the list of command available starting with \'%s\':" % text, '$MG:color:BLACK')
2084 logger.info( " "+ "\n ".join(out['command']))
2085 elif not out['Options']:
2086 logger.info( "No possibility starting with \'%s\'" % text, '$MG:color:BLACK')
2087 logger.info( "You can type help XXX, to see all command starting with XXX", '$MG:color:BLACK')
2091
2093 """Default action if line is not recognized"""
2094
2095 if line.strip() == '' and self.default_value is not None:
2096 self.value = self.default_value
2097 else:
2098 self.value = line
2099
2101 """If empty line, return default"""
2102
2103 if self.default_value is not None:
2104 self.value = self.default_value
2105
2106
2107 - def postcmd(self, stop, line):
2108
2109 try:
2110 if self.value in self.allow_arg:
2111 return True
2112 elif str(self.value) == 'EOF':
2113 self.value = self.default_value
2114 return True
2115 elif line and hasattr(self, 'do_%s' % line.split()[0]):
2116 return self.reask()
2117 elif self.value == 'repeat':
2118 return self.reask()
2119 elif len(self.allow_arg)==0:
2120 return True
2121 elif not self.casesensitive:
2122 for ans in self.allow_arg:
2123 if ans.lower() == self.value.lower():
2124 self.value = ans
2125 return True
2126 break
2127 else:
2128 raise Exception
2129 else:
2130 raise Exception
2131 except Exception,error:
2132 if self.wrong_answer < 100:
2133 self.wrong_answer += 1
2134 logger.warning("""%s not valid argument. Valid argument are in (%s).""" \
2135 % (self.value,','.join(self.allow_arg)))
2136 logger.warning('please retry')
2137 return False
2138 else:
2139 self.value = self.default_value
2140 return True
2141
2145
2151
2156 """ a class for answering a question with the path autocompletion"""
2157
2158 completion_prefix=''
2159 allowpath=True
2160
2161 - def completenames(self, text, line, begidx, endidx, formatting=True):
2162 prev_timer = signal.alarm(0)
2163 if prev_timer:
2164 nb_back = len(line)
2165 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
2166 self.stdout.write(line)
2167 self.stdout.flush()
2168
2169 try:
2170 out = {}
2171 out[' Options'] = Cmd.list_completion(text, self.allow_arg)
2172 out[' Path from ./'] = Cmd.path_completion(text, only_dirs = False)
2173 out[' Recognized command'] = BasicCmd.completenames(self, text)
2174
2175 return self.deal_multiple_categories(out, formatting)
2176 except Exception, error:
2177 print error
2178
2184
2186 prev_timer = signal.alarm(0)
2187 if prev_timer:
2188 nb_back = len(line)
2189 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
2190 self.stdout.write(line)
2191 self.stdout.flush()
2192 try:
2193 args = Cmd.split_arg(line[0:begidx])
2194 except Exception, error:
2195 print error
2196
2197
2198 if args[-1].endswith(os.path.sep):
2199
2200 return Cmd.path_completion(text,
2201 os.path.join('.',*[a for a in args \
2202 if a.endswith(os.path.sep)]))
2203 self.completenames(line+text)
2204
2205
2206 - def postcmd(self, stop, line):
2207 try:
2208 if self.value in self.allow_arg:
2209 return True
2210 elif self.value and os.path.isfile(self.value):
2211 return os.path.relpath(self.value)
2212 elif self.value and str(self.value) == 'EOF':
2213 self.value = self.default_value
2214 return True
2215 elif line and hasattr(self, 'do_%s' % line.split()[0]):
2216
2217 reprint_opt = True
2218 elif self.value == 'repeat':
2219 reprint_opt = True
2220 else:
2221 raise Exception
2222 except Exception, error:
2223 print """not valid argument. Valid argument are file path or value in (%s).""" \
2224 % ','.join(self.allow_arg)
2225 print 'please retry'
2226 reprint_opt = False
2227
2228 if line != 'EOF':
2229 return self.reask(reprint_opt)
2230
2237
2238
2239
2240
2241 -class CmdFile(file):
2242 """ a class for command input file -in order to debug cmd \n problem"""
2243
2250
2252 """readline method treating correctly a line whithout \n at the end
2253 (add it)
2254 """
2255 if self.lines:
2256 line = self.lines.pop(0)
2257 else:
2258 return ''
2259
2260 if line.endswith('\n'):
2261 return line
2262 else:
2263 return line + '\n'
2264
2267
2270