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 cmd
19 import logging
20 import os
21 import pydoc
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 Exception, error:
42 if __debug__:
43 print error
44 import internal.misc as misc
45 MADEVENT = True
46
47 pjoin = os.path.join
50 """Class for run-time error"""
51
52 -def debug(debug_only=True):
53
54 def deco_debug(f):
55
56 if debug_only and not __debug__:
57 return f
58
59 def deco_f(*args, **opt):
60 try:
61 return f(*args, **opt)
62 except Exception, error:
63 print error
64 print traceback.print_exc(file=sys.stdout)
65 return
66 return deco_f
67 return deco_debug
68
74 """Simple extension for the readline"""
75
79
81 """convert the multiple category in a formatted list understand by our
82 specific readline parser"""
83
84 if 'libedit' in readline.__doc__:
85
86 out = []
87 for name, opt in dico.items():
88 out += opt
89 return out
90
91
92 out = []
93 valid=0
94
95 for name, opt in dico.items():
96 if not opt:
97 continue
98 name = name.replace(' ', '_')
99 valid += 1
100 out.append(opt[0].rstrip()+'@@'+name+'@@')
101
102 d = {}
103 for x in opt:
104 d[x] = 1
105 opt = list(d.keys())
106 opt.sort()
107 out += opt
108
109
110 if valid == 1:
111 out = out[1:]
112 return out
113
114 @debug()
116 """print auto-completions by category"""
117 longest_match_length += len(self.completion_prefix)
118 try:
119 if len(matches) == 1:
120 self.stdout.write(matches[0]+' ')
121 return
122 self.stdout.write('\n')
123 l2 = [a[-2:] for a in matches]
124 if '@@' in l2:
125 nb_column = self.getTerminalSize()//(longest_match_length+1)
126 pos=0
127 for val in self.completion_matches:
128 if val.endswith('@@'):
129 category = val.rsplit('@@',2)[1]
130 category = category.replace('_',' ')
131 self.stdout.write('\n %s:\n%s\n' % (category, '=' * (len(category)+2)))
132 start = 0
133 pos = 0
134 continue
135 elif pos and pos % nb_column ==0:
136 self.stdout.write('\n')
137 self.stdout.write(self.completion_prefix + val + \
138 ' ' * (longest_match_length +1 -len(val)))
139 pos +=1
140 self.stdout.write('\n')
141 else:
142
143 nb_column = self.getTerminalSize()//(longest_match_length+1)
144 for i,val in enumerate(matches):
145 if i and i%nb_column ==0:
146 self.stdout.write('\n')
147 self.stdout.write(self.completion_prefix + val + \
148 ' ' * (longest_match_length +1 -len(val)))
149 self.stdout.write('\n')
150
151 self.stdout.write(self.prompt+readline.get_line_buffer())
152 self.stdout.flush()
153 except Exception, error:
154 if __debug__:
155 print error
156
158 def ioctl_GWINSZ(fd):
159 try:
160 import fcntl, termios, struct, os
161 cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
162 '1234'))
163 except:
164 return None
165 return cr
166 cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
167 if not cr:
168 try:
169 fd = os.open(os.ctermid(), os.O_RDONLY)
170 cr = ioctl_GWINSZ(fd)
171 os.close(fd)
172 except:
173 pass
174 if not cr:
175 try:
176 cr = (env['LINES'], env['COLUMNS'])
177 except:
178 cr = (25, 80)
179 return int(cr[1])
180
182 """Return the next possible completion for 'text'.
183 If a command has not been entered, then complete against command list.
184 Otherwise try to call complete_<command> to get list of completions.
185 """
186
187 if state == 0:
188 import readline
189 origline = readline.get_line_buffer()
190 line = origline.lstrip()
191 stripped = len(origline) - len(line)
192 begidx = readline.get_begidx() - stripped
193 endidx = readline.get_endidx() - stripped
194
195 if ';' in line:
196 begin, line = line.rsplit(';',1)
197 begidx = begidx - len(begin) - 1
198 endidx = endidx - len(begin) - 1
199 if line[:begidx] == ' ' * begidx:
200 begidx=0
201
202 if begidx>0:
203 cmd, args, foo = self.parseline(line)
204 if cmd == '':
205 compfunc = self.completedefault
206 else:
207 try:
208 compfunc = getattr(self, 'complete_' + cmd)
209 except AttributeError:
210 compfunc = self.completedefault
211 else:
212 compfunc = self.completenames
213
214
215 if line and begidx > 2 and line[begidx-2:begidx] == '\ ':
216 Ntext = line.split(os.path.sep)[-1]
217 self.completion_prefix = Ntext.rsplit('\ ', 1)[0] + '\ '
218 to_rm = len(self.completion_prefix) - 1
219 Nbegidx = len(line.rsplit(os.path.sep, 1)[0]) + 1
220 data = compfunc(Ntext.replace('\ ', ' '), line, Nbegidx, endidx)
221 self.completion_matches = [p[to_rm:] for p in data
222 if len(p)>to_rm]
223
224 elif line and line[begidx-1] == '-':
225 try:
226 Ntext = line.split()[-1]
227 self.completion_prefix = Ntext.rsplit('-',1)[0] +'-'
228 to_rm = len(self.completion_prefix)
229 Nbegidx = len(line.rsplit(None, 1)[0])
230 data = compfunc(Ntext, line, Nbegidx, endidx)
231 self.completion_matches = [p[to_rm:] for p in data
232 if len(p)>to_rm]
233 except Exception, error:
234 print error
235 else:
236 self.completion_prefix = ''
237 self.completion_matches = compfunc(text, line, begidx, endidx)
238
239
240 self.completion_matches = [ (l[-1] in [' ','@','=',os.path.sep]
241 and l or (l+' ')) for l in self.completion_matches if l]
242
243 try:
244 return self.completion_matches[state]
245 except IndexError, error:
246
247
248
249
250 return None
251
253 """Extension of the cmd object for only the check command"""
254
255 - def check_history(self, args):
256 """check the validity of line"""
257
258 if len(args) > 1:
259 self.help_history()
260 raise self.InvalidCmd('\"history\" command takes at most one argument')
261
262 if not len(args):
263 return
264
265 if args[0] =='.':
266 if not self._export_dir:
267 raise self.InvalidCmd("No default directory is defined for \'.\' option")
268 elif args[0] != 'clean':
269 dirpath = os.path.dirname(args[0])
270 if dirpath and not os.path.exists(dirpath) or \
271 os.path.isdir(args[0]):
272 raise self.InvalidCmd("invalid path %s " % dirpath)
273
275 """check that the line is compatible with save options"""
276
277 if len(args) > 2:
278 self.help_save()
279 raise self.InvalidCmd, 'too many arguments for save command.'
280
281 if len(args) == 2:
282 if args[0] != 'options':
283 self.help_save()
284 raise self.InvalidCmd, '\'%s\' is not recognized as first argument.' % \
285 args[0]
286 else:
287 args.pop(0)
288
290 """Extension of the cmd object for only the help command"""
291
293 logger.info("syntax: quit")
294 logger.info("-- terminates the application")
295
296 help_EOF = help_quit
297
298 - def help_history(self):
299 logger.info("syntax: history [FILEPATH|clean|.] ")
300 logger.info(" If FILEPATH is \'.\' and \'output\' is done,")
301 logger.info(" Cards/proc_card_mg5.dat will be used.")
302 logger.info(" If FILEPATH is omitted, the history will be output to stdout.")
303 logger.info(" \"clean\" will remove all entries from the history.")
304
306 logger.info("syntax: help")
307 logger.info("-- access to the in-line help" )
308
310 """help text for save"""
311 logger.info("syntax: save [options] [FILEPATH]")
312 logger.info("-- save options configuration to filepath.")
313
315 """help for display command"""
316 logger.info("syntax: display " + "|".join(self._display_opts))
317 logger.info("-- display a the status of various internal state variables")
318
320 """Extension of the cmd object for only the complete command"""
321
323 args = self.split_arg(line[0:begidx])
324
325 if len(args) == 1:
326 return self.list_completion(text, self._display_opts)
327
328 - def complete_history(self, text, line, begidx, endidx):
329 "Complete the history command"
330
331 args = self.split_arg(line[0:begidx])
332
333
334 if args[-1].endswith(os.path.sep):
335 return self.path_completion(text,
336 os.path.join('.',*[a for a in args \
337 if a.endswith(os.path.sep)]))
338
339 if len(args) == 1:
340 return self.path_completion(text)
341
343 "Complete the save command"
344
345 args = self.split_arg(line[0:begidx])
346
347
348 if len(args) == 1:
349 return self.list_completion(text, ['options'])
350
351
352 if args[-1].endswith(os.path.sep):
353 return self.path_completion(text,
354 pjoin('.',*[a for a in args if a.endswith(os.path.sep)]),
355 only_dirs = True)
356
357
358 if len(args) == 2:
359 return self.path_completion(text)
360
361 -class Cmd(CheckCmd, HelpCmd, CompleteCmd, BasicCmd):
362 """Extension of the cmd.Cmd command line.
363 This extensions supports line breaking, history, comments,
364 internal call to cmdline, path completion,...
365 this class should be MG5 independent"""
366
367
368 next_possibility = {}
369 history_header = ""
370
371 _display_opts = ['options','variable']
372
374 """expected error for wrong command"""
375 pass
376
377 ConfigurationError = InvalidCmd
378
379 debug_output = 'debug'
380 error_debug = """Please report this bug to developers\n
381 More information is found in '%s'.\n
382 Please attach this file to your report."""
383 config_debug = error_debug
384
385 keyboard_stop_msg = """stopping all current operation
386 in order to quit the program please enter exit"""
387
388
390 """Init history and line continuation"""
391
392 self.log = True
393 self.history = []
394 self.save_line = ''
395 cmd.Cmd.__init__(self, *arg, **opt)
396 self.__initpos = os.path.abspath(os.getcwd())
397 self.child = None
398 self.mother = None
399 self.inputfile = None
400 self.stored_line = ''
401
402
403
404
406 """ A suite of additional function needed for in the cmd
407 this implement history, line breaking, comment treatment,...
408 """
409
410 if not line:
411 return line
412 line = line.lstrip()
413
414
415
416 if ';' in line:
417 lines = line.split(';')
418 else:
419 lines = [line]
420 for l in lines:
421 l = l.strip()
422 if not (l.startswith("history") or l.startswith('help') or \
423 l.startswith('#*')):
424 self.history.append(l)
425
426
427 if self.save_line:
428 line = self.save_line + line
429 self.save_line = ''
430
431
432 if line.endswith('\\'):
433 self.save_line = line[:-1]
434 return ''
435
436
437 if '#' in line:
438 line = line.split('#')[0]
439
440
441 if ';' in line and not (line.startswith('!') or line.startswith('shell')):
442 for subline in line.split(';'):
443 stop = self.onecmd(subline)
444 stop = self.postcmd(stop, subline)
445 return ''
446
447
448 return line
449
451 """ """
452
453 if self.child:
454 return self.child.nice_error_handling(error, line)
455
456 os.chdir(self.__initpos)
457
458 self.log = False
459 if os.path.exists(self.debug_output):
460 os.remove(self.debug_output)
461 try:
462 cmd.Cmd.onecmd(self, 'history %s' % self.debug_output.replace(' ', '\ '))
463 except Exception, error:
464 print error
465
466 debug_file = open(self.debug_output, 'a')
467 traceback.print_exc(file=debug_file)
468
469 if self.history and line == self.history[-1]:
470 error_text = 'Command \"%s\" interrupted with error:\n' % line
471 elif self.history:
472 error_text = 'Command \"%s\" interrupted in sub-command:\n' %line
473 error_text += '\"%s\" with error:\n' % self.history[-1]
474 else:
475 error_text = ''
476 error_text += '%s : %s\n' % (error.__class__.__name__,
477 str(error).replace('\n','\n\t'))
478 error_text += self.error_debug % {'debug': self.debug_output}
479 logger_stderr.critical(error_text)
480
481
482 try:
483 self.do_display('options', debug_file)
484 except Exception, error:
485 debug_file.write('Fail to write options with error %s' % error)
486
487
488 if self.use_rawinput == False:
489 return True
490 return False
491
493 if self.child:
494 return self.child.nice_user_error(error, line)
495
496 os.chdir(self.__initpos)
497 if line == self.history[-1]:
498 error_text = 'Command \"%s\" interrupted with error:\n' % line
499 else:
500 error_text = 'Command \"%s\" interrupted in sub-command:\n' %line
501 error_text += '\"%s\" with error:\n' % self.history[-1]
502 error_text += '%s : %s' % (error.__class__.__name__,
503 str(error).replace('\n','\n\t'))
504 logger_stderr.error(error_text)
505
506 if self.use_rawinput == False:
507 return True
508
509 self.history.pop()
510 return False
511
513 if self.child:
514 return self.child.nice_user_error(error, line)
515
516 os.chdir(self.__initpos)
517 if not self.history or line == self.history[-1]:
518 error_text = 'Error detected in \"%s\"\n' % line
519 else:
520 error_text = 'Error detected in sub-command %s\n' % self.history[-1]
521 error_text += 'write debug file %s \n' % self.debug_output
522 self.log = False
523 cmd.Cmd.onecmd(self, 'history %s' % self.debug_output)
524 debug_file = open(self.debug_output, 'a')
525 traceback.print_exc(file=debug_file)
526 error_text += self.config_debug % {'debug' :self.debug_output}
527 error_text += '%s : %s' % (error.__class__.__name__,
528 str(error).replace('\n','\n\t'))
529 logger_stderr.error(error_text)
530
531
532 try:
533 self.do_display('options', debug_file)
534 except Exception, error:
535 debug_file.write('Fail to write options with error %s' % error)
536
537 if self.use_rawinput == False:
538 return True
539
540 if self.history:
541 self.history.pop()
542 return False
543
544
565
567 """action to perform to close nicely on a keyboard interupt"""
568 pass
569
570 - def exec_cmd(self, line, errorhandling=False, printcmd=True,
571 precmd=False, postcmd=True):
572 """for third party call, call the line with pre and postfix treatment
573 without global error handling """
574
575 if printcmd:
576 logger.info(line)
577 if self.child:
578 current_interface = self.child
579 else:
580 current_interface = self
581
582 if precmd:
583 line = current_interface.precmd(line)
584 if errorhandling:
585 stop = current_interface.onecmd(line)
586 else:
587 stop = cmd.Cmd.onecmd(current_interface, line)
588 if postcmd:
589 stop = current_interface.postcmd(stop, line)
590 return stop
591
593 """for third party call, call the line with pre and postfix treatment
594 with global error handling"""
595
596 return self.exec_cmd(line, errorhandling=True, precmd=True)
597
599 """If empty line, do nothing. Default is repeat previous command."""
600 pass
601
603 """Default action if line is not recognized"""
604
605
606 logger.warning("Command \"%s\" not recognized, please try again" % \
607 line.split()[0])
608
609
610 @staticmethod
612 """Split a line of arguments"""
613
614 split = line.split()
615 out=[]
616 tmp=''
617 for data in split:
618 if data[-1] == '\\':
619 tmp += data[:-1]+' '
620 elif tmp:
621 tmp += data
622 tmp = os.path.expanduser(os.path.expandvars(tmp))
623 out.append(tmp)
624 else:
625 out.append(data)
626 return out
627
629 """if the line finish with a '-' the code splits in a weird way
630 on GNU_SPLITTING"""
631
632 line = line.lstrip()
633 if line[-1] in [' ','\t']:
634 return '', line, len(line),len(enidx)
635 return text, line, begidx, endidx
636
637
638
639
640
641 - def do_history(self, line):
642 """write in a file the suite of command that was used"""
643
644 args = self.split_arg(line)
645
646 self.check_history(args)
647
648 if len(args) == 0:
649 print '\n'.join(self.history)
650 return
651 elif args[0] == 'clean':
652 self.history = []
653 logger.info('History is cleaned')
654 return
655 elif args[0] == '.':
656 output_file = os.path.join(self._export_dir, 'Cards', \
657 'proc_card_mg5.dat')
658 output_file = open(output_file, 'w')
659 else:
660 output_file = open(args[0], 'w')
661
662
663 text = self.get_history_header()
664 text += ('\n'.join(self.history) + '\n')
665
666
667 output_file.write(text)
668 output_file.close()
669
670 if self.log:
671 logger.info("History written to " + output_file.name)
672
673 - def clean_history(self, to_keep=['set','add','load'],
674 remove_bef_lb1=None,
675 to_remove=['open','display','launch'],
676 keep_last=False):
677 """Remove all commands in arguments from history"""
678
679
680 nline = -1
681 last = 0
682 while nline > -len(self.history):
683
684 if remove_bef_lb1 and self.history[nline].startswith(remove_bef_lb1):
685 if last:
686 last = 2
687 self.history.pop(nline)
688 continue
689 else:
690 last=1
691 if nline == -1 and keep_last:
692 nline -=1
693 continue
694 if any([self.history[nline].startswith(arg) for arg in to_remove]):
695 self.history.pop(nline)
696 continue
697 if last == 2:
698 if not any([self.history[nline].startswith(arg) for arg in to_keep]):
699 self.history.pop(nline)
700 continue
701 else:
702 nline -= 1
703 else:
704 nline -= 1
705
707
708 if self.history:
709 self.history.pop()
710
711
712 self.inputfile = open(filepath)
713 for line in self.inputfile:
714
715 line = line.replace('\n', '').strip()
716
717 if line:
718 self.exec_cmd(line, precmd=True)
719 if self.stored_line:
720 self.exec_cmd(self.stored_line, precmd=True)
721 self.stored_line = ''
722
723 if self.child:
724 self.child.exec_cmd('quit')
725
726 return
727
729 """Default history header"""
730
731 return self.history_header
732
734 """Define a sub cmd_interface"""
735
736
737 self.child = obj_instance
738 self.child.mother = self
739
740 if self.use_rawinput and interface:
741
742 obj_instance.cmdloop()
743 stop = obj_instance.postloop()
744 return stop
745 if self.inputfile:
746
747 obj_instance.inputfile = self.inputfile
748
749 if not interface:
750 return self.child
751
752 - def postloop(self):
753 """ """
754
755 args = self.split_arg(self.lastcmd)
756 if args and args[0] in ['quit','exit']:
757 if 'all' in args:
758 return True
759 if len(args) >1 and args[1].isdigit():
760 if args[1] not in ['0', '1']:
761 return True
762 return False
763
764
765
766
767 @staticmethod
774
775 signal.signal(signal.SIGALRM, handle_alarm)
776
777 if fct is None:
778 fct = raw_input
779
780 if timeout:
781 signal.alarm(timeout)
782 question += '[%ss to answer] ' % (timeout)
783 try:
784 result = fct(question)
785 except TimeOutError:
786 if noerror:
787 print '\nuse %s' % default
788 if fct_timeout:
789 fct_timeout(True)
790 return default
791 else:
792 signal.alarm(0)
793 raise
794 finally:
795 signal.alarm(0)
796 if fct_timeout:
797 fct_timeout(False)
798 return result
799
800
801
802
803
804 - def ask(self, question, default, choices=[], path_msg=None,
805 timeout = True, fct_timeout=None):
806 """ ask a question with some pre-define possibility
807 path info is
808 """
809
810 if path_msg:
811 path_msg = [path_msg]
812 else:
813 path_msg = []
814
815 if timeout:
816 try:
817 timeout = self.options['timeout']
818 except:
819 pass
820
821
822 if choices + path_msg:
823 question += ' ['
824 question += "\033[%dm%s\033[0m, " % (4, default)
825 for data in choices[:9] + path_msg:
826 if default == data:
827 continue
828 else:
829 question += "%s, " % data
830
831 if len(choices) > 9:
832 question += '... , '
833 question = question[:-2]+']'
834
835 if path_msg:
836 f = lambda q: raw_path_input(q, allow_arg=choices, default=default)
837 else:
838 f = lambda q: smart_input(q, allow_arg=choices, default=default)
839
840 answer = self.check_answer_in_input_file(choices, path_msg)
841 if answer is not None:
842 return answer
843
844 value = Cmd.timed_input(question, default, timeout=timeout,
845 fct=f, fct_timeout=fct_timeout)
846
847 return value
848
875
877 """store a line of the input file which should be executed by the higher mother"""
878
879 if self.mother:
880 self.mother.store_line(line)
881 else:
882 self.stored_line = line
883
885 if self.mother:
886 return self.mother.check_stored_line()
887 else:
888 return self.stored_line
889
890
892 """ exit the mainloop() """
893
894 if self.child:
895 self.child.exec_cmd('quit ' + line, printcmd=False)
896 return
897 elif self.mother:
898 self.mother.child = None
899 if line == 'all':
900 pass
901 elif line:
902 level = int(line) - 1
903 if level:
904 self.mother.lastcmd = 'quit %s' % level
905
906 return True
907
908
909 do_EOF = do_quit
910 do_exit = do_quit
911
912
913
914
915
917 """ propose some usefull possible action """
918
919
920 if line:
921 return cmd.Cmd.do_help(self, line)
922
923
924 names = self.get_names()
925 cmds = {}
926 names.sort()
927
928 prevname = ''
929 for name in names:
930 if name[:3] == 'do_':
931 if name == prevname:
932 continue
933 prevname = name
934 cmdname=name[3:]
935 try:
936 doc = getattr(self.cmd, name).__doc__
937 except:
938 doc = None
939 if not doc:
940 doc = getattr(self, name).__doc__
941 if not doc:
942 tag = "Documented commands"
943 elif ':' in doc:
944 tag = doc.split(':',1)[0]
945 else:
946 tag = "Documented commands"
947 if tag in cmds:
948 cmds[tag].append(cmdname)
949 else:
950 cmds[tag] = [cmdname]
951
952
953 self.stdout.write("%s\n"%str(self.doc_leader))
954 tag = "Documented commands"
955 header = "%s (type help <topic>):" % tag
956 self.print_topics(header, cmds[tag], 15,80)
957 for name, item in cmds.items():
958 if name == "Documented commands":
959 continue
960 if name == "Not in help":
961 continue
962 header = "%s (type help <topic>):" % name
963 self.print_topics(header, item, 15,80)
964
965
966
967 if len(self.history) == 0:
968 last_action_2 = last_action = 'start'
969 else:
970 last_action_2 = last_action = 'none'
971
972 pos = 0
973 authorize = self.next_possibility.keys()
974 while last_action_2 not in authorize and last_action not in authorize:
975 pos += 1
976 if pos > len(self.history):
977 last_action_2 = last_action = 'start'
978 break
979
980 args = self.history[-1 * pos].split()
981 last_action = args[0]
982 if len(args)>1:
983 last_action_2 = '%s %s' % (last_action, args[1])
984 else:
985 last_action_2 = 'none'
986
987 print 'Contextual Help'
988 print '==============='
989 if last_action_2 in authorize:
990 options = self.next_possibility[last_action_2]
991 elif last_action in authorize:
992 options = self.next_possibility[last_action]
993
994 text = 'The following command(s) may be useful in order to continue.\n'
995 for option in options:
996 text+='\t %s \n' % option
997 print text
998
1000 """Advanced commands: basic display"""
1001
1002 args = self.split_arg(line)
1003
1004
1005 if len(args) == 0:
1006 self.help_display()
1007 raise self.InvalidCmd, 'display require at least one argument'
1008
1009 if args[0] == "options":
1010 outstr = "Value of current Options:\n"
1011 for key, value in self.options.items():
1012 outstr += '%25s \t:\t%s\n' %(key,value)
1013 output.write(outstr)
1014
1015 elif args[0] == "variable":
1016 outstr = "Value of Internal Variable:\n"
1017 try:
1018 var = eval(args[1])
1019 except:
1020 outstr += 'GLOBAL:\nVariable %s is not a global variable\n' % args[1]
1021 else:
1022 outstr += 'GLOBAL:\n'
1023 outstr += misc.nice_representation(var, nb_space=4)
1024
1025 try:
1026 var = eval('self.%s' % args[1])
1027 except:
1028 outstr += 'LOCAL:\nVariable %s is not a local variable\n' % args[1]
1029 else:
1030 outstr += 'LOCAL:\n'
1031 outstr += misc.nice_representation(var, nb_space=4)
1032
1033 pydoc.pager(outstr)
1034
1035
1036 - def do_save(self, line, check=True):
1037 """Save the configuration file"""
1038
1039 args = self.split_arg(line)
1040
1041 if check:
1042 Cmd.check_save(self, args)
1043
1044
1045 if'HOME' in os.environ and os.environ['HOME'] and \
1046 os.path.exists(pjoin(os.environ['HOME'], '.mg5', 'mg5_configuration.txt')):
1047 base = pjoin(os.environ['HOME'], '.mg5', 'mg5_configuration.txt')
1048 if hasattr(self, 'me_dir'):
1049 basedir = self.me_dir
1050 elif not MADEVENT:
1051 basedir = MG5DIR
1052 else:
1053 basedir = os.getcwd()
1054 elif MADEVENT:
1055
1056 base = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
1057 basedir = self.me_dir
1058 else:
1059 if hasattr(self, 'me_dir'):
1060 base = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt')
1061 if len(args) == 0 and os.path.exists(base):
1062 self.write_configuration(base, base, self.me_dir)
1063 base = pjoin(MG5DIR, 'input', 'mg5_configuration.txt')
1064 basedir = MG5DIR
1065
1066 if len(args) == 0:
1067 args.append(base)
1068 self.write_configuration(args[0], base, basedir)
1069
1071 """Write the configuration file"""
1072
1073
1074
1075
1076 logger.info('save configuration file to %s' % filepath)
1077 to_write = self.options.keys()[:]
1078 text = ""
1079
1080 for line in file(basefile):
1081 if '#' in line:
1082 data, comment = line.split('#',1)
1083 else:
1084 data, comment = line, ''
1085 data = data.split('=')
1086 if len(data) !=2:
1087 text += line
1088 continue
1089 key = data[0].strip()
1090 if key in self.options:
1091 value = str(self.options[key])
1092 else:
1093 value = data[1].strip()
1094 try:
1095 to_write.remove(key)
1096 except:
1097 pass
1098 if '_path' in key:
1099
1100
1101 if value.startswith('./'):
1102 value = os.path.realpath(os.path.join(basedir, value))
1103 text += '%s = %s # %s \n' % (key, value, comment)
1104 for key in to_write:
1105 if key in self.options:
1106 text += '%s = %s \n' % (key,self.options[key])
1107 else:
1108 text += '%s = %s \n' % (key,self.options[key])
1109 writer = open(filepath,'w')
1110 writer.write(text)
1111 writer.close()
1112
1113
1114
1115
1116 @staticmethod
1118 """Propose completions of text in list"""
1119
1120 if not text:
1121 completions = list
1122 else:
1123 completions = [ f
1124 for f in list
1125 if f.startswith(text)
1126 ]
1127
1128 return completions
1129
1130
1131 @staticmethod
1132 - def path_completion(text, base_dir = None, only_dirs = False,
1133 relative=True):
1134 """Propose completions of text to compose a valid path"""
1135
1136 if base_dir is None:
1137 base_dir = os.getcwd()
1138
1139 base_dir = os.path.expanduser(os.path.expandvars(base_dir))
1140
1141 prefix, text = os.path.split(text)
1142 base_dir = os.path.join(base_dir, prefix)
1143 if prefix:
1144 prefix += os.path.sep
1145
1146 if only_dirs:
1147 completion = [prefix + f
1148 for f in os.listdir(base_dir)
1149 if f.startswith(text) and \
1150 os.path.isdir(os.path.join(base_dir, f)) and \
1151 (not f.startswith('.') or text.startswith('.'))
1152 ]
1153 else:
1154 completion = [ prefix + f
1155 for f in os.listdir(base_dir)
1156 if f.startswith(text) and \
1157 os.path.isfile(os.path.join(base_dir, f)) and \
1158 (not f.startswith('.') or text.startswith('.'))
1159 ]
1160
1161 completion = completion + \
1162 [prefix + f + os.path.sep
1163 for f in os.listdir(base_dir)
1164 if f.startswith(text) and \
1165 os.path.isdir(os.path.join(base_dir, f)) and \
1166 (not f.startswith('.') or text.startswith('.'))
1167 ]
1168
1169 if relative:
1170 completion += [prefix + f for f in ['.'+os.path.sep, '..'+os.path.sep] if \
1171 f.startswith(text) and not prefix.startswith('.')]
1172
1173 completion = [a.replace(' ','\ ') for a in completion]
1174 return completion
1175
1180 """CMD command with shell activate"""
1181
1182
1184 "Run a shell command"
1185
1186 if line.strip() is '':
1187 self.help_shell()
1188 else:
1189 logging.info("running shell command: " + line)
1190 subprocess.call(line, shell=True)
1191
1193 """ add path for shell """
1194
1195
1196
1197 if len(self.split_arg(line[0:begidx])) > 1 and line[begidx - 1] == os.path.sep:
1198 if not text:
1199 text = ''
1200 output = self.path_completion(text,
1201 base_dir=\
1202 self.split_arg(line[0:begidx])[-1])
1203 else:
1204 output = self.path_completion(text)
1205 return output
1206
1208 """help for the shell"""
1209
1210 logger.info("syntax: shell CMD (or ! CMD)")
1211 logger.info("-- run the shell command CMD and catch output")
1212
1220 """ a class for answering a question with the path autocompletion"""
1221
1223 """Initializing before starting the main loop"""
1224 self.prompt = ''
1225 self.value = None
1226 BasicCmd.preloop(self)
1227
1228 - def __init__(self, allow_arg=[], default=None, *arg, **opt):
1234
1236 prev_timer = signal.alarm(0)
1237 if prev_timer:
1238 nb_back = len(line)
1239 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
1240 self.stdout.write(line)
1241 self.stdout.flush()
1242 try:
1243 return Cmd.list_completion(text, self.allow_arg)
1244 except Exception, error:
1245 print error
1246
1248 """Default action if line is not recognized"""
1249
1250 if line.strip() == '' and self.default_value is not None:
1251 self.value = self.default_value
1252 else:
1253 self.value = line
1254
1256 """If empty line, return default"""
1257
1258 if self.default_value is not None:
1259 self.value = self.default_value
1260
1261 - def postcmd(self, stop, line):
1262
1263 try:
1264 if self.value in self.allow_arg:
1265 return True
1266 elif str(self.value) == 'EOF':
1267 self.value = self.default_value
1268 return True
1269 else:
1270 raise Exception
1271 except Exception:
1272 if self.wrong_answer < 100:
1273 self.wrong_answer += 1
1274 print """%s not valid argument. Valid argument are in (%s).""" \
1275 % (self.value,','.join(self.allow_arg))
1276 print 'please retry'
1277 return False
1278 else:
1279 self.value = self.default_value
1280 return True
1281
1283 cmd.Cmd.cmdloop(self, intro)
1284 return self.value
1285
1291
1296 """ a class for answering a question with the path autocompletion"""
1297
1298
1300 prev_timer = signal.alarm(0)
1301 if prev_timer:
1302 nb_back = len(line)
1303 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
1304 self.stdout.write(line)
1305 self.stdout.flush()
1306 try:
1307 out = {}
1308 out[' Options'] = SmartQuestion.completenames(self, text, line)
1309 out[' Path from ./'] = Cmd.path_completion(text, only_dirs = False)
1310
1311 return self.deal_multiple_categories(out)
1312 except Exception, error:
1313 print error
1314
1316 prev_timer = signal.alarm(0)
1317 if prev_timer:
1318 nb_back = len(line)
1319 self.stdout.write('\b'*nb_back + '[timer stopped]\n')
1320 self.stdout.write(line)
1321 self.stdout.flush()
1322 try:
1323 args = Cmd.split_arg(line[0:begidx])
1324 except Exception, error:
1325 print error
1326
1327
1328 if args[-1].endswith(os.path.sep):
1329
1330 return Cmd.path_completion(text,
1331 os.path.join('.',*[a for a in args \
1332 if a.endswith(os.path.sep)]))
1333 self.completenames(line+text)
1334
1335
1336 - def postcmd(self, stop, line):
1337
1338 try:
1339 if self.value in self.allow_arg:
1340 return True
1341 elif os.path.isfile(self.value):
1342 return os.path.relpath(self.value)
1343 else:
1344 raise Exception
1345 except Exception, error:
1346 print """not valid argument. Valid argument are file path or value in (%s).""" \
1347 % ','.join(self.allow_arg)
1348 print 'please retry'
1349 return False
1350
1356
1357
1358
1359
1360 -class CmdFile(file):
1361 """ a class for command input file -in order to debug cmd \n problem"""
1362
1364
1365 file.__init__(self, name, opt)
1366 self.text = file.read(self)
1367 self.close()
1368 self.lines = self.text.split('\n')
1369
1371 """readline method treating correctly a line whithout \n at the end
1372 (add it)
1373 """
1374 if self.lines:
1375 line = self.lines.pop(0)
1376 else:
1377 return ''
1378
1379 if line.endswith('\n'):
1380 return line
1381 else:
1382 return line + '\n'
1383
1386
1389