I want to make a little modification to the Android source to meet my requirement. Here is the requirement:
I want index all the objects in an Android app by adding one more public int field to the java.lang.Object class. Therefore, all the classes can inherit the newly added field because all of them are the subclasses of the Object class.
What I have done so far is modify the java.lang.Object class under <Android_source>/libcore/libart/src/main/java/java/lang folder and recompile the source.
I want to ask if I am doing the right thing. Can my Android app recognize this change (e.g. can a String object access the newly added field)?
Edit
After around 3 weeks try and error, I finally got the complete answer. I want to share this experience with others if anybody else want to modify the core java libraries of Android source (e.g., modifying Object.java and String.java etc.). Again, as mentioned by Michael, please note that such a modification may only be suitable for research or testing purpose.
The key challenge in making a successful modification (here 'successful' means the modified Android source can be built and run on emulators or real devices without any problem) is that some of the classes in the core java library have their C++ mirrors (located in <Android_source>/art/runtime/mirrors/). When modifying these java classes, you should also make the same modifications to their C++ mirrors. Otherwise, you could fail the build process because there are a bunch of checkings that you need to pass. Since I only add a new field to the Object.java, I will list some checkings (or requirements) I encountered below:
1.The size of an object instance = the size of its C++ mirror. For example, if I add a long field into Object.java, I should also add a uint64_t field to its C++ mirror to make their size equal.
2.Try to make the size of an object instance be the power of 2 (e.g., 2, 4, 8, 16, ...). For example, the size of the original Object.java is 8, therefore I add a long field to increase the size to 16. If I add an int field, the size becomes 12 and it can fail many checkings. I don't figure out the exact reason but I guess it has something to do with memory alignment.
3.Try to put primitive-type fields after non-primitive-type fields and primitive-type fields should be ordered by size. This means you should put reference-type fields in the front, followed by 8-byte-primitive-type fields, then 4-byte-primitive-type fields, then 2-byte-primitive-type fields, then 1-byte-primitive-type fields. Again, I guess the reason is memory alignment
That's all I done to meet my requirements. I am open to any discussions if you have any ideas about the purpose of these checkings (especially the 2ed and 3rd one)
New edit
More specifically, I did the following things:
Add a new field (e.g., public long tag;) in Object.java
Change static constexpr uint32_t kObjectHeaderSize = kUseBrooksReadBarrier ? 16 : 8; to static constexpr uint32_t kObjectHeaderSize = kUseBrooksReadBarrier ? 24 : 16; in Object.h
Add the following method in Object.h (Only on Android 7)
static MemberOffset TagOffset() {
return OFFSET_OF_OBJECT_MEMBER(Object, tag);
}
Add a new public field public: uint64_t tag; in Object.h
Change
#define MIRROR_OBJECT_CLASS_OFFSET 0
ADD_TEST_EQ(MIRROR_OBJECT_CLASS_OFFSET, art::mirror::Object::ClassOffset().Int32Value())
#define MIRROR_OBJECT_LOCK_WORD_OFFSET 4
ADD_TEST_EQ(MIRROR_OBJECT_LOCK_WORD_OFFSET, art::mirror::Object::MonitorOffset().Int32Value())
#if defined(USE_BROOKS_READ_BARRIER)
#define MIRROR_OBJECT_HEADER_SIZE 16
#else
#define MIRROR_OBJECT_HEADER_SIZE 8
to
#define MIRROR_OBJECT_CLASS_OFFSET 0
ADD_TEST_EQ(MIRROR_OBJECT_CLASS_OFFSET, art::mirror::Object::ClassOffset().Int32Value())
#define MIRROR_OBJECT_LOCK_WORD_OFFSET 4
ADD_TEST_EQ(MIRROR_OBJECT_LOCK_WORD_OFFSET, art::mirror::Object::MonitorOffset().Int32Value())
#define MIRROR_OBJECT_CLASS_TAG 8
ADD_TEST_EQ(MIRROR_OBJECT_CLASS_TAG, art::mirror::Object::TagOffset().Int32Value())
#if defined(USE_BROOKS_READ_BARRIER)
#define MIRROR_OBJECT_HEADER_SIZE 24
#else
#define MIRROR_OBJECT_HEADER_SIZE 16
in asm_support.h (Only on Android 7)
Add addOffset(OFFSETOF_MEMBER(mirror::Object, tag), "tag"); in class_linker_test.cc
Change
static_assert(kObjectHeaderSize == sizeof(mirror::HeapReference<mirror::Class>) +
sizeof(LockWord),
to
static_assert(kObjectHeaderSize == sizeof(mirror::HeapReference<mirror::Class>) +
sizeof(LockWord) + 8,
in art/runtime/gc/collector/concurrent_copying.cc
8 Change static constexpr size_t kFirstElementOffset = 12u; to static constexpr size_t kFirstElementOffset = 20u; in array.h
9 Change static constexpr size_t kObjectAlignmentShift = 3; to static constexpr size_t kObjectAlignmentShift = 4; in runtime_globals.h (Not done yet)
10 Change
static_assert(kObjectAlignment == 8, "Alignment check");
class PACKED(8) ImageHeader {
to
static_assert(kObjectAlignment == 16, "Alignment check");
class PACKED(16) ImageHeader {
in image.h (Not done yet)
11 Change static constexpr size_t kAlignment = 8; to static constexpr size_t kAlignment = 16; in gc::space::BumpPointerSpace (Not done yet)
12 Change #!/usr/bin/python to #!/usr/local/bin/python in device/generic/goldfish/tools/mk_combined_img.py (The value depends on your /bin/env python)(Only on Android 10)
13 Change
#define DCHECK_ALIGNED_PARAM(value, alignment) \
DCHECK(::art::IsAlignedParam(value, alignment)) << reinterpret_cast<const void*>(value)
to
#define DCHECK_ALIGNED_PARAM(value, alignment) \
DCHECK(::art::IsAlignedParam(value, alignment)) << reinterpret_cast<const void*>(value) << "," << alignment
in art/libartbase/base/bit_utils.h (for debug purpose)(Only for Android 11)
14 Change
DCHECK_ALIGNED_PARAM(remaining_space, object_class->GetObjectSize());
Object* end = dst + remaining_space / object_class->GetObjectSize();
to
DCHECK_ALIGNED_PARAM(remaining_space, kObjectAlignment);
Object* end = dst + remaining_space / kObjectAlignment;
in art/dex2oat/linker/image_writer.cc (Only for Android 11)
Change
memcpy(reinterpret_cast<uint8_t*>(to_ref) + kObjectHeaderSize,
reinterpret_cast<const uint8_t*>(from_ref) + kObjectHeaderSize,
obj_size - kObjectHeaderSize);
to
memcpy(reinterpret_cast<uint8_t*>(to_ref) + kObjectHeaderSize - 8,
reinterpret_cast<const uint8_t*>(from_ref) + kObjectHeaderSize - 8,
obj_size - kObjectHeaderSize + 8);
in concurrent_copying.cc (on Android 10)(reference)
Firstly, I'd like to state that I don't think this is a good idea and is probably overkill outside of research purposes. If you are modifying AOSP then the code you write will be dependent on the target device running that customised build of AOSP. However, it is still possible.
I'm assuming you already know how to compile and flash a custom AOSP build to a device. In order to write code that makes use of your new functionality, you'll also need to compile a custom SDK. This is so that Android Studio will know that your new method exists within Object, and can compile correctly against it. The full documentation can be found here, but essentially it boils down to:
. build/envsetup.sh
lunch sdk-eng
make sdk
When you have your SDK zip file, you'll need to unzip it to your SDK's platforms directory - it should now show up checked in your SDK manager. If you have given your SDK a custom platform ID then you should be able to use that in your build.gradle files.
Disclaimer: This advice is purely from memory, it's a lengthy process so I've not had time to double-check, and chances are there may be a couple of minor things I've missed. This should get you most of the way towards where you want to be though.
I am a beginner to Python, I need a help with manipulating csv files in Python.
I am trying to do sliding window mechanism for each row in dataset.
for an example if the dataset is this
timestamp | temperature | windspeed
965068200 9.61883 60.262
965069100 9.47203 60.1664
965070000 9.31125 60.0145
965070900 9.13649 59.8064
and if user specified window size is 3,the result should be something like
timestamp | temperature-2 | temperature-1 |temperature-0 | windspeed-2 | windspeed-1 | windspeed-0
965070000 9.61883 9.47203 9.31125 60.262 60.1664 60.0145
965070900 9.47203 9.31125 9.13649 60.1664 60.0145 59.8064
I could do this by using List of ObjectsArray in Java.Reading CSV and generate new CSV which it contains transformed dataset.
Here is the code
http://pastebin.com/cQnTBg8d #researh
I need to do this in Python , please help me to solve this.
Thank you
This answer assumes you are using Python 3.x - for Python 2.x some changes are required (some obvious places are commented)
For the data format in the question, this could be a starting point in Python:
import collections
def slide(infile,outfile,window_size):
queue=collections.deque(maxlen=window_size)
line=infile.readline()
headers=[s.strip() for s in line.split("|")]
row=[headers[0]]
for h in headers[1:]
for i in reversed(range(window_size)):
row.append("%s-%i"%(h,i))
outfile.write(" | ".join(row))
outfile.write("\n")
for line in infile:
queue.append(line.split())
if len(queue)==window_size:
row=[queue[-1][0]]
for j in range(1,len(headers)):
for old in queue:
row.append(old[j])
outfile.write("\t".join(row))
outfile.write("\n")
ws=3
with open("infile.csv","r") as inf:
with open("outfile.csv","w") as outf:
slide(inf,outf,ws)
actually this code is all about using a queue to keep the input rows for the window and not more - everything else is text-to-list-to-text.
With actual csv-data (see comment)
import csv
import collections
def slide(infile,outfile,window_size):
r=csv.reader(infile)
w=csv.writer(outfile)
queue=collections.deque(maxlen=window_size)
headers=next(r) # r.next() on python 2
l=[headers[0]]
for h in headers[1:]
for i in reversed(range(window_size)):
l.append("%s-%i"%(h,i))
w.writerow(l)
hrange=range(1,len(headers))
for row in r:
queue.append(row)
if len(queue)==window_size:
l=[queue[-1][0]]
for j in hrange:
for old in queue:
l.append(old[j])
w.writerow(l)
ws=3
with open("infile.csv","r") as inf: # rb and no newline param on python 2
with open("outfile.csv","w") as outf: # wb and no newline param on python 2
slide(inf,outf,ws)
I am trying to match a Java version in HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall by iterating over the subkeys within Uninstall. I am trying to match a regular expression to Java 7 Update 40, but the regex is matching all DisplayName entries. Below is the code:
On Error Resume Next
Const HKEY_LOCAL_MACHINE = &H80000002
Dim oReg
Dim objShell
Set objShell = WScript.CreateObject("WScript.Shell")
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\.\root\default:StdRegProv")
Dim sPath, aSub, sKey
Set objRegEx = New RegExp
objRegEx.Pattern = "\w{4}\s\d{1}\s\w{6}\s\d+"
objRedEx.IgnoreCase = True
objRegEx.Global = False
sPath = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
oReg.EnumKey HKEY_LOCAL_MACHINE, sPath, aSub
For Each sKey In aSub
disName = "HKLM" & "\" & sPath & "\" & sKey & "\DisplayName"
unString = "HKLM" & "\" & sPath & "\" & sKey & "\UninstallString"
reDisName = objShell.RegRead(disName)
reUnString = objShell.RegRead(unString)
'Wscript.echo(reDisName)
If objRexEx.Test( reDisName ) Then
Wscript.echo "Match"
End If
'Wscript.echo ObjShell.RegRead(disName)
'Wscript.echo ObjShell.RegRead(unString)
Next
Sorry if the formatting is off, I put a ctrl-k in front of each code line. This is my first time posting here so go easy...
You should start all your scripts with Option Explicit and Dim all your variables. Then you wouldn't need sln's eagle eyes to spot your typo:
Option Explicit
Dim objRegEx : Set objRegEx = New RegExp
objRegEx.Pattern = "\w{4}\s\d{1}\s\w{6}\s\d+"
objRedEx.IgnoreCase = True
output:
cscript 19188400.vbs
...\19188400.vbs(4, 1) Microsoft VBScript runtime error: Variable is undefined: 'objRedEx'
If you insist on using a global On Error Resume Next (a most dangerous mal-practice) then you should disable it until your script is thoroughly debugged. Keeping the OERN in a script known to have even the slightest problem is inviting desaster. Asking for help with code containing a global OERN is futile. So run you program without the OERN and see if the cause for its misbehaviour in't obvious.
Diagnostic output should be as specific as possible. Your WScript.Echo "Match" just shows that the statement is executed; a WScript.Echo "Match", disname would be a bit better. Using .Execute and looking at the Match's details could be more revealing.
The .Pattern should be more specific to. If you look for java updates, anchoring a literal "java" at the start of the string, and asking for "upgrade" instead of "\w{6}" may help to avoid false positives. OTOH, my display names don't look like
Java 7 Update 19
but like
Java(TM) 6 Update 19
and who knows what the next owner of Java will put into the display name.
You seem to have a few typo's
objRedEx.IgnoreCase = True
...
If objRexEx.Test( reDisName ) Then
This question already has answers here:
How to print color in console using System.out.println?
(15 answers)
Closed 5 years ago.
How can I color Java output?
For example in C and other languages I can use ANSI-escape like \033[0m to do this. But in Java it doesn't work.
public static void main(String[] x) {
System.out.println("\033[0m BLABLA \033[0m\n");
}
Note
You may not be able to color Window's cmd prompt, but it should work in many unix (or unix-like) terminals.
Also, note that some terminals simply won't support some (if any) ANSI escape sequences and, especially, 24-bit colors.
Usage
Please refer to the section Curses at the bottom for the best solution. For a personal or easy solution (although not as cross-platform solution), refer to the ANSI Escape Sequences section.
TL;DR
java: System.out.println((char)27 + "[31m" + "ERROR MESSAGE IN RED");
python: print(chr(27) + "[31m" + "ERROR MESSAGE IN RED")
bash or zsh: printf '\x1b[31mERROR MESSAGE IN RED'
this may also work for Os X: printf '\e[31mERROR MESSAGE IN RED'
sh: printf 'CTRL+V,CTRL+[[31mERROR MESSAGE IN RED'
ie, press CTRL+V and then CTRL+[ in order to get a "raw" ESC character when escape interpretation is not available
If done correctly, you should see a ^[. Although it looks like two characters, it is really just one, the ESC character.
You can also press CTRL+V,CTRL+[ in vim in any of the programming or sripting langauges because that uses a literal ESC character
Also, you can replace Ctrl+[ with ESC … eg, you can use CTRL+V,ESC, but I find the former easier, since I am already pressing CTRL and since [ is less out of the way.
ANSI Escape Sequences
Background on Escape Sequences
While it is not the best way to do it, the easiest way to do this in a programming or scripting language is to use escape sequences. From that link:
An escape sequence is a series of characters used to change the state of computers and their attached peripheral devices. These are also known as control sequences, reflecting their use in device control.
Backgound on ANSI Escape Sequences
However, it gets even easier than that in video text terminals, as these terminals use ANSI escape sequences. From that link:
ANSI escape sequences are a standard for in-band signaling to control the cursor location, color, and other options on video text terminals. Certain sequences of bytes, most starting with Esc and '[', are embedded into the text, which the terminal looks for and interprets as commands, not as character codes.
How to Use ANSI Escape Sequences
Generally
Escape sequences begin with an escape character; for ANSI escape sequences, the sequence always begins with ESC (ASCII: 27 / hex: 0x1B).
For a list of what you can do, refer to the ANSI Escape Sequence List on Wikipedia
In Programming Languages
Some programming langauges (like Java) will not interpret \e or \x1b as the ESC character. However, we know that the ASCII character 27 is the ESC character, so we can simply typecast 27 to a char and use that to begin the escape sequence.
Here are some ways to do it in common programming languages:
Java
System.out.println((char)27 + "[33mYELLOW");
Python 3
print(chr(27) + "[34mBLUE");
print("\x1b[35mMAGENTA");
Note that \x1b is interpretted correctly in python
Node JS
The following will NOT color output in JavaScript in the Web Console
console.log(String.fromCharCode(27) + "[36mCYAN");
console.log("\x1b[30;47mBLACK_ON_WHITE");
Note that \x1b also works in node
In Shell Prompt OR Scripts
If you are working with bash or zsh, it is quite easy to color the output (in most terminals). In Linux, Os X, and in some Window's terminals, you can check to see if your terminal supports color by doing both of the following:
printf '\e[31mRED'
printf '\x1b[31mRED'
If you see color for both, then that's great! If you see color for only one, then use that sequence. If you do not see color for either of them, then double check to make sure you typed everything correctly and that you are in bash or zsh; if you still do not see any color, then your terminal probably does not support ANSI escape sequences.
If I recall correctly, linux terminals tend to support both \e and \x1b escape sequences, while os x terminals only tend to support \e, but I may be wrong. Nonetheless, if you see something like the following image, then you're all set! (Note that I am using the shell, zsh, and it is coloring my prompt string; also, I am using urxvt as my terminal in linux.)
"How does this work?" you might ask. Bascially, printf is interpretting the sequence of characters that follows (everything inside of the single-quotes). When printf encounters \e or \x1b, it will convert these characters to the ESC character (ASCII: 27). That's just what we want. Now, printf sends ESC31m, and since there is an ESC followed by a valid ANSI escape sequence, we should get colored output (so long as it is supported by the terminal).
You can also use echo -e '\e[32mGREEN' (for example), to color output. Note that the -e flag for echo "[enables] interpretation of backslash escapes" and must be used if you want echo to appropriately interpret the escape sequence.
More on ANSI Escape Sequences
ANSI escape sequences can do more than just color output, but let's start with that, and see exactly how color works; then, we will see how to manipulate the cursor; finally, we'll take a look and see how to use 8-bit color and also 24-bit color (although it only has tenuous support).
On Wikipedia, they refer to ESC[ as CSI, so I will do the same.
Color
To color output using ANSI escapes, use the following:
CSI n m
CSI: escape character—^[[ or ESC[
n: a number—one of the following:
30-37, 39: foreground
40-47, 49: background
m: a literal ASCII m—terminates the escape sequence
I will use bash or zsh to demonstrate all of the possible color combinations. Plop the following in bash or zsh to see for yourself (You may need to replace \e with \x1b):
for fg in {30..37} 39; do for bg in {40..47} 49; do printf "\e[${fg};${bg}m~TEST~"; done; printf "\n"; done;
Result:
Quick Reference (Color)
+~~~~~~+~~~~~~+~~~~~~~~~~~+
| fg | bg | color |
+~~~~~~+~~~~~~+~~~~~~~~~~~+
| 30 | 40 | black |
| 31 | 41 | red |
| 32 | 42 | green |
| 33 | 43 | yellow |
| 34 | 44 | blue |
| 35 | 45 | magenta |
| 36 | 46 | cyan |
| 37 | 47 | white |
| 39 | 49 | default |
+~~~~~~+~~~~~~+~~~~~~~~~~~+
Select Graphic Rendition (SGR)
SGR just allows you to change the text. Many of these do not work in certain terminals, so use these sparingly in production-level projects. However, they can be useful for making program output more readable or helping you distinguish between different types of output.
Color actually falls under SGR, so the syntax is the same:
CSI n m
CSI: escape character—^[[ or ESC[
n: a number—one of the following:
0: reset
1-9: turns on various text effects
21-29: turns off various text effects (less supported than 1-9)
30-37, 39: foreground color
40-47, 49: background color
38: 8- or 24-bit foreground color (see 8/24-bit Color below)
48: 8- or 24-bit background color (see 8/24-bit Color below)
m: a literal ASCII m—terminates the escape sequence
Although there is only tenuous support for faint (2), italic (3), underline (4), blinking (5,6), reverse video (7), conceal (8), and crossed out (9), some (but rarely all) tend to work on linux and os x terminals.
It's also worthwhile to note that you can separate any of the above attributes with a semi-colon. For example printf '\e[34;47;1;3mCRAZY TEXT\n' will show CRAZY TEXT with a blue foreground on a white background, and it will be bold and italic.
Eg:
Plop the following in your bash or zsh shell to see all of the text effects you can do. (You may need to replace \e with \x1b.)
for i in {1..9}; do printf "\e[${i}m~TEST~\e[0m "; done
Result:
You can see that my terminal supports all of the text effects except for faint (2), conceal (8) and cross out (9).
Quick Reference (SGR Attributes 0-9)
+~~~~~+~~~~~~~~~~~~~~~~~~+
| n | effect |
+~~~~~+~~~~~~~~~~~~~~~~~~+
| 0 | reset |
| 1 | bold |
| 2 | faint* |
| 3 | italic** |
| 4 | underline |
| 5 | slow blink |
| 6 | rapid blink* |
| 7 | inverse |
| 8 | conceal* |
| 9 | strikethrough* |
+~~~~~+~~~~~~~~~~~~~~~~~~+
* not widely supported
** not widely supported and sometimes treated as inverse
8-bit Color
While most terminals support this, it is less supported than 0-7,9 colors.
Syntax:
CSI 38;5; n m
CSI: escape character—^[[ or ESC[
38;5;: literal string that denotes use of 8-bit colors for foreground
n: a number—one of the following:
0-255
If you want to preview all of the colors in your terminal in a nice way, I have a nice script on gist.github.com.
It looks like this:
If you want to change the background using 8-bit colors, just replace the 38 with a 48:
CSI 48;5; n m
CSI: escape character—^[[ or ESC[
48;5;: literal string that denotes use of 8-bit colors for background
n: a number—one of the following:
0-255
24-bit Color
Also known as true color, 24-bit color provides some really cool functionality. Support for this is definitely growing (as far as I know it works in most modern terminals except urxvt, my terminal [insert angry emoji]).
24-bit color is actually supported in vim (see the vim wiki to see how to enable 24-bit colors). It's really neat because it pulls from the colorscheme defined for gvim; eg, it uses the fg/bg from highlight guibg=#______ guifg=#______ for the 24-bit colors! Neato, huh?
Here is how 24-bit color works:
CSI 38;2; r ; g ; b m
CSI: escape character—^[[ or ESC[
38;2;: literal string that denotes use of 24-bit colors for foreground
r,g,b: numbers—each should be 0-255
To test just a few of the many colors you can have ((2^8)^3 or 2^24 or 16777216 possibilites, I think), you can use this in bash or zsh:
for r in 0 127 255; do for g in 0 127 255; do for b in 0 127 255; do printf "\e[38;2;${r};${g};${b}m($r,$g,$b)\e[0m "; done; printf "\n"; done; done;
Result (this is in gnome-terminal since urxvt DOES NOT SUPPORT 24-bit color ... get it together, urxvt maintainer ... for real):
If you want 24-bit colors for the background ... you guessed it! You just replace 38 with 48:
CSI 48;2; r ; g ; b m
CSI: escape character—^[[ or ESC[
48;2;: literal string that denotes use of 24-bit colors for background
r,g,b: numbers—each should be 0-255
Inserting Raw Escape Sequences
Sometimes \e and \x1b will not work. For example, in the sh shell, sometimes neither works (although it does on my system now, I don't think it used to).
To circumvent this, you can use CTRL+V,CTRL+[ or CTRLV,ESC
This will insert a "raw" ESC character (ASCII: 27). It will look like this ^[, but do not fret; it is only one character—not two.
Eg:
Curses
Refer to the Curses (Programming Library) page for a full reference on curses. It should be noted that curses only works on unix and unix-like operating systems.
Up and Running with Curses
I won't go into too much detail, for search engines can reveal links to websites that can explain this much better than I can, but I'll discuss it briefly here and give an example.
Why Use Curses Over ANSI Escapes?
If you read the above text, you might recall that \e or \x1b will sometimes work with printf. Well, sometimes \e and \x1b will not work at all (this is not standard and I have never worked with a terminal like this, but it is possible). More importantly, more complex escape sequences (think Home and other multi-character keys) are difficult to support for every terminal (unless you are willing to spend a lot of time and effort parsing terminfo and termcap and and figuring out how to handle every terminal).
Curses solves this problem. Basically, it is able to understand what capabilities a terminal has, using these methods (as described by the wikipedia article linked above):
Most implementations of curses use a database that can describe the capabilities of thousands of different terminals. There are a few implementations, such as PDCurses, which use specialized device drivers rather than a terminal database. Most implementations use terminfo; some use termcap. Curses has the advantage of back-portability to character-cell terminals and simplicity. For an application that does not require bit-mapped graphics or multiple fonts, an interface implementation using curses will usually be much simpler and faster than one using an X toolkit.
Most of the time, curses will poll terminfo and will then be able to understand how to manipulate the cursor and text attributes. Then, you, the programmer, use the API provided by curses to manipulate the cursor or change the text color or other attributes if the functionality you seek is desired.
Example with Python
I find python is really easy to use, but if you want to use curses in a different programming language, then simply search it on duckduckgo or any other search engine. :) Here is a quick example in python 3:
import curses
def main(stdscr):
# allow curses to use default foreground/background (39/49)
curses.use_default_colors()
# Clear screen
stdscr.clear()
curses.init_pair(1, curses.COLOR_RED, -1)
curses.init_pair(2, curses.COLOR_GREEN, -1)
stdscr.addstr("ERROR: I like tacos, but I don't have any.\n", curses.color_pair(1))
stdscr.addstr("SUCCESS: I found some tacos.\n", curses.color_pair(2))
stdscr.refresh() # make sure screen is refreshed
stdscr.getkey() # wait for user to press key
if __name__ == '__main__':
curses.wrapper(main)
result:
You might think to yourself that this is a much more round-about way of doing things, but it really is much more cross-platform (really cross-terminal … at least in the unix- and unix-like-platform world). For colors, it is not quite as important, but when it comes to supporting other multi-sequence escape sequences (such as Home, End, Page Up, Page Down, etc), then curses becomes all the more important.
Example with Tput
tput is a command line utility for manipulating cursor and text
tput comes with the curses package. If you want to use cross-terminal (ish) applications in the terminal, you should use tput, as it parses terminfo or whatever it needs to and uses a set of standardized commands (like curses) and returns the correct escape sequence.
example:
echo "$(tput setaf 1)$(tput bold)ERROR:$(tput sgr0)$(tput setaf 1) My tacos have gone missing"
echo "$(tput setaf 2)$(tput bold)SUCCESS:$(tput sgr0)$(tput setaf 2) Oh good\! I found my tacos\!"
Result:
More Info on Tput
see: http://linuxcommand.org/lc3_adv_tput.php to see how tput works
see: http://invisible-island.net/ncurses/man/terminfo.5.html for a list of commands that you can use
This has worked for me:
System.out.println((char)27 + "[31mThis text would show up red" + (char)27 + "[0m");
You need the ending "[37m" to return the color to white (or whatever you were using). If you don't it may make everything that follows "red".
No, but there are third party API's that can handle it
http://www.javaworld.com/javaworld/javaqa/2002-12/02-qa-1220-console.html
Edit: of course there are newer articles than that one I posted, the information is still viable though.
Above link is dead, see this question instead: How to print color in console using System.out.println?
You can use the JANSI library to render ANSI escape sequences in Windows.
Yes it is 100% possible
set classpath= %classpath%;d:\jansi-1.4.jar;
Try this below code:
import org.fusesource.jansi.AnsiConsole;
import static org.fusesource.jansi.Ansi.*;
import static org.fusesource.jansi.Ansi.Color.*;
public class Sample
{
public static void main(String[] args)
{
AnsiConsole.systemInstall();
System.out.println(ansi().fg(RED).a("Hello World").reset());
System.out.println("My Name is Raman");
AnsiConsole.systemUninstall();
}
}
Here is a solution for Win32 Console.
1) Get JavaNativeAccess libraries here: https://github.com/twall/jna/
2) These two Java classes will do the trick.
Enjoy.
package com.stackoverflow.util;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Structure;
public class Win32 {
public static final int STD_INPUT_HANDLE = -10;
public static final int STD_OUTPUT_HANDLE = -11;
public static final int STD_ERROR_HANDLE = -12;
public static final short CONSOLE_FOREGROUND_COLOR_BLACK = 0x00;
public static final short CONSOLE_FOREGROUND_COLOR_BLUE = 0x01;
public static final short CONSOLE_FOREGROUND_COLOR_GREEN = 0x02;
public static final short CONSOLE_FOREGROUND_COLOR_AQUA = 0x03;
public static final short CONSOLE_FOREGROUND_COLOR_RED = 0x04;
public static final short CONSOLE_FOREGROUND_COLOR_PURPLE = 0x05;
public static final short CONSOLE_FOREGROUND_COLOR_YELLOW = 0x06;
public static final short CONSOLE_FOREGROUND_COLOR_WHITE = 0x07;
public static final short CONSOLE_FOREGROUND_COLOR_GRAY = 0x08;
public static final short CONSOLE_FOREGROUND_COLOR_LIGHT_BLUE = 0x09;
public static final short CONSOLE_FOREGROUND_COLOR_LIGHT_GREEN = 0x0A;
public static final short CONSOLE_FOREGROUND_COLOR_LIGHT_AQUA = 0x0B;
public static final short CONSOLE_FOREGROUND_COLOR_LIGHT_RED = 0x0C;
public static final short CONSOLE_FOREGROUND_COLOR_LIGHT_PURPLE = 0x0D;
public static final short CONSOLE_FOREGROUND_COLOR_LIGHT_YELLOW = 0x0E;
public static final short CONSOLE_FOREGROUND_COLOR_BRIGHT_WHITE = 0x0F;
public static final short CONSOLE_BACKGROUND_COLOR_BLACK = 0x00;
public static final short CONSOLE_BACKGROUND_COLOR_BLUE = 0x10;
public static final short CONSOLE_BACKGROUND_COLOR_GREEN = 0x20;
public static final short CONSOLE_BACKGROUND_COLOR_AQUA = 0x30;
public static final short CONSOLE_BACKGROUND_COLOR_RED = 0x40;
public static final short CONSOLE_BACKGROUND_COLOR_PURPLE = 0x50;
public static final short CONSOLE_BACKGROUND_COLOR_YELLOW = 0x60;
public static final short CONSOLE_BACKGROUND_COLOR_WHITE = 0x70;
public static final short CONSOLE_BACKGROUND_COLOR_GRAY = 0x80;
public static final short CONSOLE_BACKGROUND_COLOR_LIGHT_BLUE = 0x90;
public static final short CONSOLE_BACKGROUND_COLOR_LIGHT_GREEN = 0xA0;
public static final short CONSOLE_BACKGROUND_COLOR_LIGHT_AQUA = 0xB0;
public static final short CONSOLE_BACKGROUND_COLOR_LIGHT_RED = 0xC0;
public static final short CONSOLE_BACKGROUND_COLOR_LIGHT_PURPLE = 0xD0;
public static final short CONSOLE_BACKGROUND_COLOR_LIGHT_YELLOW = 0xE0;
public static final short CONSOLE_BACKGROUND_COLOR_BRIGHT_WHITE = 0xF0;
// typedef struct _COORD {
// SHORT X;
// SHORT Y;
// } COORD, *PCOORD;
public static class COORD extends Structure {
public short X;
public short Y;
}
// typedef struct _SMALL_RECT {
// SHORT Left;
// SHORT Top;
// SHORT Right;
// SHORT Bottom;
// } SMALL_RECT;
public static class SMALL_RECT extends Structure {
public short Left;
public short Top;
public short Right;
public short Bottom;
}
// typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
// COORD dwSize;
// COORD dwCursorPosition;
// WORD wAttributes;
// SMALL_RECT srWindow;
// COORD dwMaximumWindowSize;
// } CONSOLE_SCREEN_BUFFER_INFO;
public static class CONSOLE_SCREEN_BUFFER_INFO extends Structure {
public COORD dwSize;
public COORD dwCursorPosition;
public short wAttributes;
public SMALL_RECT srWindow;
public COORD dwMaximumWindowSize;
}
// Source: https://github.com/twall/jna/nonav/javadoc/index.html
public interface Kernel32 extends Library {
Kernel32 DLL = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
// HANDLE WINAPI GetStdHandle(
// __in DWORD nStdHandle
// );
public int GetStdHandle(
int nStdHandle);
// BOOL WINAPI SetConsoleTextAttribute(
// __in HANDLE hConsoleOutput,
// __in WORD wAttributes
// );
public boolean SetConsoleTextAttribute(
int in_hConsoleOutput,
short in_wAttributes);
// BOOL WINAPI GetConsoleScreenBufferInfo(
// __in HANDLE hConsoleOutput,
// __out PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
// );
public boolean GetConsoleScreenBufferInfo(
int in_hConsoleOutput,
CONSOLE_SCREEN_BUFFER_INFO out_lpConsoleScreenBufferInfo);
// DWORD WINAPI GetLastError(void);
public int GetLastError();
}
}
package com.stackoverflow.util;
import java.io.PrintStream;
import com.stackoverflow.util.Win32.Kernel32;
public class ConsoleUtil {
public static void main(String[] args)
throws Exception {
System.out.print("abc");
static_color_print(
System.out,
"def",
Win32.CONSOLE_BACKGROUND_COLOR_RED,
Win32.CONSOLE_FOREGROUND_COLOR_BRIGHT_WHITE);
System.out.print("def");
System.out.println();
}
private static Win32.CONSOLE_SCREEN_BUFFER_INFO _static_console_screen_buffer_info = null;
public static void static_save_settings() {
if (null == _static_console_screen_buffer_info) {
_static_console_screen_buffer_info = new Win32.CONSOLE_SCREEN_BUFFER_INFO();
}
int stdout_handle = Kernel32.DLL.GetStdHandle(Win32.STD_OUTPUT_HANDLE);
Kernel32.DLL.GetConsoleScreenBufferInfo(stdout_handle, _static_console_screen_buffer_info);
}
public static void static_restore_color()
throws Exception {
if (null == _static_console_screen_buffer_info) {
throw new Exception("Internal error: Must save settings before restore");
}
int stdout_handle = Kernel32.DLL.GetStdHandle(Win32.STD_OUTPUT_HANDLE);
Kernel32.DLL.SetConsoleTextAttribute(
stdout_handle,
_static_console_screen_buffer_info.wAttributes);
}
public static void static_set_color(Short background_color, Short foreground_color) {
int stdout_handle = Kernel32.DLL.GetStdHandle(Win32.STD_OUTPUT_HANDLE);
if (null == background_color || null == foreground_color) {
Win32.CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info =
new Win32.CONSOLE_SCREEN_BUFFER_INFO();
Kernel32.DLL.GetConsoleScreenBufferInfo(stdout_handle, console_screen_buffer_info);
short current_bg_and_fg_color = console_screen_buffer_info.wAttributes;
if (null == background_color) {
short current_bg_color = (short) (current_bg_and_fg_color / 0x10);
background_color = new Short(current_bg_color);
}
if (null == foreground_color) {
short current_fg_color = (short) (current_bg_and_fg_color % 0x10);
foreground_color = new Short(current_fg_color);
}
}
short bg_and_fg_color =
(short) (background_color.shortValue() | foreground_color.shortValue());
Kernel32.DLL.SetConsoleTextAttribute(stdout_handle, bg_and_fg_color);
}
public static<T> void static_color_print(
PrintStream ostream,
T value,
Short background_color,
Short foreground_color)
throws Exception {
static_save_settings();
try {
static_set_color(background_color, foreground_color);
ostream.print(value);
}
finally {
static_restore_color();
}
}
public static<T> void static_color_println(
PrintStream ostream,
T value,
Short background_color,
Short foreground_color)
throws Exception {
static_save_settings();
try {
static_set_color(background_color, foreground_color);
ostream.println(value);
}
finally {
static_restore_color();
}
}
}
The simplest method is to run your program (unmodified) in Cygwin console.
The second simplest method is to run you program (also unmodified) in the ordinary Windows console, pipelining its output through tee.exe (from Cygwin or Git distribution). Tee.exe will recognize the escape codes and call appropriate WinAPI functions.
Something like:
java MyClass | tee.exe log.txt
java MyClass | tee.exe /dev/null
I created a jar library called JCDP (Java Colored Debug Printer).
For Linux it uses the ANSI escape codes that WhiteFang mentioned, but abstracts them using words instead of codes which is much more intuitive.
For Windows it actually includes the JAnsi library but creates an abstraction layer over it, maintaining the intuitive and simple interface created for Linux.
This library is licensed under the MIT License so feel free to use it.
Have a look at JCDP's github repository.
Escape sequences must be interpreted by SOMETHING to be converted to color. The standard CMD.EXE used by java when started from the command line, doesn't support this so therefore Java does not.
Check This Out: i used ANSI values with escape code and it probably not work in windows command prompt but in IDEs and Unix shell.
you can also check 'Jansi' library here for windows support.
System.out.println("\u001B[35m" + "This text is PURPLE!" + "\u001B[0m");
I've written a library called AnsiScape that allows you to write coloured output in a more structured way:
Example:
AnsiScape ansiScape = new AnsiScape();
String colors = ansiScape.format("{red {blueBg Red text with blue background}} {b Bold text}");
System.out.println(colors);
The library it also allows you to define your own "escape classes" akin to css classes.
Example:
AnsiScapeContext context = new AnsiScapeContext();
// Defines a "class" for text
AnsiClass text = AnsiClass.withName("text").add(RED);
// Defines a "class" for the title used
AnsiClass title = AnsiClass.withName("title").add(BOLD, BLUE_BG, YELLOW);
// Defines a "class" to render urls
AnsiClass url = AnsiClass.withName("url").add(BLUE, UNDERLINE);
// Registering the classes to the context
context.add(text).add(title).add(url);
// Creating an AnsiScape instance with the custom context
AnsiScape ansiScape = new AnsiScape(context);
String fmt = "{title Chapter 1}\n" +
"{text So it begins:}\n" +
"- {text Option 1}\n" +
"- {text Url: {url www.someurl.xyz}}";
System.out.println(ansiScape.format(fmt));
System.err.println("Errorrrrrr") it will print text in Red color on console.
This works in eclipse just to turn it red, don't know about other places.
System.err.println(" BLABLA ");