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:
448 if not 'libedit' in readline.__doc__:
449 readline.set_completion_display_matches_hook(self.print_suggestions)
450 else:
451 readline.set_completion_display_matches_hook()
452
456
458 """convert the multiple category in a formatted list understand by our
459 specific readline parser"""
460
461 if not formatting:
462 return dico
463
464 if 'libedit' in readline.__doc__:
465
466 out = []
467 for name, opt in dico.items():
468 out += opt
469 return out
470
471
472 if not forceCategory and all(len(s) <= 1 for s in dico.values() ):
473 values = set((s[0] for s in dico.values() if len(s)==1))
474 if len(values) == 1:
475 return values
476
477
478 out = []
479 valid=0
480
481 for name, opt in dico.items():
482 if not opt:
483 continue
484 name = name.replace(' ', '_')
485 valid += 1
486 out.append(opt[0].rstrip()+'@@'+name+'@@')
487
488 d = {}
489 for x in opt:
490 d[x] = 1
491 opt = list(d.keys())
492 opt.sort()
493 out += opt
494
495 if not forceCategory and valid == 1:
496 out = out[1:]
497
498 return out
499
500 @debug()
502 """print auto-completions by category"""
503 if not hasattr(self, 'completion_prefix'):
504 self.completion_prefix = ''
505 longest_match_length += len(self.completion_prefix)
506 try:
507 if len(matches) == 1:
508 self.stdout.write(matches[0]+' ')
509 return
510 self.stdout.write('\n')
511 l2 = [a[-2:] for a in matches]
512 if '@@' in l2:
513 nb_column = self.getTerminalSize()//(longest_match_length+1)
514 pos=0
515 for val in self.completion_matches:
516 if val.endswith('@@'):
517 category = val.rsplit('@@',2)[1]
518 category = category.replace('_',' ')
519 self.stdout.write('\n %s:\n%s\n' % (category, '=' * (len(category)+2)))
520 start = 0
521 pos = 0
522 continue
523 elif pos and pos % nb_column ==0:
524 self.stdout.write('\n')
525 self.stdout.write(self.completion_prefix + val + \
526 ' ' * (longest_match_length +1 -len(val)))
527 pos +=1
528 self.stdout.write('\n')
529 else:
530
531 nb_column = self.getTerminalSize()//(longest_match_length+1)
532 for i,val in enumerate(matches):
533 if i and i%nb_column ==0:
534 self.stdout.write('\n')
535 self.stdout.write(self.completion_prefix + val + \
536 ' ' * (longest_match_length +1 -len(val)))
537 self.stdout.write('\n')
538
539 self.stdout.write(self.prompt+readline.get_line_buffer())
540 self.stdout.flush()
541 except Exception, error:
542 if __debug__:
543 logger.error(error)
544
546 def ioctl_GWINSZ(fd):
547 try:
548 import fcntl, termios, struct
549 cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
550 '1234'))
551 except Exception:
552 return None
553 return cr
554 cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
555 if not cr:
556 try:
557 fd = os.open(os.ctermid(), os.O_RDONLY)
558 cr = ioctl_GWINSZ(fd)
559 os.close(fd)
560 except Exception:
561 pass
562 if not cr:
563 try:
564 cr = (os.environ['LINES'], os.environ['COLUMNS'])
565 except Exception:
566 cr = (25, 80)
567 return int(cr[1])
568
570 """Return the next possible completion for 'text'.
571 If a command has not been entered, then complete against command list.
572 Otherwise try to call complete_<command> to get list of completions.
573 """
574 if state == 0:
575 import readline
576 origline = readline.get_line_buffer()
577 line = origline.lstrip()
578 stripped = len(origline) - len(line)
579 begidx = readline.get_begidx() - stripped
580 endidx = readline.get_endidx() - stripped
581
582 if ';' in line:
583 begin, line = line.rsplit(';',1)
584 begidx = begidx - len(begin) - 1
585 endidx = endidx - len(begin) - 1
586 if line[:begidx] == ' ' * begidx:
587 begidx=0
588
589 if begidx>0:
590 cmd, args, foo = self.parseline(line)
591 if cmd == '':
592 compfunc = self.completedefault
593 else:
594 try:
595 compfunc = getattr(self, 'complete_' + cmd)
596 except AttributeError, error:
597 compfunc = self.completedefault
598 except Exception, error:
599 misc.sprint(error)
600 else:
601 compfunc = self.completenames
602
603
604 if line and begidx > 2 and line[begidx-2:begidx] == '\ ':
605 Ntext = line.split(os.path.sep)[-1]
606 self.completion_prefix = Ntext.rsplit('\ ', 1)[0] + '\ '
607 to_rm = len(self.completion_prefix) - 1
608 Nbegidx = len(line.rsplit(os.path.sep, 1)[0]) + 1
609 data = compfunc(Ntext.replace('\ ', ' '), line, Nbegidx, endidx)
610 self.completion_matches = [p[to_rm:] for p in data
611 if len(p)>to_rm]
612
613 elif line and line[begidx-1] in ['-',"=",':']:
614 try:
615 sep = line[begidx-1]
616 Ntext = line.split()[-1]
617 self.completion_prefix = Ntext.rsplit(sep,1)[0] + sep
618 to_rm = len(self.completion_prefix)
619 Nbegidx = len(line.rsplit(None, 1)[0])
620 data = compfunc(Ntext, line, Nbegidx, endidx)
621 self.completion_matches = [p[to_rm:] for p in data
622 if len(p)>to_rm]
623 except Exception, error:
624 print error
625 else:
626 self.completion_prefix = ''
627 self.completion_matches = compfunc(text, line, begidx, endidx)
628
629 self.completion_matches = [ l if l[-1] in [' ','@','=',os.path.sep]
630 else ((l + ' ') if not l.endswith('\\$') else l[:-2])
631 for l in self.completion_matches if l]
632
633 try:
634 return self.completion_matches[state]
635 except IndexError, error:
636
637
638
639 return None
640
641 @staticmethod
643 """Split a line of arguments"""
644
645 split = line.split()
646 out=[]
647 tmp=''
648 for data in split:
649 if data[-1] == '\\':
650 tmp += data[:-1]+' '
651 elif tmp:
652 tmp += data
653 tmp = os.path.expanduser(os.path.expandvars(tmp))
654 out.append(tmp)
655
656
657 tmp = ''
658 else:
659 out.append(data)
660 return out
661
662 @staticmethod
664 """Propose completions of text in list"""
665
666 if not text:
667 completions = list
668 else:
669 completions = [ f
670 for f in list
671 if f.startswith(text)
672 ]
673
674 return completions
675
676
677 @staticmethod
678 - def path_completion(text, base_dir = None, only_dirs = False,
679 relative=True):
680 """Propose completions of text to compose a valid path"""
681
682 if base_dir is None:
683 base_dir = os.getcwd()
684 base_dir = os.path.expanduser(os.path.expandvars(base_dir))
685
686 if text == '~':
687 text = '~/'
688 prefix, text = os.path.split(text)
689 prefix = os.path.expanduser(os.path.expandvars(prefix))
690 base_dir = os.path.join(base_dir, prefix)
691 if prefix:
692 prefix += os.path.sep
693
694 if only_dirs:
695 completion = [prefix + f + os.path.sep
696 for f in os.listdir(base_dir)
697 if f.startswith(text) and \
698 os.path.isdir(os.path.join(base_dir, f)) and \
699 (not f.startswith('.') or text.startswith('.'))
700 ]
701 else:
702 completion = [ prefix + f
703 for f in os.listdir(base_dir)
704 if f.startswith(text) and \
705 os.path.isfile(os.path.join(base_dir, f)) and \
706 (not f.startswith('.') or text.startswith('.'))
707 ]
708
709 completion = completion + \
710 [prefix + f + os.path.sep
711 for f in os.listdir(base_dir)
712 if f.startswith(text) and \
713 os.path.isdir(os.path.join(base_dir, f)) and \
714 (not f.startswith('.') or text.startswith('.'))
715 ]
716
717 if relative:
718 completion += [prefix + f for f in ['.'+os.path.sep, '..'+os.path.sep] if \
719 f.startswith(text) and not prefix.startswith('.')]
720
721 completion = [a.replace(' ','\ ') for a in completion]
722 return completion
723
728 """Extension of the cmd object for only the check command"""
729
730 - def check_history(self, args):
731 """check the validity of line"""
732
733 if len(args) > 1:
734 self.help_history()
735 raise self.InvalidCmd('\"history\" command takes at most one argument')
736
737 if not len(args):
738 return
739
740 if args[0] =='.':
741 if not self._export_dir:
742 raise self.InvalidCmd("No default directory is defined for \'.\' option")
743 elif args[0] != 'clean':
744 dirpath = os.path.dirname(args[0])
745 if dirpath and not os.path.exists(dirpath) or \
746 os.path.isdir(args[0]):
747 raise self.InvalidCmd("invalid path %s " % dirpath)
748
750 """check that the line is compatible with save options"""
751
752 if len(args) > 2:
753 self.help_save()
754 raise self.InvalidCmd, 'too many arguments for save command.'
755
756 if len(args) == 2:
757 if args[0] != 'options':
758 self.help_save()
759 raise self.InvalidCmd, '\'%s\' is not recognized as first argument.' % \
760 args[0]
761 else:
762 args.pop(0)
763
765 """Extension of the cmd object for only the help command"""
766
768 logger.info("-- terminates the application",'$MG:color:BLUE')
769 logger.info("syntax: quit",'$MG:color:BLACK')
770
771 help_EOF = help_quit
772
773 - def help_history(self):
774 logger.info("-- interact with the command history.",'$MG:color:BLUE')
775 logger.info("syntax: history [FILEPATH|clean|.] ",'$MG:color:BLACK')
776 logger.info(" > If FILEPATH is \'.\' and \'output\' is done,")
777 logger.info(" Cards/proc_card_mg5.dat will be used.")
778 logger.info(" > If FILEPATH is omitted, the history will be output to stdout.")
779 logger.info(" \"clean\" will remove all entries from the history.")
780
782 logger.info("-- access to the in-line help",'$MG:color:BLUE')
783 logger.info("syntax: help",'$MG:color:BLACK')
784
786 """help text for save"""
787 logger.info("-- save options configuration to filepath.",'$MG:color:BLUE')
788 logger.info("syntax: save [options] [FILEPATH]",'$MG:color:BLACK')
789
791 """help for display command"""
792 logger.info("-- display a the status of various internal state variables",'$MG:color:BLUE')
793 logger.info("syntax: display " + "|".join(self._display_opts),'$MG:color:BLACK')
794
803
804 - def complete_history(self, text, line, begidx, endidx):
805 "Complete the history command"
806
807 args = self.split_arg(line[0:begidx])
808
809
810 if args[-1].endswith(os.path.sep):
811 return self.path_completion(text,
812 os.path.join('.',*[a for a in args \
813 if a.endswith(os.path.sep)]))
814
815 if len(args) == 1:
816 return self.path_completion(text)
817
819 "Complete the save command"
820
821 args = self.split_arg(line[0:begidx])
822
823
824 if len(args) == 1:
825 return self.list_completion(text, ['options'])
826
827
828 if args[-1].endswith(os.path.sep):
829 return self.path_completion(text,
830 pjoin('.',*[a for a in args if a.endswith(os.path.sep)]),
831 only_dirs = True)
832
833
834 if len(args) == 2:
835 return self.path_completion(text)
836
837 -class Cmd(CheckCmd, HelpCmd, CompleteCmd, BasicCmd):
838 """Extension of the cmd.Cmd command line.
839 This extensions supports line breaking, history, comments,
840 internal call to cmdline, path completion,...
841 this class should be MG5 independent"""
842
843
844 next_possibility = {}
845 history_header = ""
846
847 _display_opts = ['options','variable']
848 allow_notification_center = True
849
851 """expected error for wrong command"""
852 pass
853
854 ConfigurationError = InvalidCmd
855
856 debug_output = 'debug'
857 error_debug = """Please report this bug to developers\n
858 More information is found in '%(debug)s'.\n
859 Please attach this file to your report."""
860 config_debug = error_debug
861
862 keyboard_stop_msg = """stopping all current operation
863 in order to quit the program please enter exit"""
864
865
866 if MADEVENT:
867 plugin_path = []
868 else:
869 plugin_path = [pjoin(MG5DIR, 'PLUGIN')]
870 if 'PYTHONPATH' in os.environ:
871 for PluginCandidate in os.environ['PYTHONPATH'].split(':'):
872 try:
873 dirlist = os.listdir(PluginCandidate)
874 except OSError:
875 continue
876 for onedir in dirlist:
877 if onedir == 'MG5aMC_PLUGIN':
878 plugin_path.append(pjoin(PluginCandidate, 'MG5aMC_PLUGIN'))
879 break
880 else:
881 continue
882 break
883
885 """Init history and line continuation"""
886
887 self.log = True
888 self.history = []
889 self.save_line = ''
890 super(Cmd, self).__init__(*arg, **opt)
891 self.__initpos = os.path.abspath(os.getcwd())
892 self.child = None
893 self.mother = None
894 self.inputfile = None
895 self.haspiping = not sys.stdin.isatty()
896 self.stored_line = ''
897
898 if not hasattr(self, 'helporder'):
899 self.helporder = ['Documented commands']
900
902 """Hook method executed once when the cmdloop() method is called."""
903 if self.completekey:
904 try:
905 import readline
906 self.old_completer = readline.get_completer()
907 readline.set_completer(self.complete)
908 readline.parse_and_bind(self.completekey+": complete")
909 except ImportError:
910 readline = None
911 pass
912 if readline and not 'libedit' in readline.__doc__:
913 readline.set_completion_display_matches_hook(self.print_suggestions)
914
915
917
918 self.preloop()
919 if intro is not None:
920 self.intro = intro
921 if self.intro:
922 print self.intro
923 stop = None
924 while not stop:
925 if self.cmdqueue:
926 line = self.cmdqueue[0]
927 del self.cmdqueue[0]
928 else:
929 if self.use_rawinput:
930 try:
931 line = raw_input(self.prompt)
932 except EOFError:
933 line = 'EOF'
934 else:
935 sys.stdout.write(self.prompt)
936 sys.stdout.flush()
937 line = sys.stdin.readline()
938 if not len(line):
939 line = 'EOF'
940 else:
941 line = line[:-1]
942 try:
943 line = self.precmd(line)
944 stop = self.onecmd(line)
945 except BaseException, error:
946 self.error_handling(error, line)
947 if isinstance(error, KeyboardInterrupt):
948 stop = True
949 finally:
950 stop = self.postcmd(stop, line)
951 self.postloop()
952
954 """avoid to have html opening / notification"""
955 self.allow_notification_center = False
956 try:
957 self.options['automatic_html_opening'] = False
958 self.options['notification_center'] = False
959
960 except:
961 pass
962
963
965 """ A suite of additional function needed for in the cmd
966 this implement history, line breaking, comment treatment,...
967 """
968
969 if not line:
970 return line
971
972
973 if self.save_line:
974 line = self.save_line + line
975 self.save_line = ''
976
977 line = line.lstrip()
978
979 if line.endswith('\\'):
980 self.save_line = line[:-1]
981 return ''
982
983
984 if '#' in line:
985 line = line.split('#')[0]
986
987
988 if ';' in line:
989 lines = line.split(';')
990 for subline in lines:
991 if not (subline.startswith("history") or subline.startswith('help') \
992 or subline.startswith('#*')):
993 self.history.append(subline)
994 stop = self.onecmd_orig(subline)
995 stop = self.postcmd(stop, subline)
996 return ''
997
998
999 self.history.append(line)
1000 return line
1001
1002 - def postcmd(self,stop, line):
1003 """ finishing a command
1004 This looks if the command add a special post part."""
1005
1006 if line.strip():
1007 try:
1008 cmd, subline = line.split(None, 1)
1009 except ValueError:
1010 pass
1011 else:
1012 if hasattr(self,'post_%s' %cmd):
1013 stop = getattr(self, 'post_%s' % cmd)(stop, subline)
1014 return stop
1015
1039
1040
1041
1042
1043 - def ask(self, question, default, choices=[], path_msg=None,
1044 timeout = True, fct_timeout=None, ask_class=None, alias={},
1045 first_cmd=None, text_format='4', **opt):
1046 """ ask a question with some pre-define possibility
1047 path info is
1048 """
1049
1050 if path_msg:
1051 path_msg = [path_msg]
1052 else:
1053 path_msg = []
1054
1055 if timeout is True:
1056 try:
1057 timeout = self.options['timeout']
1058 except Exception:
1059 pass
1060
1061
1062 if choices + path_msg:
1063 question += ' ['
1064 question += "\033[%sm%s\033[0m, " % (text_format, default)
1065 for data in choices[:9] + path_msg:
1066 if default == data:
1067 continue
1068 else:
1069 question += "%s, " % data
1070
1071 if len(choices) > 9:
1072 question += '... , '
1073 question = question[:-2]+']'
1074 else:
1075 question += "[\033[%sm%s\033[0m] " % (text_format, default)
1076 if ask_class:
1077 obj = ask_class
1078 elif path_msg:
1079 obj = OneLinePathCompletion
1080 else:
1081 obj = SmartQuestion
1082
1083 if alias:
1084 choices += alias.keys()
1085
1086 question_instance = obj(question, allow_arg=choices, default=default,
1087 mother_interface=self, **opt)
1088
1089 if first_cmd:
1090 if isinstance(first_cmd, str):
1091 question_instance.onecmd(first_cmd)
1092 else:
1093 for line in first_cmd:
1094 question_instance.onecmd(line)
1095 if not self.haspiping:
1096 if hasattr(obj, "haspiping"):
1097 obj.haspiping = self.haspiping
1098
1099
1100
1101
1102 answer = self.check_answer_in_input_file(question_instance, default, path_msg)
1103 if answer is not None:
1104 if answer in alias:
1105 answer = alias[answer]
1106 if ask_class:
1107 line=answer
1108 answer = question_instance.default(line)
1109 question_instance.postcmd(answer, line)
1110 return question_instance.answer
1111 if hasattr(question_instance, 'check_answer_consistency'):
1112 question_instance.check_answer_consistency()
1113 return answer
1114
1115 question = question_instance.question
1116 value = Cmd.timed_input(question, default, timeout=timeout,
1117 fct=question_instance, fct_timeout=fct_timeout)
1118
1119 try:
1120 if value in alias:
1121 value = alias[value]
1122 except TypeError:
1123 pass
1124
1125 if value == default and ask_class:
1126 value = question_instance.default(default)
1127 return value
1128
1138
1140 """check import command"""
1141
1142 if '-f' in args:
1143 self.force = True
1144 args.remove('-f')
1145 if args[0] != 'command':
1146 args.set(0, 'command')
1147 if len(args) != 2:
1148 raise self.InvalidCmd('import command requires one filepath argument')
1149 if not os.path.exists(args[1]):
1150 raise 'No such file or directory %s' % args[1]
1151
1152
1212
1214 """store a line of the input file which should be executed by the higher mother"""
1215
1216 if self.mother:
1217 self.mother.store_line(line)
1218 else:
1219 self.stored_line = line
1220
1222 """return stored line and clean it"""
1223 if self.mother:
1224 value = self.mother.get_stored_line()
1225 self.mother.stored_line = None
1226 else:
1227 value = self.stored_line
1228 self.stored_line = None
1229 return value
1230
1231
1232
1234 """ """
1235
1236 if self.child:
1237 return self.child.nice_error_handling(error, line)
1238
1239 os.chdir(self.__initpos)
1240
1241 self.log = False
1242 if os.path.exists(self.debug_output):
1243 os.remove(self.debug_output)
1244 try:
1245 super(Cmd,self).onecmd('history %s' % self.debug_output.replace(' ', '\ '))
1246 except Exception, error:
1247 logger.error(error)
1248
1249 debug_file = open(self.debug_output, 'a')
1250 traceback.print_exc(file=debug_file)
1251 if hasattr(error, 'filename'):
1252 debug_file.write("Related File: %s\n" % error.filename)
1253
1254 if self.history and line == self.history[-1]:
1255 error_text = 'Command \"%s\" interrupted with error:\n' % line
1256 elif self.history:
1257 error_text = 'Command \"%s\" interrupted in sub-command:\n' %line
1258 error_text += '\"%s\" with error:\n' % self.history[-1]
1259 else:
1260 error_text = ''
1261 error_text += '%s : %s\n' % (error.__class__.__name__,
1262 str(error).replace('\n','\n\t'))
1263 error_text += self.error_debug % {'debug':self.debug_output}
1264 logger_stderr.critical(error_text)
1265
1266
1267
1268 try:
1269 self.do_display('options', debug_file)
1270 except Exception, error:
1271 debug_file.write('Fail to write options with error %s' % error)
1272
1273
1274 for card in ['proc_card_mg5.dat','param_card.dat', 'run_card.dat']:
1275 try:
1276 ff = open(pjoin(self.me_dir, 'Cards', card))
1277 debug_file.write(ff.read())
1278 ff.close()
1279 except Exception:
1280 pass
1281
1282
1283 if self.use_rawinput == False:
1284 return True
1285 return False
1286
1287
1288
1290 if self.child:
1291 return self.child.nice_user_error(error, line)
1292
1293 os.chdir(self.__initpos)
1294 if not self.history or line == self.history[-1]:
1295 error_text = 'Command \"%s\" interrupted with error:\n' % line
1296 else:
1297 error_text = 'Command \"%s\" interrupted in sub-command:\n' %line
1298 error_text += '\"%s\" with error:\n' % self.history[-1]
1299 error_text += '%s : %s' % (error.__class__.__name__,
1300 str(error).replace('\n','\n\t'))
1301 logger_stderr.error(error_text)
1302
1303 if self.use_rawinput == False:
1304 return True
1305
1306 self.history.pop()
1307 return False
1308
1340
1342 """Interpret the argument as though it had been typed in response
1343 to the prompt.
1344
1345 The return value is a flag indicating whether interpretation of
1346 commands by the interpreter should stop.
1347
1348 This allow to pass extra argument for internal call.
1349 """
1350 if '~/' in line and os.environ.has_key('HOME'):
1351 line = line.replace('~/', '%s/' % os.environ['HOME'])
1352 if '#' in line:
1353 line = line.split('#')[0]
1354
1355 line = os.path.expandvars(line)
1356 cmd, arg, line = self.parseline(line)
1357 if not line:
1358 return self.emptyline()
1359 if cmd is None:
1360 return self.default(line)
1361 self.lastcmd = line
1362 if cmd == '':
1363 return self.default(line)
1364 else:
1365 try:
1366 func = getattr(self, 'do_' + cmd)
1367 except AttributeError:
1368 return self.default(line)
1369 return func(arg, **opt)
1370
1408
1409
1410
1411 - def onecmd(self, line, **opt):
1412 """catch all error and stop properly command accordingly"""
1413
1414 try:
1415 return self.onecmd_orig(line, **opt)
1416 except BaseException, error:
1417 self.error_handling(error, line)
1418
1419
1421 """action to perform to close nicely on a keyboard interupt"""
1422 pass
1423
1424 - def exec_cmd(self, line, errorhandling=False, printcmd=True,
1425 precmd=False, postcmd=True,
1426 child=True, **opt):
1446
1448 """for third party call, call the line with pre and postfix treatment
1449 with global error handling"""
1450
1451 return self.exec_cmd(line, errorhandling=True, precmd=True)
1452
1454 """If empty line, do nothing. Default is repeat previous command."""
1455 pass
1456
1457 - def default(self, line, log=True):
1458 """Default action if line is not recognized"""
1459
1460
1461 if log:
1462 logger.warning("Command \"%s\" not recognized, please try again" % \
1463 line.split()[0])
1464 if line.strip() in ['q', '.q', 'stop']:
1465 logger.info("If you want to quit mg5 please type \"exit\".")
1466
1467 if self.history and self.history[-1] == line:
1468 self.history.pop()
1469
1470
1471 - def do_history(self, line):
1472 """write in a file the suite of command that was used"""
1473
1474 args = self.split_arg(line)
1475
1476 self.check_history(args)
1477
1478 if len(args) == 0:
1479 logger.info('\n'.join(self.history))
1480 return
1481 elif args[0] == 'clean':
1482 self.history = []
1483 logger.info('History is cleaned')
1484 return
1485 elif args[0] == '.':
1486 output_file = os.path.join(self._export_dir, 'Cards', \
1487 'proc_card_mg5.dat')
1488 output_file = open(output_file, 'w')
1489 else:
1490 output_file = open(args[0], 'w')
1491
1492
1493 text = self.get_history_header()
1494 text += ('\n'.join(self.history) + '\n')
1495
1496
1497 output_file.write(text)
1498 output_file.close()
1499
1500 if self.log:
1501 logger.info("History written to " + output_file.name)
1502
1503 - def compile(self, *args, **opts):
1507
1508 - def avoid_history_duplicate(self, line, no_break=[]):
1509 """remove all line in history (but the last) starting with line.
1510 up to the point when a line didn't start by something in no_break.
1511 (reading in reverse order)"""
1512
1513 new_history = []
1514 for i in range(1, len(self.history)+1):
1515 cur_line = self.history[-i]
1516 if i == 1:
1517 new_history.append(cur_line)
1518 elif not any((cur_line.startswith(text) for text in no_break)):
1519 to_add = self.history[:-i+1]
1520 to_add.reverse()
1521 new_history += to_add
1522 break
1523 elif cur_line.startswith(line):
1524 continue
1525 else:
1526 new_history.append(cur_line)
1527
1528 new_history.reverse()
1529 self.history[:] = new_history
1530
1531
1533
1534 if self.history:
1535 self.history.pop()
1536
1537
1538 previous_store_line = self.get_stored_line()
1539
1540
1541 if isinstance(filepath, str):
1542 commandline = open(filepath).readlines()
1543 else:
1544 commandline = filepath
1545 oldinputfile = self.inputfile
1546 oldraw = self.use_rawinput
1547 self.inputfile = (l for l in commandline)
1548 self.use_rawinput = False
1549
1550
1551
1552 for line in self.inputfile:
1553
1554 line = line.replace('\n', '').strip()
1555
1556 if line:
1557 self.exec_cmd(line, precmd=True)
1558 stored = self.get_stored_line()
1559 while stored:
1560 line = stored
1561 self.exec_cmd(line, precmd=True)
1562 stored = self.get_stored_line()
1563
1564
1565 if self.child:
1566 self.child.exec_cmd('quit')
1567 self.inputfile = oldinputfile
1568 self.use_rawinput = oldraw
1569
1570
1571 cmd = self
1572 while hasattr(cmd, 'mother') and cmd.mother:
1573 cmd = cmd.mother
1574 cmd.stored_line = previous_store_line
1575 return
1576
1578 """Default history header"""
1579
1580 return self.history_header
1581
1582 - def postloop(self):
1583 """ """
1584
1585 if self.use_rawinput and self.completekey:
1586 try:
1587 import readline
1588 readline.set_completer(self.old_completer)
1589 del self.old_completer
1590 except ImportError:
1591 pass
1592 except AttributeError:
1593 pass
1594
1595 args = self.split_arg(self.lastcmd)
1596 if args and args[0] in ['quit','exit']:
1597 if 'all' in args:
1598 return True
1599 if len(args) >1 and args[1].isdigit():
1600 if args[1] not in ['0', '1']:
1601 return True
1602
1603 return False
1604
1605
1606
1607
1608 @staticmethod
1615
1616 signal.signal(signal.SIGALRM, handle_alarm)
1617
1618 if fct is None:
1619 fct = raw_input
1620
1621 if timeout:
1622 signal.alarm(timeout)
1623 question += '[%ss to answer] ' % (timeout)
1624 try:
1625 result = fct(question)
1626 except TimeOutError:
1627 if noerror:
1628 logger.info('\nuse %s' % default)
1629 if fct_timeout:
1630 fct_timeout(True)
1631 return default
1632 else:
1633 signal.alarm(0)
1634 raise
1635 finally:
1636 signal.alarm(0)
1637 if fct_timeout:
1638 fct_timeout(False)
1639 return result
1640
1641
1642
1643
1644
1645
1646
1648 """Not in help: exit the mainloop() """
1649
1650 if self.child:
1651 self.child.exec_cmd('quit ' + line, printcmd=False)
1652 return
1653 elif self.mother:
1654 self.mother.child = None
1655 if line == 'all':
1656 pass
1657 elif line:
1658 level = int(line) - 1
1659 if level:
1660 self.mother.lastcmd = 'quit %s' % level
1661 logger.info(' ')
1662 return True
1663
1664
1665 do_EOF = do_quit
1666 do_exit = do_quit
1667
1669 """Not in help: propose some usefull possible action """
1670
1671
1672 if line:
1673 return super(Cmd, self).do_help(line)
1674
1675
1676 names = self.get_names()
1677 cmds = {}
1678 names.sort()
1679
1680 prevname = ''
1681 for name in names:
1682 if name[:3] == 'do_':
1683 if name == prevname:
1684 continue
1685 prevname = name
1686 cmdname=name[3:]
1687 try:
1688 doc = getattr(self.cmd, name).__doc__
1689 except Exception:
1690 doc = None
1691 if not doc:
1692 doc = getattr(self, name).__doc__
1693 if not doc:
1694 tag = "Documented commands"
1695 elif ':' in doc:
1696 tag = doc.split(':',1)[0]
1697 else:
1698 tag = "Documented commands"
1699 if tag in cmds:
1700 cmds[tag].append(cmdname)
1701 else:
1702 cmds[tag] = [cmdname]
1703
1704 self.stdout.write("%s\n"%str(self.doc_leader))
1705 for tag in self.helporder:
1706 if tag not in cmds:
1707 continue
1708 header = "%s (type help <topic>):" % tag
1709 self.print_topics(header, cmds[tag], 15,80)
1710 for name, item in cmds.items():
1711 if name in self.helporder:
1712 continue
1713 if name == "Not in help":
1714 continue
1715 header = "%s (type help <topic>):" % name
1716 self.print_topics(header, item, 15,80)
1717
1718
1719
1720 if len(self.history) == 0:
1721 last_action_2 = last_action = 'start'
1722 else:
1723 last_action_2 = last_action = 'none'
1724
1725 pos = 0
1726 authorize = self.next_possibility.keys()
1727 while last_action_2 not in authorize and last_action not in authorize:
1728 pos += 1
1729 if pos > len(self.history):
1730 last_action_2 = last_action = 'start'
1731 break
1732
1733 args = self.history[-1 * pos].split()
1734 last_action = args[0]
1735 if len(args)>1:
1736 last_action_2 = '%s %s' % (last_action, args[1])
1737 else:
1738 last_action_2 = 'none'
1739
1740 logger.info('Contextual Help')
1741 logger.info('===============')
1742 if last_action_2 in authorize:
1743 options = self.next_possibility[last_action_2]
1744 elif last_action in authorize:
1745 options = self.next_possibility[last_action]
1746 else:
1747 return
1748 text = 'The following command(s) may be useful in order to continue.\n'
1749 for option in options:
1750 text+='\t %s \n' % option
1751 logger.info(text)
1752
1754 """Advanced commands: basic display"""
1755
1756 args = self.split_arg(line)
1757
1758
1759 if len(args) == 0:
1760 self.help_display()
1761 raise self.InvalidCmd, 'display require at least one argument'
1762
1763 if args[0] == "options":
1764 outstr = "Value of current Options:\n"
1765 for key, value in self.options.items():
1766 outstr += '%25s \t:\t%s\n' %(key,value)
1767 output.write(outstr)
1768
1769 elif args[0] == "variable":
1770 outstr = "Value of Internal Variable:\n"
1771 try:
1772 var = eval(args[1])
1773 except Exception:
1774 outstr += 'GLOBAL:\nVariable %s is not a global variable\n' % args[1]
1775 else:
1776 outstr += 'GLOBAL:\n'
1777 outstr += misc.nice_representation(var, nb_space=4)
1778
1779 try:
1780 var = eval('self.%s' % args[1])
1781 except Exception:
1782 outstr += 'LOCAL:\nVariable %s is not a local variable\n' % args[1]
1783 else:
1784 outstr += 'LOCAL:\n'
1785 outstr += misc.nice_representation(var, nb_space=4)
1786 split = args[1].split('.')
1787 for i, name in enumerate(split):
1788 try:
1789 __import__('.'.join(split[:i+1]))
1790 exec('%s=sys.modules[\'%s\']' % (split[i], '.'.join(split[:i+1])))
1791 except ImportError:
1792 try:
1793 var = eval(args[1])
1794 except Exception, error:
1795 outstr += 'EXTERNAL:\nVariable %s is not a external variable\n' % args[1]
1796 break
1797 else:
1798 outstr += 'EXTERNAL:\n'
1799 outstr += misc.nice_representation(var, nb_space=4)
1800 else:
1801 var = eval(args[1])
1802 outstr += 'EXTERNAL:\n'
1803 outstr += misc.nice_representation(var, nb_space=4)
1804
1805 pydoc.pager(outstr)
1806
1807
1808 - def do_save(self, line, check=True):
1809 """Save the configuration file"""
1810
1811 args = self.split_arg(line)
1812
1813 if check:
1814 Cmd.check_save(self, args)
1815
1816
1817 if 'HOME' in os.environ and os.environ['HOME'] and \
1818 os.path.exists(pjoin(os.environ['HOME'], '.mg5', 'mg5_configuration.txt')):
1819 base = pjoin(os.environ['HOME'], '.mg5', 'mg5_configuration.txt')
1820 if hasattr(self, 'me_dir'):
1821 basedir = self.me_dir
1822 elif not MADEVENT:
1823 basedir = MG5DIR
1824 else:
1825 basedir = os.getcwd()
1826 elif MADEVENT:
1827
1828 for config_file in ['me5_configuration.txt', 'amcatnlo_configuration.txt']:
1829 if os.path.exists(pjoin(self.me_dir, 'Cards', config_file)):
1830 base = pjoin(self.me_dir, 'Cards', config_file)
1831 basedir = self.me_dir
1832 else:
1833 if hasattr(self, 'me_dir'):
1834 base = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
1835 if len(args) == 0 and os.path.exists(base):
1836 self.write_configuration(base, base, self.me_dir)
1837 base = pjoin(MG5DIR, 'input', 'mg5_configuration.txt')
1838 basedir = MG5DIR
1839
1840 if len(args) == 0:
1841 args.append(base)
1842 self.write_configuration(args[0], base, basedir, self.options)
1843
1845 """Write the configuration file"""
1846
1847
1848
1849
1850 logger.info('save configuration file to %s' % filepath)
1851 to_write = to_keep.keys()
1852 text = ""
1853 has_mg5_path = False
1854
1855 for line in file(basefile):
1856 if '=' in line:
1857 data, value = line.split('=',1)
1858 else:
1859 text += line
1860 continue
1861 data = data.strip()
1862 if data.startswith('#'):
1863 key = data[1:].strip()
1864 else:
1865 key = data
1866 if '#' in value:
1867 value, comment = value.split('#',1)
1868 else:
1869 comment = ''
1870 if key in to_keep:
1871 value = str(to_keep[key])
1872 else:
1873 text += line
1874 continue
1875 if key == 'mg5_path':
1876 has_mg5_path = True
1877 try:
1878 to_write.remove(key)
1879 except Exception:
1880 pass
1881 if '_path' in key:
1882
1883
1884 if not os.path.isabs(value):
1885 value = os.path.realpath(os.path.join(basedir, value))
1886 text += '%s = %s # %s \n' % (key, value, comment)
1887
1888 for key in to_write:
1889 if key in to_keep:
1890 text += '%s = %s \n' % (key, to_keep[key])
1891
1892 if not MADEVENT and not has_mg5_path:
1893 text += """\n# MG5 MAIN DIRECTORY\n"""
1894 text += "mg5_path = %s\n" % MG5DIR
1895
1896 writer = open(filepath,'w')
1897 writer.write(text)
1898 writer.close()
1899
1904 """CMD command with shell activate"""
1905
1906
1908 "Run a shell command"
1909
1910 if line.strip() is '':
1911 self.help_shell()
1912 else:
1913 logging.info("running shell command: " + line)
1914 subprocess.call(line, shell=True)
1915
1917 """ add path for shell """
1918
1919
1920
1921 if len(self.split_arg(line[0:begidx])) > 1 and line[begidx - 1] == os.path.sep:
1922 if not text:
1923 text = ''
1924 output = self.path_completion(text,
1925 base_dir=\
1926 self.split_arg(line[0:begidx])[-1])
1927 else:
1928 output = self.path_completion(text)
1929 return output
1930
1932 """help for the shell"""
1933 logger.info("-- run the shell command CMD and catch output",'$MG:color:BLUE')
1934 logger.info("syntax: shell CMD (or ! CMD)",'$MG:color:BLACK')
1935
1943 """ a class for answering a question with the path autocompletion"""
1944
1945 allowpath = False
1947 """Initializing before starting the main loop"""
1948 self.prompt = '>'
1949 self.value = None
1950 BasicCmd.preloop(self)
1951
1952 @property
1955
1956 - def __init__(self, question, allow_arg=[], default=None,
1957 mother_interface=None, *arg, **opt):
1958 self.question = question
1959 self.wrong_answer = 0
1960 self.allow_arg = [str(a) for a in allow_arg]
1961 self.history_header = ''
1962 self.default_value = str(default)
1963 self.mother_interface = mother_interface
1964
1965 if 'case' in opt:
1966 self.casesensitive = opt['case']
1967 del opt['case']
1968 elif 'casesensitive' in opt:
1969 self.casesensitive = opt['casesensitive']
1970 del opt['casesensitive']
1971 else:
1972 self.casesensistive = True
1973 super(SmartQuestion, self).__init__(*arg, **opt)
1974
1975 - def __call__(self, question, reprint_opt=True, **opts):
1976
1977 self.question = question
1978 for key,value in opts:
1979 setattr(self, key, value)
1980 if reprint_opt:
1981 print question
1982 return self.cmdloop()
1983
1984
1986 prev_timer = signal.alarm(0)
1987 if prev_timer:
1988 nb_back = len(line)
1989 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
1990 self.stdout.write(line)
1991 self.stdout.flush()
1992 try:
1993 out = {}
1994 out[' Options'] = Cmd.list_completion(text, self.allow_arg)
1995 out[' Recognized command'] = BasicCmd.completenames(self, text)
1996
1997 return self.deal_multiple_categories(out)
1998 except Exception, error:
1999 print error
2000
2001 completedefault = completenames
2002
2004
2005
2006 return dir(self)
2007
2008 - def onecmd(self, line, **opt):
2009 """catch all error and stop properly command accordingly
2010 Interpret the argument as though it had been typed in response
2011 to the prompt.
2012
2013 The return value is a flag indicating whether interpretation of
2014 commands by the interpreter should stop.
2015
2016 This allow to pass extra argument for internal call.
2017 """
2018 try:
2019 if '~/' in line and os.environ.has_key('HOME'):
2020 line = line.replace('~/', '%s/' % os.environ['HOME'])
2021 line = os.path.expandvars(line)
2022 cmd, arg, line = self.parseline(line)
2023 if not line:
2024 return self.emptyline()
2025 if cmd is None:
2026 return self.default(line)
2027 self.lastcmd = line
2028 if cmd == '':
2029 return self.default(line)
2030 else:
2031 try:
2032 func = getattr(self, 'do_' + cmd)
2033 except AttributeError:
2034 return self.default(line)
2035 return func(arg, **opt)
2036 except Exception as error:
2037 logger.warning(error)
2038 if __debug__:
2039 raise
2040
2041 - def reask(self, reprint_opt=True):
2042 pat = re.compile('\[(\d*)s to answer\]')
2043 prev_timer = signal.alarm(0)
2044
2045 if prev_timer:
2046 if pat.search(self.question):
2047 timeout = int(pat.search(self.question).groups()[0])
2048 else:
2049 timeout=20
2050 print
2051 signal.alarm(timeout)
2052 if reprint_opt:
2053 if not prev_timer:
2054 self.question = pat.sub('',self.question)
2055 print self.question
2056
2057 if self.mother_interface:
2058 answer = self.mother_interface.check_answer_in_input_file(self, 'EOF',
2059 path=self.allowpath)
2060 if answer:
2061 stop = self.default(answer)
2062 self.postcmd(stop, answer)
2063 return False
2064
2065 return False
2066
2068
2069 text=line
2070 out ={}
2071 out['Options'] = Cmd.list_completion(text, self.allow_arg)
2072 out['command'] = BasicCmd.completenames(self, text)
2073
2074 if not text:
2075 if out['Options']:
2076 logger.info( "Here is the list of all valid options:", '$MG:color:BLACK')
2077 logger.info( " "+ "\n ".join(out['Options']))
2078 if out['command']:
2079 logger.info( "Here is the list of command available:", '$MG:color:BLACK')
2080 logger.info( " "+ "\n ".join(out['command']))
2081 else:
2082 if out['Options']:
2083 logger.info( "Here is the list of all valid options starting with \'%s\'" % text, '$MG:color:BLACK')
2084 logger.info( " "+ "\n ".join(out['Options']))
2085 if out['command']:
2086 logger.info( "Here is the list of command available starting with \'%s\':" % text, '$MG:color:BLACK')
2087 logger.info( " "+ "\n ".join(out['command']))
2088 elif not out['Options']:
2089 logger.info( "No possibility starting with \'%s\'" % text, '$MG:color:BLACK')
2090 logger.info( "You can type help XXX, to see all command starting with XXX", '$MG:color:BLACK')
2094
2096 """Default action if line is not recognized"""
2097
2098 if line.strip() == '' and self.default_value is not None:
2099 self.value = self.default_value
2100 else:
2101 self.value = line
2102
2104 """If empty line, return default"""
2105
2106 if self.default_value is not None:
2107 self.value = self.default_value
2108
2109
2110 - def postcmd(self, stop, line):
2111
2112 try:
2113 if self.value in self.allow_arg:
2114 return True
2115 elif str(self.value) == 'EOF':
2116 self.value = self.default_value
2117 return True
2118 elif line and hasattr(self, 'do_%s' % line.split()[0]):
2119 return self.reask()
2120 elif self.value == 'repeat':
2121 return self.reask()
2122 elif len(self.allow_arg)==0:
2123 return True
2124 elif not self.casesensitive:
2125 for ans in self.allow_arg:
2126 if ans.lower() == self.value.lower():
2127 self.value = ans
2128 return True
2129 break
2130 else:
2131 raise Exception
2132 else:
2133 raise Exception
2134 except Exception,error:
2135 if self.wrong_answer < 100:
2136 self.wrong_answer += 1
2137 logger.warning("""%s not valid argument. Valid argument are in (%s).""" \
2138 % (self.value,','.join(self.allow_arg)))
2139 logger.warning('please retry')
2140 return False
2141 else:
2142 self.value = self.default_value
2143 return True
2144
2148
2154
2159 """ a class for answering a question with the path autocompletion"""
2160
2161 completion_prefix=''
2162 allowpath=True
2163
2164 - def completenames(self, text, line, begidx, endidx, formatting=True):
2165 prev_timer = signal.alarm(0)
2166 if prev_timer:
2167 nb_back = len(line)
2168 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
2169 self.stdout.write(line)
2170 self.stdout.flush()
2171
2172 try:
2173 out = {}
2174 out[' Options'] = Cmd.list_completion(text, self.allow_arg)
2175 out[' Path from ./'] = Cmd.path_completion(text, only_dirs = False)
2176 out[' Recognized command'] = BasicCmd.completenames(self, text)
2177
2178 return self.deal_multiple_categories(out, formatting)
2179 except Exception, error:
2180 print error
2181
2187
2189 prev_timer = signal.alarm(0)
2190 if prev_timer:
2191 nb_back = len(line)
2192 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
2193 self.stdout.write(line)
2194 self.stdout.flush()
2195 try:
2196 args = Cmd.split_arg(line[0:begidx])
2197 except Exception, error:
2198 print error
2199
2200
2201 if args[-1].endswith(os.path.sep):
2202
2203 return Cmd.path_completion(text,
2204 os.path.join('.',*[a for a in args \
2205 if a.endswith(os.path.sep)]))
2206 self.completenames(line+text)
2207
2208
2209 - def postcmd(self, stop, line):
2210 try:
2211 if self.value in self.allow_arg:
2212 return True
2213 elif self.value and os.path.isfile(self.value):
2214 return os.path.relpath(self.value)
2215 elif self.value and str(self.value) == 'EOF':
2216 self.value = self.default_value
2217 return True
2218 elif line and hasattr(self, 'do_%s' % line.split()[0]):
2219
2220 reprint_opt = True
2221 elif self.value == 'repeat':
2222 reprint_opt = True
2223 else:
2224 raise Exception
2225 except Exception, error:
2226 print """not valid argument. Valid argument are file path or value in (%s).""" \
2227 % ','.join(self.allow_arg)
2228 print 'please retry'
2229 reprint_opt = False
2230
2231 if line != 'EOF':
2232 return self.reask(reprint_opt)
2233
2240
2241
2242
2243
2244 -class CmdFile(file):
2245 """ a class for command input file -in order to debug cmd \n problem"""
2246
2253
2255 """readline method treating correctly a line whithout \n at the end
2256 (add it)
2257 """
2258 if self.lines:
2259 line = self.lines.pop(0)
2260 else:
2261 return ''
2262
2263 if line.endswith('\n'):
2264 return line
2265 else:
2266 return line + '\n'
2267
2270
2273