Home | History | Annotate | Download | only in tools
      1 #!/usr/bin/env python2.7
      2 
      3 # Copyright 2014, ARM Limited
      4 # All rights reserved.
      5 #
      6 # Redistribution and use in source and binary forms, with or without
      7 # modification, are permitted provided that the following conditions are met:
      8 #
      9 #   * Redistributions of source code must retain the above copyright notice,
     10 #     this list of conditions and the following disclaimer.
     11 #   * Redistributions in binary form must reproduce the above copyright notice,
     12 #     this list of conditions and the following disclaimer in the documentation
     13 #     and/or other materials provided with the distribution.
     14 #   * Neither the name of ARM Limited nor the names of its contributors may be
     15 #     used to endorse or promote products derived from this software without
     16 #     specific prior written permission.
     17 #
     18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
     19 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     21 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
     22 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     23 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     24 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     25 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     26 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 
     29 
     30 import sys
     31 import time
     32 import multiprocessing
     33 
     34 
     35 __need_newline__ = multiprocessing.Value('i', 0)
     36 __last_overwritable_line_length__ = multiprocessing.Value('i', 0)
     37 __print_lock__ = multiprocessing.Lock()
     38 
     39 
     40 # If the last printed character was not a newline, print one.
     41 def EnsureNewLine():
     42   global __need_newline__
     43 
     44   if __need_newline__.value:
     45     __need_newline__.value = 0
     46     sys.stdout.write('\n')
     47 
     48 
     49 # Like print, but insert a newline if necessary to avoid corrupting the status
     50 # display (provided by UpdateProgress).
     51 def Print(string):
     52   global __last_overwritable_line_length__
     53 
     54   EnsureNewLine()
     55   print string
     56   __last_overwritable_line_length__.value = 0
     57 
     58 
     59 def PrintOverwritableLine(string, verbose = False):
     60   global __need_newline__
     61   global __last_overwritable_line_length__
     62 
     63   with __print_lock__:
     64     if verbose:
     65       # In verbose mode we do not overwrite previous lines.
     66       EnsureNewLine()
     67     else:
     68       # Otherwise, overwrite the previous line.
     69       sys.stdout.write('\r')
     70 
     71     sys.stdout.write(string)
     72 
     73     # Append spaces to hide the previous line.
     74     new_len = len(string)
     75     spaces = __last_overwritable_line_length__.value - new_len
     76     if spaces > 0:
     77       sys.stdout.write(' ' * spaces)
     78     __last_overwritable_line_length__.value = new_len
     79 
     80     # We haven't printed a newline, so any subsequent print output (with verbose
     81     # logs or error reports) will need to print one.
     82     __need_newline__.value = 1
     83 
     84 
     85 # Display the run progress:
     86 # [time| progress|+ passed|- failed]  Name
     87 def UpdateProgress(start_time, passed, failed, count, verbose, name,
     88                    prefix = ''):
     89   minutes, seconds = divmod(time.time() - start_time, 60)
     90   progress = float(passed + failed) / count * 100
     91   passed_colour = '\x1b[32m' if passed != 0 else ''
     92   failed_colour = '\x1b[31m' if failed != 0 else ''
     93   indicator = '[%02d:%02d| %3d%%|'
     94   indicator += passed_colour + '+ %d\x1b[0m|'
     95   indicator += failed_colour + '- %d\x1b[0m]'
     96 
     97   progress_string = prefix
     98   progress_string += indicator % (minutes, seconds, progress, passed, failed)
     99   progress_string += '  ' + name
    100 
    101   PrintOverwritableLine(progress_string, verbose)
    102