llvm.org GIT mirror llvm / a2e9363
New class, useful for command-line interactive programs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10662 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 16 years ago
3 changed file(s) with 206 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===- SlowOperationInformer.h - Keep the user informed ---------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by the LLVM research group and is distributed under
5 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines a simple object which can be used to let the user know what
10 // is going on when a slow operation is happening,l and gives them the ability
11 // to cancel it. Potentially slow operations can stack allocate one of these
12 // objects, and periodically call the "progress" method to update the progress
13 // bar. If the operation takes more than 3 seconds to complete, the progress
14 // bar is automatically shown and updated every second. As such, the slow
15 // operation should not print stuff to the screen, and should not be confused if
16 // an extra line appears on the screen (ie, the cursor should be at the start of
17 // the line).
18 //
19 // If the user presses CTRL-C during the operation, the next invocation of the
20 // progress method with throw an std::string object indicating that the
21 // operation was cancelled. As such, client code must be exception safe around
22 // the progress method.
23 //
24 // Because SlowOperationInformers fiddle around with signals, they cannot be
25 // nested. The SIGINT signal handler is restored after the
26 // SlowOperationInformer is destroyed, but the SIGALRM handlers is set back to
27 // the default.
28 //
29 //===----------------------------------------------------------------------===//
30
31 #ifndef SUPPORT_SLOW_OPERATION_INFORMER_H
32 #define SUPPORT_SLOW_OPERATION_INFORMER_H
33
34 #include
35
36 namespace llvm {
37 class SlowOperationInformer {
38 std::string OperationName;
39 unsigned LastPrintAmount;
40
41 SlowOperationInformer(const SlowOperationInformer&); // DO NOT IMPLEMENT
42 void operator=(const SlowOperationInformer&); // DO NOT IMPLEMENT
43 public:
44 SlowOperationInformer(const std::string &Name);
45 ~SlowOperationInformer();
46
47 /// progress - Clients should periodically call this method when they are in
48 /// an exception-safe state. The Amount variable should indicate how far
49 /// along the operation is, given in 1/10ths of a percent (in other words,
50 /// Amount should range from 0 to 1000).
51 void progress(unsigned Amount);
52 };
53 } // end namespace llvm
54
55 #endif /* SLOW_OPERATION_INFORMER_H */
0 //===- SlowOperationInformer.h - Keep the user informed ---------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by the LLVM research group and is distributed under
5 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines a simple object which can be used to let the user know what
10 // is going on when a slow operation is happening,l and gives them the ability
11 // to cancel it. Potentially slow operations can stack allocate one of these
12 // objects, and periodically call the "progress" method to update the progress
13 // bar. If the operation takes more than 3 seconds to complete, the progress
14 // bar is automatically shown and updated every second. As such, the slow
15 // operation should not print stuff to the screen, and should not be confused if
16 // an extra line appears on the screen (ie, the cursor should be at the start of
17 // the line).
18 //
19 // If the user presses CTRL-C during the operation, the next invocation of the
20 // progress method with throw an std::string object indicating that the
21 // operation was cancelled. As such, client code must be exception safe around
22 // the progress method.
23 //
24 // Because SlowOperationInformers fiddle around with signals, they cannot be
25 // nested. The SIGINT signal handler is restored after the
26 // SlowOperationInformer is destroyed, but the SIGALRM handlers is set back to
27 // the default.
28 //
29 //===----------------------------------------------------------------------===//
30
31 #ifndef SUPPORT_SLOW_OPERATION_INFORMER_H
32 #define SUPPORT_SLOW_OPERATION_INFORMER_H
33
34 #include
35
36 namespace llvm {
37 class SlowOperationInformer {
38 std::string OperationName;
39 unsigned LastPrintAmount;
40
41 SlowOperationInformer(const SlowOperationInformer&); // DO NOT IMPLEMENT
42 void operator=(const SlowOperationInformer&); // DO NOT IMPLEMENT
43 public:
44 SlowOperationInformer(const std::string &Name);
45 ~SlowOperationInformer();
46
47 /// progress - Clients should periodically call this method when they are in
48 /// an exception-safe state. The Amount variable should indicate how far
49 /// along the operation is, given in 1/10ths of a percent (in other words,
50 /// Amount should range from 0 to 1000).
51 void progress(unsigned Amount);
52 };
53 } // end namespace llvm
54
55 #endif /* SLOW_OPERATION_INFORMER_H */
0 //===-- SlowOperationInformer.cpp - Keep the user informed ----------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by the LLVM research group and is distributed under
5 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the SlowOperationInformer class for the LLVM debugger.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "Support/SlowOperationInformer.h"
14 #include "Config/config.h" // Get the signal handler return type
15 #include
16 #include
17 #include
18 #include
19 using namespace llvm;
20
21 /// OperationCancelled - This flag is set by the SIGINT signal handler if the
22 /// user presses CTRL-C.
23 static volatile bool OperationCancelled;
24
25 /// ShouldShowStatus - This flag gets set if the operation takes a long time.
26 ///
27 static volatile bool ShouldShowStatus;
28
29 /// NestedSOI - Sanity check. SlowOperationInformers cannot be nested or run in
30 /// parallel. This ensures that they never do.
31 static bool NestedSOI = false;
32
33 static RETSIGTYPE SigIntHandler(int Sig) {
34 OperationCancelled = true;
35 signal(SIGINT, SigIntHandler);
36 }
37
38 static RETSIGTYPE SigAlarmHandler(int Sig) {
39 ShouldShowStatus = true;
40 }
41
42 static sighandler_t OldSigIntHandler;
43
44
45 SlowOperationInformer::SlowOperationInformer(const std::string &Name)
46 : OperationName(Name), LastPrintAmount(0) {
47 assert(!NestedSOI && "SlowerOperationInformer objects cannot be nested!");
48 NestedSOI = true;
49
50 OperationCancelled = 0;
51 ShouldShowStatus = 0;
52
53 signal(SIGALRM, SigAlarmHandler);
54 OldSigIntHandler = signal(SIGINT, SigIntHandler);
55 alarm(1);
56 }
57
58 SlowOperationInformer::~SlowOperationInformer() {
59 NestedSOI = false;
60 if (LastPrintAmount)
61 std::cout << "\n";
62
63 alarm(0);
64 signal(SIGALRM, SIG_DFL);
65 signal(SIGINT, OldSigIntHandler);
66 }
67
68 /// progress - Clients should periodically call this method when they are in
69 /// an exception-safe state. The Amount variable should indicate how far
70 /// along the operation is, given in 1/10ths of a percent (in other words,
71 /// Amount should range from 0 to 1000).
72 void SlowOperationInformer::progress(unsigned Amount) {
73 if (OperationCancelled) {
74 std::cout << "\n";
75 LastPrintAmount = 0;
76 throw "While " + OperationName + ", operation cancelled.";
77 }
78
79 // If we haven't spent enough time in this operation to warrant displaying the
80 // progress bar, don't do so yet.
81 if (!ShouldShowStatus)
82 return;
83
84 // Delete whatever we printed last time.
85 std::string ToPrint = std::string(LastPrintAmount, '\b');
86
87 std::ostringstream OS;
88 OS << "Progress " << OperationName << ": " << Amount/10 << "." << Amount % 10
89 << "%";
90
91 LastPrintAmount = OS.str().size();
92 std::cout << ToPrint+OS.str() << std::flush;
93 }