[1] | 1 | #!/usr/bin/env python |
---|
| 2 | # ------------------------------------------------------------------------------------------------- |
---|
| 3 | # Macroprocessor vith PYthon script inclusion |
---|
| 4 | # |
---|
| 5 | # Written by Franck Wajsburt at LIP6 2009 |
---|
| 6 | # |
---|
| 7 | # This program is free software; you can redistribute it and/or |
---|
| 8 | # modify it under the terms of the GNU General Public License as |
---|
| 9 | # published by the Free Software Foundation; either version 2 of the |
---|
| 10 | # License, or (at your option) any later version. |
---|
| 11 | # |
---|
| 12 | # This program is distributed in the hope that it will be useful, but |
---|
| 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
| 15 | # General Public License for more details. |
---|
| 16 | # |
---|
| 17 | # You should have received a copy of the GNU General Public License |
---|
| 18 | # along with this program; if not, write to the Free Software |
---|
| 19 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
| 20 | # ------------------------------------------------------------------------------------------------- |
---|
| 21 | # requires doctutils package to run rst2html |
---|
| 22 | # |
---|
| 23 | # TODO exectution step by step |
---|
| 24 | # TODO ecrire un manuel |
---|
| 25 | # TODO faire des tests unitaires |
---|
| 26 | # ------------------------------------------------------------------------------------------------- |
---|
| 27 | _date = '2009-12-30 16:00' |
---|
| 28 | _version = '1.07' |
---|
| 29 | _authors = 'Franck Wajsburt' |
---|
| 30 | _organization = '(UPMC/LIP6/SOC)' |
---|
| 31 | __doc__ = '''\ |
---|
| 32 | =========================================================================== |
---|
| 33 | Macroprocessor vith PYthon script inclusion |
---|
| 34 | - Authors: '''+_authors+''' |
---|
| 35 | - Date: '''+_date+''' |
---|
| 36 | - Version: '''+_version+''' |
---|
| 37 | - Organisation: '''+_organization+''' |
---|
| 38 | ===========================================================================''' |
---|
| 39 | |
---|
| 40 | import os, sys, pdb |
---|
| 41 | from optparse import OptionParser |
---|
| 42 | from datetime import datetime |
---|
| 43 | |
---|
| 44 | # ------------------------------------------------------------------------------------------------- |
---|
| 45 | # os and log utilities |
---|
| 46 | # ------------------------------------------------------------------------------------------------- |
---|
| 47 | |
---|
| 48 | def _mpyhash(s): |
---|
| 49 | return "%08x" % (hash(s) & 0xffffffff) |
---|
| 50 | |
---|
| 51 | def _exit(error): |
---|
| 52 | if (error <> ''): |
---|
| 53 | print >> sys.stderr, "\n*** mpy:", error |
---|
| 54 | print >> sys.stderr, "*** preprocessing aborted\n" |
---|
| 55 | exit(1) |
---|
| 56 | |
---|
| 57 | def _mpyfindfile(fname, mpyidir): |
---|
| 58 | "try to find fname in any directory (or subdir) of mpyidir list" |
---|
| 59 | "if fname is 'stdin' then just returns 'stdin' else returns real filename" |
---|
| 60 | "if fname does not exist then returns ''" |
---|
| 61 | if fname == 'stdin': |
---|
| 62 | return fname |
---|
| 63 | else: |
---|
| 64 | for path in mpyidir: |
---|
| 65 | for root, dirs, files in os.walk(path): |
---|
| 66 | for f in files: |
---|
| 67 | if f == fname: # fname found |
---|
| 68 | return os.path.join(root,f) |
---|
| 69 | return '' |
---|
| 70 | |
---|
| 71 | def _mpyopen(fname = '', mpyidir = [], realfname = ''): |
---|
| 72 | "two behaviors:" |
---|
| 73 | " 1. try to open realfname but if realfname is '' then 2." |
---|
| 74 | " 2. try to open fname in any directory OR SUBDIR of mpyidir list1" |
---|
| 75 | "returns tuple (string_with_file_content, real_file_name)" |
---|
| 76 | "if fname is 'stdin' then open sys.stdin file" |
---|
| 77 | if realfname == '': |
---|
| 78 | realfname = _mpyfindfile(fname,mpyidir) |
---|
| 79 | if realfname == '': |
---|
| 80 | _exit("unable to find file %s" % fname) |
---|
| 81 | if realfname == 'stdin': |
---|
| 82 | return sys.stdin, fname |
---|
| 83 | else: |
---|
| 84 | try: mpyin = open(realfname,'r') |
---|
| 85 | except IOError, e: _exit(e) # but cannot be open |
---|
| 86 | return mpyin, realfname |
---|
| 87 | |
---|
| 88 | def _mpytree(mess): |
---|
| 89 | print >> mpyglobals['mpytree'], mess |
---|
| 90 | mpyglobals['mpytree'].flush() |
---|
| 91 | |
---|
| 92 | def _mpylog(mess): |
---|
| 93 | global mpyglobals |
---|
| 94 | print >> mpyglobals['mpylog'], mess |
---|
| 95 | mpyglobals['mpylog'].flush() |
---|
| 96 | if mpyglobals['mpyverbose']: |
---|
| 97 | print >> sys.stderr, mess |
---|
| 98 | |
---|
| 99 | def _dictlog(dic, exclude=[]): |
---|
| 100 | for key,val in dic.items(): |
---|
| 101 | for exc in exclude: |
---|
| 102 | if key[0:len(exc)] == exc: |
---|
| 103 | break |
---|
| 104 | else: |
---|
| 105 | _mpylog(' :%s: %s' % (key, str(val))) |
---|
| 106 | |
---|
| 107 | # ------------------------------------------------------------------------------------------------- |
---|
| 108 | # macro expander |
---|
| 109 | # ------------------------------------------------------------------------------------------------- |
---|
| 110 | |
---|
| 111 | def _mpy( mpyins = [] # ['infile1', ...] |
---|
| 112 | , mpytxt = '' # 'python code' |
---|
| 113 | , mpyout = '' # 'outfile' |
---|
| 114 | , mpydict = {} ): # global dictionary |
---|
| 115 | |
---|
| 116 | # to allow _mpy call in inclusion |
---|
| 117 | exec 'from mpy import mpyglobals, mpygen, mpyexp' in mpydict |
---|
| 118 | |
---|
| 119 | # get arguments from the global dictionary |
---|
| 120 | global mpyglobals |
---|
| 121 | mpylog = mpyglobals['mpylog'] # log file |
---|
| 122 | mpydebug = mpyglobals['mpydebug'] # True|False |
---|
| 123 | mpyverbose = mpyglobals['mpyverbose'] # True|False |
---|
| 124 | mpywdir = mpyglobals['mpywdir'] # working directory |
---|
| 125 | mpyidir = mpyglobals['mpyidir'] # list of input directory |
---|
| 126 | mpyoutlist = mpyglobals['mpyoutlist'] # list of opened output |
---|
| 127 | mpytabwidth= mpyglobals['mpytabwidth']# number of char of a tabulation character |
---|
| 128 | |
---|
| 129 | # this is necessary in order to write in mpyout file with just print |
---|
| 130 | if mpyout not in ('', 'stdout'): |
---|
| 131 | stdout = sys.stdout |
---|
| 132 | try: |
---|
| 133 | sys.stdout = open( mpywdir+'/'+mpyout, "w") |
---|
| 134 | mpyoutlist.append(mpywdir+'/'+mpyout) |
---|
| 135 | except IOError, e: _exit(e) |
---|
| 136 | |
---|
| 137 | opened_mpyin = [] # list of opened mpyin (include) |
---|
| 138 | |
---|
| 139 | # default values, a way to define the variable type |
---|
| 140 | mpyin = sys.stdin # mpyin file |
---|
| 141 | mpyfname = '' # real filename of mpyin file |
---|
| 142 | mpylineno = 1 # line number in mpyin file |
---|
| 143 | mpycharno = 0 # character number in mpyin file |
---|
| 144 | mpylength = 0 # number of character of mpyin file |
---|
| 145 | level = 0; # level > 0 in python inclusion |
---|
| 146 | mode = '' # '' outside python section, 'eval' | 'code' inside |
---|
| 147 | buf = '' # buffer for python section |
---|
| 148 | |
---|
| 149 | # the first item in mpyins is a buffer to exec |
---|
| 150 | mpyins = [mpytxt] + mpyins |
---|
| 151 | |
---|
| 152 | # for all files in mpyins list (first name is a buffer) { |
---|
| 153 | nbloop = 0 |
---|
| 154 | for fname in mpyins: |
---|
| 155 | |
---|
| 156 | if nbloop == 0: |
---|
| 157 | # the fist item of mpyins is a buffer |
---|
| 158 | mpyin, mpyfname = None, 'buffer' |
---|
| 159 | mpybuf = fname |
---|
| 160 | if mpybuf != '': |
---|
| 161 | lbuf = len(mpybuf) |
---|
| 162 | if lbuf > 31: lbuf = 31 |
---|
| 163 | if mpydebug == True: |
---|
| 164 | _mpylog("\n**Expand to file** %s **from text** `%s...`" |
---|
| 165 | % (mpyoutlist[-1], mpybuf[0:lbuf])) |
---|
| 166 | if mpydebug == True: |
---|
| 167 | _dictlog(mpydict, exclude=['_','mpy']) |
---|
| 168 | else: |
---|
| 169 | # try to open fnam then initialize all associated counters |
---|
| 170 | mpyin, mpyfname = _mpyopen(fname,mpyidir) |
---|
| 171 | mpybuf = mpyin.read(-1) # all chars of mpyin file |
---|
| 172 | if __name__ == '__main__': |
---|
| 173 | _mpylog('\nLog\n'+'-'*40) |
---|
| 174 | |
---|
| 175 | _mpylog("\n**Generate to file** %s **from file** %s" |
---|
| 176 | % (mpyoutlist[-1], mpyfname)) |
---|
| 177 | if nbloop == 1 and mpytxt == '': |
---|
| 178 | _dictlog(mpydict, exclude=['_','mpy']) |
---|
| 179 | |
---|
| 180 | mpylineno = 1 # line number in mpyin file |
---|
| 181 | mpycharno = 0 # character number in mpyin file |
---|
| 182 | mpylinecharno = 0 # character number in current line |
---|
| 183 | startlineno = 0 # first ligne of python inclusion |
---|
| 184 | mpylength = len(mpybuf) # number of character of mpyin file |
---|
| 185 | level = 0; # level > 0 in python inclusion |
---|
| 186 | mode = '' # '' because outside python section at first |
---|
| 187 | buf = '' # buffer for python section |
---|
| 188 | instr = 0 # in string boolean (0 outside, 1 inside) |
---|
| 189 | erasespace = 0 # nb space to erase for current line |
---|
| 190 | nbspacetab = 0 # nb space to erase for current expands |
---|
| 191 | |
---|
| 192 | # fname may include files, when a file ends, it is maybe an |
---|
| 193 | # include file and then we must continue to process. |
---|
| 194 | # This while exits with a break statement |
---|
| 195 | # while the hierarchical file continues { |
---|
| 196 | while True: |
---|
| 197 | |
---|
| 198 | # foreach char in current mpybuf { |
---|
| 199 | while mpycharno < mpylength: |
---|
| 200 | |
---|
| 201 | # get the current char |
---|
| 202 | c = mpybuf[mpycharno] |
---|
| 203 | mpycharno += 1 |
---|
| 204 | |
---|
| 205 | # in order to get line number of error |
---|
| 206 | if c == '\n': |
---|
| 207 | mpylinecharno = 0 |
---|
| 208 | mpylineno += 1 |
---|
| 209 | else: |
---|
| 210 | mpylinecharno += 1 |
---|
| 211 | |
---|
| 212 | # debug mode merges python section with result file |
---|
| 213 | if mpydebug == True : |
---|
| 214 | sys.stdout.write(c) |
---|
| 215 | |
---|
| 216 | # outside python section |
---|
| 217 | if level == 0: |
---|
| 218 | startlineno = mpylineno |
---|
| 219 | if c == '[': |
---|
| 220 | level += 1 |
---|
| 221 | mode = 'eval' |
---|
| 222 | elif c == '{': |
---|
| 223 | level += 1 |
---|
| 224 | mode = 'code' |
---|
| 225 | else: |
---|
| 226 | if mpydebug == False: # in debug mode c is already written |
---|
| 227 | sys.stdout.write(c) |
---|
| 228 | |
---|
| 229 | # inside python section |
---|
| 230 | else: |
---|
| 231 | |
---|
| 232 | # tabulation of expansion |
---|
| 233 | if erasespace != 0: |
---|
| 234 | if c == ' ' : |
---|
| 235 | erasespace -= 1 |
---|
| 236 | continue |
---|
| 237 | if c == '\t' : |
---|
| 238 | erasespace -= mpytabwidth |
---|
| 239 | continue |
---|
| 240 | else: |
---|
| 241 | if c == '\n': |
---|
| 242 | erasespace = nbspacetab |
---|
| 243 | buf += c |
---|
| 244 | continue |
---|
| 245 | else: |
---|
| 246 | _exit ( "%s[%d]: %d spaces expected not %c" |
---|
| 247 | % (mpyfname, mpylineno, nbspacetab, c)) |
---|
| 248 | |
---|
| 249 | # we are inside a string is it a newline ? |
---|
| 250 | if instr == 1 and c == '\n': |
---|
| 251 | erasespace = nbspacetab |
---|
| 252 | |
---|
| 253 | # is it a string delimitor ? |
---|
| 254 | if buf[-2:]+c == "'''" : |
---|
| 255 | instr = 1 - instr |
---|
| 256 | if instr == 1: |
---|
| 257 | nbspacetab = mpylinecharno-3 |
---|
| 258 | |
---|
| 259 | # count [ and { |
---|
| 260 | if c == '[' : |
---|
| 261 | if mode == 'eval': |
---|
| 262 | level += 1 |
---|
| 263 | buf += c |
---|
| 264 | elif c == '{': |
---|
| 265 | if mode == 'code': |
---|
| 266 | level += 1 |
---|
| 267 | buf += c |
---|
| 268 | |
---|
| 269 | # test for evaluation |
---|
| 270 | elif c == ']': |
---|
| 271 | if level == 0: |
---|
| 272 | if startlineno == mpylineno: |
---|
| 273 | _exit ( "%s[%d]: unexpected ']'" % (mpyfname, mpylineno)) |
---|
| 274 | else: |
---|
| 275 | _exit ( "%s[%d-%d]: unexpected ']'" % (mpyfname, startlineno, mpylineno)) |
---|
| 276 | elif mode == 'code': |
---|
| 277 | buf += c |
---|
| 278 | else: # mode eval |
---|
| 279 | level -= 1 |
---|
| 280 | if level != 0: |
---|
| 281 | buf += c |
---|
| 282 | else: |
---|
| 283 | # test if buf is a file name, if yes includes file |
---|
| 284 | # therefore pushes the current file and opens the new |
---|
| 285 | incname = _mpyfindfile(buf,mpyidir) |
---|
| 286 | if incname != '': |
---|
| 287 | if mpydebug == True: |
---|
| 288 | _mpylog("\nInclude to %s from %s" % (mpyout, incname)) |
---|
| 289 | |
---|
| 290 | # push known parameters of the current opened file |
---|
| 291 | opened_mpyin.append((mpyin, mpybuf, mpyfname, |
---|
| 292 | mpylineno, mpycharno, mpylength)) |
---|
| 293 | |
---|
| 294 | # old values required for test of recursivity just below |
---|
| 295 | oldmpyfname = mpyfname |
---|
| 296 | oldmpylineno = mpylineno |
---|
| 297 | |
---|
| 298 | # open the include file |
---|
| 299 | mpyin, mpyfname = _mpyopen(realfname = incname) |
---|
| 300 | mpybuf = mpyin.read(-1) |
---|
| 301 | mpylineno = 1 |
---|
| 302 | mpycharno = 0 |
---|
| 303 | mpylength = len(mpybuf) |
---|
| 304 | level = 0 |
---|
| 305 | buf = mode = '' |
---|
| 306 | |
---|
| 307 | # test recursive include |
---|
| 308 | for f in opened_mpyin[:-1]: |
---|
| 309 | if mpyfname in f: |
---|
| 310 | _exit ("%s[%d]: forbidden recursive inclusion on %s" |
---|
| 311 | % (oldmpyfname, oldmpylineno, mpyfname)) |
---|
| 312 | |
---|
| 313 | # just evaluate buf |
---|
| 314 | else: |
---|
| 315 | try: print eval(buf, mpydict), |
---|
| 316 | except Exception, e: |
---|
| 317 | if startlineno == mpylineno: |
---|
| 318 | _exit ( "%s[%d]: %s" % (mpyfname, mpylineno, e)) |
---|
| 319 | else: |
---|
| 320 | _exit ( "%s[%d-%d]: %s" % (mpyfname, startlineno, mpylineno, e)) |
---|
| 321 | buf = mode = '' |
---|
| 322 | |
---|
| 323 | # test for execute |
---|
| 324 | elif c == '}': |
---|
| 325 | |
---|
| 326 | if level == 0: |
---|
| 327 | if startlineno == mpylineno: |
---|
| 328 | _exit ( "%s[%d]: unexpected '}'" % (mpyfname, mpylineno)) |
---|
| 329 | else: |
---|
| 330 | _exit ( "%s[%d-%d]: unexpected '}'" % (mpyfname, startlineno, mpylineno)) |
---|
| 331 | elif mode == 'eval': |
---|
| 332 | buf += c |
---|
| 333 | else: # mode code |
---|
| 334 | level -= 1 |
---|
| 335 | if level != 0: |
---|
| 336 | buf += c |
---|
| 337 | else: |
---|
| 338 | try: |
---|
| 339 | mpydict |
---|
| 340 | # print >> sys.stderr, buf |
---|
| 341 | exec(buf, mpydict) |
---|
| 342 | # pdb.run(buf, mpydict) |
---|
| 343 | except Exception, e: |
---|
| 344 | if startlineno == mpylineno: |
---|
| 345 | _exit ( "%s[%d]: %s" |
---|
| 346 | % (mpyfname, mpylineno, e)) |
---|
| 347 | else: |
---|
| 348 | _exit ( "%s[%d-%d]: %s" |
---|
| 349 | % (mpyfname, startlineno, mpylineno, e)) |
---|
| 350 | buf = mode = '' |
---|
| 351 | else: |
---|
| 352 | buf += c |
---|
| 353 | |
---|
| 354 | # } end while mpycharno < mpylength: |
---|
| 355 | |
---|
| 356 | if mpyfname not in ['stdin', 'buffer']: |
---|
| 357 | mpyin.close() |
---|
| 358 | |
---|
| 359 | if level <> 0: |
---|
| 360 | if mode == 'eval': |
---|
| 361 | _exit ("%s[%d]: expected ']'" % (mpyfname,mpylineno)) |
---|
| 362 | else: |
---|
| 363 | _exit ("%s[%d]: expected '}'" % (mpyfname,mpylineno)) |
---|
| 364 | |
---|
| 365 | # pops included file if there is one, else breaks while |
---|
| 366 | try: |
---|
| 367 | mpyin, mpybuf, mpyfname, mpylineno, mpycharno, mpylength = opened_mpyin.pop() |
---|
| 368 | level = 0 |
---|
| 369 | buf = mode = '' |
---|
| 370 | |
---|
| 371 | except: break |
---|
| 372 | |
---|
| 373 | # } end while True: |
---|
| 374 | |
---|
| 375 | # because the first fname is actually a buffer |
---|
| 376 | nbloop += 1 |
---|
| 377 | |
---|
| 378 | # } end for fname in mpyins: |
---|
| 379 | |
---|
| 380 | # close and redirect sys.stdout |
---|
| 381 | if mpyout not in ('', 'stdout'): |
---|
| 382 | sys.stdout.close() |
---|
| 383 | sys.stdout = stdout |
---|
| 384 | mpyoutlist.pop() |
---|
| 385 | |
---|
| 386 | # ------------------------------------------------------------------------------------------------- |
---|
| 387 | |
---|
| 388 | def mpygen(mpyin, param): |
---|
| 389 | "call the macro processor on file mpyin with its own dictionaty, produce a newfile" |
---|
| 390 | global mpyglobals |
---|
| 391 | |
---|
| 392 | # check parameters |
---|
| 393 | if type(mpyin) <> str: |
---|
| 394 | _exit('first argument of mpygen: %s is not a valid filename' % str(mpyin)) |
---|
| 395 | if type(param) <> dict: |
---|
| 396 | _exit('second argument of mpygen: %s is not a valid dictionary' % str(param)) |
---|
| 397 | |
---|
| 398 | # test input filename syntax |
---|
| 399 | mpyout = os.path.basename(mpyin).split('.') |
---|
| 400 | if mpyout[-2] <> 'mpy': |
---|
| 401 | _exit('filename %s has not a valid form (anyroot.mpy.anyext)' % str(mpyin)) |
---|
| 402 | |
---|
| 403 | # generate output filename |
---|
| 404 | hashnumber = _mpyhash(`param`) |
---|
| 405 | mpyout_base = '.'.join(mpyout[0:-2]) |
---|
| 406 | mpyout = mpyout_base+'_'+hashnumber+'.'+mpyout[-1] |
---|
| 407 | mpymodelname = mpyout_base+'_'+hashnumber |
---|
| 408 | param['mpymodelname'] = mpymodelname |
---|
| 409 | |
---|
| 410 | # call the macro processor |
---|
| 411 | _mpytree('%s* %s <- %s\n' % (' '*mpyglobals['mpylevelgen'], mpyout, mpyin)) |
---|
| 412 | mpyglobals['mpylevelgen'] += 1 |
---|
| 413 | _mpy(mpyins = [mpyin], mpydict = param, mpyout = mpyout) |
---|
| 414 | mpyglobals['mpylevelgen'] -= 1 |
---|
| 415 | _mpytree('') |
---|
| 416 | |
---|
| 417 | # return the computed model name |
---|
| 418 | return mpymodelname |
---|
| 419 | |
---|
| 420 | # ------------------------------------------------------------------------------------------------- |
---|
| 421 | |
---|
| 422 | def mpyexp(txt, param): |
---|
| 423 | "call the macro processor on a buffer of chars with its own dictionary" |
---|
| 424 | if type(txt) <> str: |
---|
| 425 | _exit('argument of mpyexp: must be a string not %s' % type(txt)) |
---|
| 426 | _mpy(mpytxt = txt, mpydict = param) |
---|
| 427 | |
---|
| 428 | # ------------------------------------------------------------------------------------------------- |
---|
| 429 | # define globals dictionnary |
---|
| 430 | # ------------------------------------------------------------------------------------------------- |
---|
| 431 | |
---|
| 432 | _parser = OptionParser( |
---|
| 433 | usage = "%prog [options] [infiles...]", |
---|
| 434 | version = "version "+_version, |
---|
| 435 | description = "mpy opens all infiles list (default stdin) to macro-process " |
---|
| 436 | "them and writes the result in OFILE (default stdout). " |
---|
| 437 | "Infiles are searched in any dir or subdir of PATHS (default " |
---|
| 438 | "MPYIDIR environment variable)") |
---|
| 439 | |
---|
| 440 | _parser.set_defaults( verbose = False , debug = False , txt = '', tab = 8 |
---|
| 441 | , wdir = '.' , idir = '' , output = 'stdout') |
---|
| 442 | |
---|
| 443 | _parser.add_option("-v", "--verbose", action = "store_true", dest = "verbose" |
---|
| 444 | , help = "trace processing step") |
---|
| 445 | _parser.add_option("-d", "--debug", action = "store_true", dest = "debug" |
---|
| 446 | , help = "do not remove python inclusions") |
---|
| 447 | _parser.add_option("-t", "--txt", dest = "txt" |
---|
| 448 | , help = "text (chars) to macro process") |
---|
| 449 | _parser.add_option("-b", "--tab", dest = "tab" |
---|
| 450 | , help = "tabulation width [default: %default]") |
---|
| 451 | _parser.add_option("-w", "--wdir", dest = "wdir" |
---|
| 452 | , help = "define the working directory [default: %default]") |
---|
| 453 | _parser.add_option("-o", "--output", dest = "ofile", default = 'stdout' |
---|
| 454 | , help = "define output filename [default: %default] ") |
---|
| 455 | _parser.add_option("-i", "--idir", dest = "idir" |
---|
| 456 | , help = "list of directories (separated with colon ':') " |
---|
| 457 | "where to find input files " |
---|
| 458 | "(default %prog use MPYPATH environment variable) " |
---|
| 459 | "%prog begins to search in the working directory (-w option) " |
---|
| 460 | "then in all the directories or subdirectories of the path") |
---|
| 461 | |
---|
| 462 | (_options, _mpyins) = _parser.parse_args() |
---|
| 463 | |
---|
| 464 | # if no path dirctories are given in command line, getenv MPYIDIR |
---|
| 465 | if _options.idir == '': |
---|
| 466 | try: _options.idir = os.environ['MPYPATH'] |
---|
| 467 | except: pass |
---|
| 468 | |
---|
| 469 | # gets the input files |
---|
| 470 | if len(_mpyins) == 0: |
---|
| 471 | _mpyins = ['stdin'] |
---|
| 472 | |
---|
| 473 | # open log file |
---|
| 474 | if not os.path.isdir(_options.wdir): |
---|
| 475 | _exit('%s is not a working directory' % _options.wdir) |
---|
| 476 | try: |
---|
| 477 | _mpymetaname = os.path.join(_options.wdir,"mpy_meta.log") |
---|
| 478 | _mpytreename = os.path.join(_options.wdir,"mpy_tree.log") |
---|
| 479 | _mpymetafile = open(_mpymetaname,"a") |
---|
| 480 | _mpytreefile = open(_mpytreename,"a") |
---|
| 481 | _logname = os.path.join(_options.wdir,"mpy.log") |
---|
| 482 | _htmlname = os.path.join(_options.wdir,"mpy.html") |
---|
| 483 | except IOError, e: |
---|
| 484 | _exit(e) |
---|
| 485 | |
---|
| 486 | mpyglobals = dict( mpyverbose = _options.verbose # True|False |
---|
| 487 | , mpydebug = _options.debug # True|False |
---|
| 488 | , mpywdir = _options.wdir # working directory |
---|
| 489 | , mpyidir = [_options.wdir]+_options.idir.split(':') # split pathes in a list |
---|
| 490 | , mpylevelgen = 1 # level of generation (tree deep) |
---|
| 491 | , mpylog = _mpymetafile |
---|
| 492 | , mpytree = _mpytreefile |
---|
| 493 | , mpytabwidth = _options.tab |
---|
| 494 | , mpyoutlist = [_options.ofile]) |
---|
| 495 | |
---|
| 496 | # ------------------------------------------------------------------------------------------------- |
---|
| 497 | # main function |
---|
| 498 | # ------------------------------------------------------------------------------------------------- |
---|
| 499 | |
---|
| 500 | if __name__ == '__main__': |
---|
| 501 | _mpytree(''' |
---|
| 502 | ======================================================================== |
---|
| 503 | MPY: Macroprocessor with PYthon script inclusion (V'''+_version+''') |
---|
| 504 | ======================================================================== |
---|
| 505 | Generation date '''+datetime.now().strftime("%A, %d. %B %Y %I:%M%p")+''' |
---|
| 506 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 507 | ''') |
---|
| 508 | _mpytree( '\nTree Generation\n'+'-'*40+'\n\n') |
---|
| 509 | _mpytree( '* %s <- %s\n' % (_options.ofile, _mpyins[0])) |
---|
| 510 | _mpy(mpytxt = _options.txt, mpyout = _options.ofile, mpyins = _mpyins, mpydict = {}) |
---|
| 511 | try: |
---|
| 512 | os.system('cat '+_mpytreename+' '+_mpymetaname+' > '+_logname) |
---|
| 513 | os.system('rst2html '+_logname+' '+_htmlname) |
---|
| 514 | os.remove(_mpytreename) |
---|
| 515 | os.remove(_mpymetaname) |
---|
| 516 | except: |
---|
| 517 | pass |
---|