i have been thinking of several ways to integrate the string escape code in logprintf. the more i think about it, the more i like the idea of including in wget a stripped-down version of vsnprintf to be used inside logprintf. this function would also understand a special escape code (%e? %es?) that would actually trigger the escaping of the given string before the interpolation (but only if we print to a tty).
to test which kind of conversions are used by wget inside logprintf calls, yesterday i came up with this python 2.3 script (i know, it is not very pythonic but this is not the point since it works pretty well): #!/usr/bin/env python import sys import sets debug = False used_fmt_codes = sets.Set([]) def debug_print (str): if debug: print str def debug_format (str): pretty_print (str) examine_format (str) def is_escaped (str, index): tmp = index - 1 count = 0 while (str[tmp] == '\\'): tmp -= 1 count += 1 if count % 2: return True return False def retrieve_format_string (str): i = str.find ('"') j = str.find ('"', i + 1) while (is_escaped(str, j)): j = str.find ('"', j + 1) return str[i:j+1] def retrieve_format_code (str, index): chars = "c%msbpxXdiuofg" i = index + 1 while (str[i] not in chars): i += 1 return str[index:i+1] def examine_format (str): fmtstr = retrieve_format_string (str) i = fmtstr.find ('%') debug_print("format code(s):") while (i >= 0): fmt = retrieve_format_code (fmtstr, i) #print fmt used_fmt_codes.add(fmt) i = fmtstr.find ('%', i + len(fmt)) def pretty_print (str): print " ".join(str.split()) def process_logprintf (file, func): keep_scanning = False for line in file: if not keep_scanning: i = line.find("logprintf") if i >= 0: debug_print("found logprintf") debug_print(line[:-1]) j = line.find ('(', i + len("logprintf")) if j < 0: debug_print("checking next line for open brace") keep_scanning = True continue count = 1 debug_print("found open brace, count = %d" % count) for c in range (j+1, len(line)-1): if line[c] == '(': count += 1 debug_print("found open brace, count = %d" % count) elif line[c] == ')': count -= 1 debug_print("found closing brace, count = %d" % count) if count == 0: str = line[i:c+1] func(str) break if count != 0: debug_print("keep scanning on next line, count = %d" % count) str = line[i:-1] keep_scanning = True else: debug_print("scanning going on") debug_print(line[:-1]) for c in range (0, len(line)-1): if line[c] == '(': count += 1 debug_print("found opening brace, count = %d" % count) elif line[c] == ')': count -= 1 debug_print("found closing brace, count = %d" % count) if count == 0: str += line[:c+1] keep_scanning = False func(str) break if count != 0: debug_print("keep scanning on next line, count = %d" % count) str += line[:-1] debug_print(line[:-1]) if __name__ == "__main__": for i in range (1, len(sys.argv)): print "opening file %s" % sys.argv[i] file = open(sys.argv[i]) process_logprintf(file, examine_format) print used_fmt_codes # vim: et ts=4 sw=4 the result is: Set(['%5ld', '%%', '%d', '%ld', '%2d', '%.2f', '%3d', '%c', '%s', '%*s']) so, all the conversions we need are: - integer with long and field size - % charachter escape - charachter - string - float with decimal field size given this consideration, what i was planning to do is to borrow some code from the vsnprintf implementation in dietlibc and adapt it for our needs. what do you think about it? -- Aequam memento rebus in arduis servare mentem... Mauro Tortonesi University of Ferrara - Dept. of Eng. http://www.ing.unife.it Institute of Human & Machine Cognition http://www.ihmc.us Deep Space 6 - IPv6 for Linux http://www.deepspace6.net Ferrara Linux User Group http://www.ferrara.linux.it