#!/usr/local/bin/python2.3 import sys, os, string, getopt, re, signal, sys #some default definitions colours = { 'none' : "", 'default' : "\033[0m", 'bold' : "\033[1m", 'underline' : "\033[4m", 'blink' : "\033[5m", 'reverse' : "\033[7m", 'concealed' : "\033[8m", 'black' : "\033[30m", 'red' : "\033[31m", 'green' : "\033[32m", 'yellow' : "\033[33m", 'blue' : "\033[34m", 'magenta' : "\033[35m", 'cyan' : "\033[36m", 'white' : "\033[37m", 'on_black' : "\033[40m", 'on_red' : "\033[41m", 'on_green' : "\033[42m", 'on_yellow' : "\033[43m", 'on_blue' : "\033[44m", 'on_magenta' : "\033[45m", 'on_cyan' : "\033[46m", 'on_white' : "\033[47m", 'beep' : "\007", 'previous' : "prev", 'unchanged' : "unchanged", # non-standard attributes, supported by some terminals 'dark' : "\033[2m", 'italic' : "\033[3m", 'rapidblink' : "\033[6m", 'strikethrough': "\033[9m", } # ignore ctrl C - this is not ideal for standalone grcat, but # enables propagating SIGINT to the other subprocess in grc signal.signal(signal.SIGINT, signal.SIG_IGN) def add2list(clist, m, patterncolour): for group in range(0, len(m.groups()) +1): if group < len(patterncolour): clist.append((m.start(group), m.end(group), patterncolour[group])) else: clist.append((m.start(group), m.end(group), patterncolour[0])) def get_colour(x): if colours.has_key(x): return colours[x] elif len(x)>=2 and x[0]=='"' and x[-1]=='"': return eval(x) else: raise ValueError, 'Bad colour specified: '+x home = [] conffile = None if os.environ.has_key('HOME'): home = [os.environ['HOME']+"/.grc/"] conffilepath = home + ["/usr/local/share/grc/", "/usr/share/grc/", ""] for i in conffilepath: if os.path.isfile(i+sys.argv[1]): conffile = i+sys.argv[1] break if not conffile: sys.stderr.write("config file [%s] not found\n" % sys.argv[1]) sys.exit(1) regexplist = [] f = open(conffile, "r") is_last = 0 split = string.split join = string.join lower = string.lower letters = string.letters while not is_last: ll = {'count':"more"} while 1: l = f.readline() if l == "": is_last = 1 break if l[0] == "#" or l[0] == '\012': continue if not l[0] in letters: break keyword, value = split(l[:-1], "=", 1) keyword = lower(keyword) if not keyword in ["regexp", "colours", "count", "command", "skip"]: raise "Invalid keyword" ll[keyword] = value # Split string into one string per regex group # e.g. split "brown bold, red" into "brown bold" and # "red" #colstrings = [] #for colgroup in split(ll['colours'], ','): # colourlist = split(colgroup) # c = "" # for i in colourlist : # c = c + colours[i] # colstrings.append(c) # do not try to understand the optimized form below :-) if ll.has_key("colours"): colstrings = map( lambda colgroup: (join(map(lambda x: get_colour(x), split(colgroup)),'')), split(ll['colours'], ',') ) ll['colours'] = colstrings cs = ll['count'] ll['regexp'] = re.compile(ll['regexp']).search regexplist.append(ll) prevcolour = colours['default'] prevcount = "more" blockflag = 0 freadline = sys.stdin.readline while 1: line = freadline() if line == "" : break line = line[:-1] clist = [] skip = 0 for pattern in regexplist: pos = 0 has_key = pattern.has_key currcount = pattern['count'] while 1: m = pattern['regexp'](line, pos) if m: if has_key('colours'): if currcount == "block": blockflag = 1 blockcolour = pattern['colours'][0] currcount = "stop" break elif currcount == "unblock": blockflag = 0 blockcolour = colours['default'] currcount = "stop" add2list(clist, m, pattern['colours']) if currcount == "previous": currcount = prevcount if currcount == "stop": break if currcount == "more": prevcount = "more" pos = m.end(0) else: prevcount = "once" pos = len(line) if has_key('command'): os.system(pattern['command']) if not has_key('colours'): break if has_key('skip'): skip = pattern['skip'] in ("yes", "1", "true") if not has_key('colours'): break else: break if m and currcount == "stop": prevcount = "stop" break if len(clist) == 0: prevcolour = colours['default'] first_char = 0 last_char = 0 length_line = len(line) if blockflag == 0: cline = (length_line+1)*[colours['default']] for i in clist: # each position in the string has its own colour if i[2] == "prev": cline[i[0]:i[1]] = [colours['default']+prevcolour]*(i[1]-i[0]) elif i[2] != "unchanged": cline[i[0]:i[1]] = [colours['default']+i[2]]*(i[1]-i[0]) if i[0] == 0: first_char = 1 if i[2] != "prev": prevcolour = i[2] if i[1] == length_line: last_char = 1 if first_char == 0 or last_char == 0: prevcolour = colours['default'] else: cline = (length_line+1)*[blockcolour] nline = "" clineprev = "" if not skip: for i in range(len(line)): if cline[i] == clineprev: nline = nline + line[i] else: nline = nline + cline[i] + line[i] clineprev = cline[i] nline = nline + colours['default'] print nline