<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Martok&#039;s Place &#187; Programmierung</title>
	<atom:link href="http://www.martoks-place.de/category/programmierung/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.martoks-place.de</link>
	<description></description>
	<lastBuildDate>Mon, 16 Jan 2012 23:57:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Trust in Me!</title>
		<link>http://www.martoks-place.de/2011/08/trust-me/</link>
		<comments>http://www.martoks-place.de/2011/08/trust-me/#comments</comments>
		<pubDate>Sun, 28 Aug 2011 01:10:34 +0000</pubDate>
		<dc:creator>Martok</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Hack]]></category>

		<guid isPermaLink="false">http://www.martoks-place.de/?p=630</guid>
		<description><![CDATA[Nehmen wir mal an, ein (Delphi-)object, welches eine Liste gleicher Objekte verwalten soll. Man könnte das einen Baum nennen. TValueList = array of TValue; TValue = object FList: TValueList; SomeOtherStuff: integer; end; (Für später geborene: das ist die alte Syntax für &#8220;record mit Methoden&#8221;.) Leider nimmt uns der Compiler das so nicht ab. Warum? Weil [...]]]></description>
			<content:encoded><![CDATA[<p>Nehmen wir mal an, ein (Delphi-)<strong>object</strong>, welches eine Liste gleicher Objekte verwalten soll. Man könnte das einen Baum nennen.</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;">  TValueList <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">array</span> <span style="color: #000000; font-weight: bold;">of</span> TValue<span style="color: #000066;">;</span>
  TValue <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">object</span>
    FList<span style="color: #000066;">:</span> TValueList<span style="color: #000066;">;</span>
    SomeOtherStuff<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">integer</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p>(Für später geborene: das ist die alte Syntax für &#8220;record mit Methoden&#8221;.)</p>
<p>Leider nimmt uns der Compiler das so nicht ab. Warum? Weil TValue natürlich vorher noch nicht bekannt ist. Und im Gegensatz zu Klassen kann man Records nicht vorwärtsdeklarieren. Wie also könnten wir dieses Problem lösen? Man könnte Pointer verwenden, und bei Verwendung entsprechend erzeugen. Aber freigeben? Es gibt ja keinen Destructor, also keine Option. Man könnte das gesamte Objekt in eine Klassen-Instanz verwandeln, die von IUnknown die Referenzzählung erbt. Das ist aber wesentlich mehr Aufwand als das bisherige &#8220;Deklarieren und Verwenden&#8221;.</p>
<p>Die Lösung hier zeigt sich in einem fiesen, aber einfachen Hack:</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;">TValueListAlias <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">array</span> <span style="color: #000000; font-weight: bold;">of</span> <span style="color: #000066; font-weight: bold;">boolean</span><span style="color: #000066;">;</span>
TValue <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">object</span>
  FList<span style="color: #000066;">:</span> TValueListAlias<span style="color: #000066;">;</span>
  SomeOtherStuff<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">integer</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
TValueList <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">array</span> <span style="color: #000000; font-weight: bold;">of</span> TValue<span style="color: #000066;">;</span></pre></div></div>

<p>Dabei spielt es keine Rolle, welchen Basistypen man für das Alias verwendet. Es muss sich nur um ein dynamisches Array handeln. Jetzt kann man in jedem Zugriff auf das eigentliche TValueList casten und alles funktioniert. Dabei kann man die Hässlichkeiten wunderbar in Zugriffsmethoden verbergen.</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000066;">SetLength</span><span style="color: #000066;">&#40;</span>TValueList<span style="color: #000066;">&#40;</span>FList<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">42</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></div></div>

<p>Das funktioniert auch, aber wenn TValue nun Felder die finialisiert werden müssen enthält, wird sich FastMM beschweren, dass eben diese nie freigegeben werden. Es stellt sich heraus, dass SetLength zwar den BaseType richtig speichert und auch in @DynArrayClear exakt diesen wieder beräumt, aber Felder im Gegensatz zu Variablen nicht damit, sondern mit FinalizeArray freigegeben werden. Und dieses richtet sich nach der Deklaration, nicht nach dem was wirklich passiert.</p>
<p>Hier kommt dann der eigentliche Grund für diesen Beitrag: wir sagen der RTL einfach: &#8220;Vertrau mir, das ist ein anderer Datentyp!&#8221;. Mit anderen Worten: wir patchen die Feld-Tabelle der betroffenen Klasse so, dass FinalizeArray dort ein TValueList (BaseType also TValue, nicht unser Dummy von weiter oben) sieht und dieses korrekt finalisiert.</p>
<p>Das ist zunächst einfacher als gedacht:</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;">TI<span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">TypeInfo</span><span style="color: #000066;">&#40;</span>TValue<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
FT <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066; font-weight: bold;">Pointer</span><span style="color: #000066;">&#40;</span><span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">&#40;</span>TI<span style="color: #000066;">&#41;</span> <span style="color: #000066;">+</span> <span style="color: #000066; font-weight: bold;">Byte</span><span style="color: #000066;">&#40;</span>TI<span style="color: #000066;">.</span><span style="color: #006600;">Name</span><span style="color: #000066;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">for</span> I <span style="color: #000066;">:</span><span style="color: #000066;">=</span> FT<span style="color: #000066;">.</span><span style="color: #006600;">Count</span><span style="color: #000066;">-</span><span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">downto</span> <span style="color: #0000ff;">0</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">if</span> FT<span style="color: #000066;">.</span><span style="color: #006600;">Fields</span><span style="color: #000066;">&#91;</span>I<span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #000066;">TypeInfo</span><span style="color: #000066;">^</span> <span style="color: #000066;">=</span> <span style="color: #000066;">TypeInfo</span><span style="color: #000066;">&#40;</span>TValueListAlias<span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">then</span>
    ppti<span style="color: #000066;">:</span><span style="color: #000066;">=</span> FT<span style="color: #000066;">.</span><span style="color: #006600;">Fields</span><span style="color: #000066;">&#91;</span>I<span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #000066;">TypeInfo</span><span style="color: #000066;">^</span><span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">TypeInfo</span><span style="color: #000066;">&#40;</span>TValueList<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p>Nur &#8211; das funktioniert so nicht <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Runtime Error 216 ist die Folge einer Exception beim Schreiben der neuen TypeInfo. Da hat nämlich mal jemand mitgedacht und die dazugehörige Seite als PAGE_EXECUTE_READ markiert. Was man zum Glück in seinem eigenen Prozess beliebig ändern kann, und so ergibt sich (mit allen Deklarationen) folgendes Meisterwerk:</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">procedure</span> FixFieldTable<span style="color: #000066;">&#40;</span>TheRecord<span style="color: #000066;">,</span> Find<span style="color: #000066;">,</span> Replace<span style="color: #000066;">:</span> PTypeInfo<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">type</span>
  TFieldInfo <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">packed</span> <span style="color: #000000; font-weight: bold;">record</span>
    <span style="color: #000066;">TypeInfo</span><span style="color: #000066;">:</span> PPTypeInfo<span style="color: #000066;">;</span>
    Offset<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Cardinal</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
  PFieldTable <span style="color: #000066;">=</span> <span style="color: #000066;">^</span>TFieldTable<span style="color: #000066;">;</span>
  TFieldTable <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">packed</span> <span style="color: #000000; font-weight: bold;">record</span>
    X<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Word</span><span style="color: #000066;">;</span>
    Size<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Cardinal</span><span style="color: #000066;">;</span>
    Count<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Cardinal</span><span style="color: #000066;">;</span>
    Fields<span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">array</span> <span style="color: #000066;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">..</span><span style="color: #0000ff;">0</span><span style="color: #000066;">&#93;</span> <span style="color: #000000; font-weight: bold;">of</span> TFieldInfo<span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  FT<span style="color: #000066;">:</span> PFieldTable<span style="color: #000066;">;</span>
  ppti<span style="color: #000066;">:</span> PPTypeInfo<span style="color: #000066;">;</span>
  I<span style="color: #000066;">,</span> old<span style="color: #000066;">,</span> dummy<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  FT <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066; font-weight: bold;">Pointer</span><span style="color: #000066;">&#40;</span><span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">&#40;</span>TheRecord<span style="color: #000066;">&#41;</span> <span style="color: #000066;">+</span> <span style="color: #000066; font-weight: bold;">Byte</span><span style="color: #000066;">&#40;</span>TheRecord<span style="color: #000066;">.</span><span style="color: #006600;">Name</span><span style="color: #000066;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">for</span> I <span style="color: #000066;">:</span><span style="color: #000066;">=</span> FT<span style="color: #000066;">.</span><span style="color: #006600;">Count</span><span style="color: #000066;">-</span><span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">downto</span> <span style="color: #0000ff;">0</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #000000; font-weight: bold;">if</span> FT<span style="color: #000066;">.</span><span style="color: #006600;">Fields</span><span style="color: #000066;">&#91;</span>I<span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #000066;">TypeInfo</span><span style="color: #000066;">^</span> <span style="color: #000066;">=</span> Find <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">begin</span>
      ppti<span style="color: #000066;">:</span><span style="color: #000066;">=</span> FT<span style="color: #000066;">.</span><span style="color: #006600;">Fields</span><span style="color: #000066;">&#91;</span>I<span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #000066;">TypeInfo</span><span style="color: #000066;">;</span>
      VirtualProtect<span style="color: #000066;">&#40;</span>ppti<span style="color: #000066;">,</span><span style="color: #000066;">SizeOf</span><span style="color: #000066;">&#40;</span>ppti<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> PAGE_READWRITE<span style="color: #000066;">,</span> old<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
      <span style="color: #000000; font-weight: bold;">try</span>
        ppti<span style="color: #000066;">^</span><span style="color: #000066;">:</span><span style="color: #000066;">=</span> Replace<span style="color: #000066;">;</span>
      <span style="color: #000000; font-weight: bold;">finally</span>
        VirtualProtect<span style="color: #000066;">&#40;</span>ppti<span style="color: #000066;">,</span> <span style="color: #000066;">sizeof</span><span style="color: #000066;">&#40;</span>ppti<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> old<span style="color: #000066;">,</span> dummy<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
      <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #808080; font-style: italic;">{...}</span>
&nbsp;
  FixFieldTable<span style="color: #000066;">&#40;</span><span style="color: #000066;">TypeInfo</span><span style="color: #000066;">&#40;</span>TValue<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #000066;">TypeInfo</span><span style="color: #000066;">&#40;</span>TValueListAlias<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #000066;">TypeInfo</span><span style="color: #000066;">&#40;</span>TValueList<span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></div></div>

<p>Wer sich die Datenstruktur ansieht, wird feststellen dass TFieldTable ein Feld namens &#8220;Size&#8221; enthält. Sollten wir das nicht anpassen? Die einfache Antwort ist: nein! In TValue selbst wird vom dynamischen Array nur ein Pointer auf den Anfang gespeichert, und der ist unabhängig vom genauen Aussehen des Arrays immer gleich groß: nämlich 32bit oder 4 Byte. Es ändert sich also nichts.<br />
Außerdem praktisch: da SetLength den Array-Typ anlegt, den man ihm übergibt (und wir ja auf TValueList casten), werden auch untergeordnete Arrays als das freigegeben was in ihnen steckt.</p>
<p>Das funktioniert so bis mindestens BDS2006, ich kann mir aber vorstellen dass die neuen RTTI-Strukturen in XE hier einige Änderungen notwendig machen. Das müssen dann aber andere testen <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Oh, übrigens, wer es nicht erkannt hat: der Titel ist natürlich eine Referenz auf <a href="http://en.wikipedia.org/wiki/Trust_in_Me_%28The_Python%27s_Song%29">Disney&#8217;s Dschungelbuch</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.martoks-place.de/2011/08/trust-me/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Punkteverteilung</title>
		<link>http://www.martoks-place.de/2011/03/punkteverteilung/</link>
		<comments>http://www.martoks-place.de/2011/03/punkteverteilung/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 15:08:25 +0000</pubDate>
		<dc:creator>Martok</dc:creator>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Fail]]></category>

		<guid isPermaLink="false">http://www.martoks-place.de/?p=510</guid>
		<description><![CDATA[Manchmal, nur ganz selten, verhält sich ein Code anders als man denkt, weil man was anderes programmiert hat als man denkt. Man nehme z.B. eine KI mit Negamax+AlphaBeta, die immer irgendwelche völlig behämmerten Züge ausführt. Irgendwann ist mir dann mal gedämmert, dass man sich ja mal die Score-Werte ausgeben lassen könnte. next move h1 to [...]]]></description>
			<content:encoded><![CDATA[<p>Manchmal, nur ganz selten, verhält sich ein Code anders als man denkt, weil man was anderes programmiert hat als man denkt.</p>
<p>Man nehme z.B. eine KI mit <a href="http://en.wikipedia.org/wiki/Negamax">Negamax+AlphaBeta</a>, die immer irgendwelche völlig behämmerten Züge ausführt. Irgendwann ist mir dann mal gedämmert, dass man sich ja mal die Score-Werte ausgeben lassen könnte.</p>

<div class="wp_syntax"><div class="code"><pre class="plain" style="font-family:monospace;">next move
  h1 to g1 score: 9
  h1 to g2 score: 9
  h1 to i2 score: 9
  h1 to h2 score: 9
  h1 to f1 score: 9
  h1 to f3 score: 9
  h1 to h3 score: 9
  i1 to h2 score: 9
  i1 to i2 score: 9
  i1 to g1 score: 9
  i1 to g3 score: 9
  i1 to i3 score: 9
  a9 to b8 score: 9
  a9 to b9 score: 9
  a9 to a8 score: 9
  a9 to c7 score: 9
  a9 to c9 score: 9
  a9 to a7 score: 9</pre></div></div>

<p>Huch! Alles das gleiche. Wie kann das sein?</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">function</span> Score<span style="color: #000066;">&#40;</span>ABoard<span style="color: #000066;">:</span> TBoard<span style="color: #000066;">;</span> Perspective<span style="color: #000066;">:</span> TField<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> TScore<span style="color: #000066;">;</span>
<span style="color: #808080; font-style: italic;">{...}</span>
          <span style="color: #000000; font-weight: bold;">if</span> Board<span style="color: #000066;">&#91;</span>c<span style="color: #000066;">,</span>r<span style="color: #000066;">&#93;</span><span style="color: #000066;">=</span>Perspective <span style="color: #000000; font-weight: bold;">then</span>
<span style="color: #808080; font-style: italic;">{...}</span></pre></div></div>

<p>M( M( M( M( M( M( M(</p>
<p>Board ist ein Member von TGame, und damit an dieser Stelle durchaus ein gültiger Bezeichner. Nur leider nicht der den ich will, denn damit habe ich immer das Brett vom Startpunkt bewertet, niemals das nach einem Zug. Sehr schön, es sollte mal einer intelligente Compiler entwickeln, die mir sowas direkt sagen&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.martoks-place.de/2011/03/punkteverteilung/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stand back &#8211; I know CMD!</title>
		<link>http://www.martoks-place.de/2011/01/stand-back-i-know-cmd/</link>
		<comments>http://www.martoks-place.de/2011/01/stand-back-i-know-cmd/#comments</comments>
		<pubDate>Wed, 05 Jan 2011 17:22:24 +0000</pubDate>
		<dc:creator>Martok</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Shell]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.martoks-place.de/?p=486</guid>
		<description><![CDATA[Ich merke das schon, Psychologie läuft nicht so gut wie Programmierung und Politik&#8230; gnuplot hält sich für ein sehr gutes Diagramm-Plot-Programm &#8211; und das stimmt meistens auch. Wenn es darum geht, Daten aus Dateien einzulesen wird das Skript zwar sehr schnell sehr hässlich, aber es funktioniert. Zumindest, wenn man die Daten vorkocht, denn filtern kann [...]]]></description>
			<content:encoded><![CDATA[<p>Ich merke das schon, Psychologie läuft nicht so gut wie Programmierung und Politik&#8230;</p>
<p><a href="http://www.gnuplot.info/">gnuplot</a> hält sich für ein sehr gutes Diagramm-Plot-Programm &#8211; und das stimmt meistens auch. Wenn es darum geht, Daten aus Dateien einzulesen wird das Skript zwar sehr schnell sehr hässlich, aber es funktioniert. Zumindest, wenn man die Daten vorkocht, denn filtern kann man sie in gnuplot selbst nicht mehr vernünftig. Das ist aber grade dann von Nöten, wenn man lange Messreihen hat, aber zum Beispiel nur an den letzten N Messwerten interessiert ist. Eigentlich doch ein nicht grade seltenes Problem, aber fertige Lösungen jenseits von `tail -n`  sind nicht wirklich auffindbar.<br />
<span id="more-486"></span><br />
Noch wesentlich haariger wird das Thema, sobald man einen Zeitstempel drin hat. Nun ist zwar gnuplot per</p>

<div class="wp_syntax"><div class="code"><pre class="gnuplot" style="font-family:monospace;"><span style="color: #b1b100;">set</span> <span style="color: #990000;">xdata</span> time
<span style="color: #b1b100;">set</span> <span style="color: #990000;">timefmt</span> <span style="color: #0000ff;">&quot;%s&quot;</span></pre></div></div>

<p> sehr gut in der Lage das zu lesen und richtig darzustellen, aber irgendwas damit anfangen kann man nicht.</p>
<p>Hier muss also ein separates Programm her&#8230; und weil ein Programm da vielleicht etwas Overkill wäre, können wir doch das auch mit Shell-Foo (Wie heißt das auf Windows? <em>cmd-foo</em>?) lösen, oder? Klar können wir das <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>

<div class="wp_syntax"><div class="code"><pre class="dos" style="font-family:monospace;"><span style="color: #33cc33;">@</span><span style="color: #b1b100; font-weight: bold;">echo</span> off
<span style="color: #b1b100; font-weight: bold;">setlocal</span>
<span style="color: #b1b100; font-weight: bold;">set</span> show_last_seconds=43200
<span style="color: #b1b100; font-weight: bold;">set</span> tmx=
<span style="color: #b1b100; font-weight: bold;">set</span> tmi=
<span style="color: #00b100; font-weight: bold;">for</span> /F &quot;usebackq delims=;&quot; <span style="color: #33cc33;">%%</span><span style="color: #448888;">i</span> <span style="color: #00b100; font-weight: bold;">in</span> <span style="color: #33cc33;">(</span>`tail -n 1 values.log`<span style="color: #33cc33;">)</span> <span style="color: #00b100; font-weight: bold;">do</span> <span style="color: #b1b100; font-weight: bold;">set</span> tmx=<span style="color: #33cc33;">%%</span><span style="color: #448888;">i</span>
<span style="color: #b1b100; font-weight: bold;">set</span> /a tmi=tmx-show_last_seconds
<span style="color: #b1b100; font-weight: bold;">del</span> akku.csv <span style="color: #33cc33;">&gt;</span><span style="color: #0000ff; font-weight: bold;">nul</span> 2<span style="color: #33cc33;">&gt;</span><span style="color: #0000ff; font-weight: bold;">nul</span>
<span style="color: #00b100; font-weight: bold;">for</span> /F &quot;tokens=1* delims=;&quot; <span style="color: #33cc33;">%%</span><span style="color: #448888;">i</span> <span style="color: #00b100; font-weight: bold;">in</span> <span style="color: #33cc33;">(</span>values.log<span style="color: #33cc33;">)</span> <span style="color: #00b100; font-weight: bold;">do</span> <span style="color: #33cc33;">(</span>
  <span style="color: #00b100; font-weight: bold;">if</span> /I <span style="color: #33cc33;">%%</span><span style="color: #448888;">i</span> <span style="color: #000000; font-weight: bold;">GTR</span> <span style="color: #33cc33;">%</span><span style="color: #448888;">tmi</span><span style="color: #33cc33;">%</span> <span style="color: #33cc33;">(</span>
    <span style="color: #b1b100; font-weight: bold;">echo</span> <span style="color: #33cc33;">%%</span><span style="color: #448888;">i</span>;<span style="color: #33cc33;">%%</span><span style="color: #448888;">j</span><span style="color: #33cc33;">&gt;&gt;</span>akku.csv
  <span style="color: #33cc33;">)</span>
<span style="color: #33cc33;">)</span>
..binwgnuplot akku.plt
start akku.png</pre></div></div>

<p>Kurzerklärung: das Skript sucht sich zuerst die letzte Zeile. Da cmd.exe nicht anders Strings parsen kann, muss hier <em>for</em> ran &#8211; eine Schleife über genau einen CSV-Datensatz. Davon wird dann die anzuzeigende Zeit subtrahiert (hier 4 Stunden) und in Folge alle Sätze der Quelldatei geprüft, ob sie neuer sind als diese Grenzzeit. Tun das, gehts ab in die gefilterte Datei, die ein einfaches gnuplot-Skript zur Grafik macht.</p>
<p>(<a href="http://xkcd.com/208/">Referenz</a> im <a href="/2011/01/stand-back-i-know/">Titel</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.martoks-place.de/2011/01/stand-back-i-know-cmd/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Kleine Hacks erhalten die Freundschaft</title>
		<link>http://www.martoks-place.de/2010/11/kleine-hacks/</link>
		<comments>http://www.martoks-place.de/2010/11/kleine-hacks/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 20:35:21 +0000</pubDate>
		<dc:creator>Martok</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Real Life]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Hack]]></category>
		<category><![CDATA[Uni]]></category>

		<guid isPermaLink="false">http://www.martoks-place.de/?p=474</guid>
		<description><![CDATA[Heute mal wieder was aus der Bastelkiste: Unser Institut für Mechanik hat für Belege und Praktika ein schickes kleines Delphi-Programm, welches die Aufgabenblätter generieren kann. Das ganze hat den Zweck, dass die Aufgaben sich mit der Matrikelnummer personalisieren lassen (RandSeed) und man seine berechneten Werte mittels dieses Programms direkt auf Korrektheit prüfen lassen kann. Nun [...]]]></description>
			<content:encoded><![CDATA[<p>Heute mal wieder was aus der Bastelkiste:</p>
<p>Unser Institut für Mechanik hat für Belege und Praktika ein schickes kleines Delphi-Programm, welches die Aufgabenblätter generieren kann. Das ganze hat den Zweck, dass die Aufgaben sich mit der Matrikelnummer personalisieren lassen (RandSeed) und man seine berechneten Werte mittels dieses Programms direkt auf Korrektheit prüfen lassen kann.</p>
<p>Nun sind die Aufgaben nicht immer so ganz ohne, und manchmal hilft es ungemein, nicht nur Eingabefelder zu haben, die einem sagen ob man richtig oder falsch lag, sondern auch mal spicken zu können, wo denn der Fehler liegt. </p>
<p>Aber erstmal eine kleine Anekdote.<br />
Man sitzt also in einer Vorlesung, und macht nebenbei mit einem Kommilitonen ein solches Übungsbelegblatt. Die Gleichungen sehen auch erstmal alle ganz schön aus. Nun hat man ja einen Laptop dabei, kann also die Ergebnisse kontrollieren. Und siehe da: nix passt.<br />
Was tut man also? Man versucht herauszubekommen, was das Programm denn als Zahlenwert erwartet. Irgendwie dachte ich mir (warum, weiß ich auch nicht; vielleicht wars ja Schicksal <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  ) dass mir ein Hex-Editor weiterhelfen könnte. Konnte er natürlich nicht, hat aber soweit geholfen, als dass ich festgestllt habe, dass es zu jedem Aufgabenblatt 2 Definitionen gibt. Eine generiert die Aufgabenstellung, und eine generiert&#8230; Moment. Was ist das? Ein Lösungsweg!<br />
Es gibt also nicht nur 2 Programmversionen (wie schon das _student im Dateinamen vermuten lässt), sondern zu allem Überfluss enthält die selbe Echse offenbar beide Teile. Irgendwo muss also umgeschaltet werden, was gemacht werden soll.</p>
<p>Nachdem man seinen IDA Pro wiedergefunden und gestartet hat, wird also mal das Programm hineingeworfen. Etwas warten, und die Programmstelle wieder finden. Das macht sich recht einfach, immerhin ist der Titel des Belegs ein <em>sehr</em> eindeutiges Merkmal (im Code-Segment jedenfalls). Nun muss man nur noch die XRefs zurückverfolgen, um rauszubekommen wo der wichtige Aufruf erfolgt. Der ist nämlich da, wo basierend auf einem Vergleich der eine oder andere Zweig (=Ausgabeanweisungen) aufgerufen wird. It always boils down to a simple comparision.<br />
Der letzte Schritt (wo allerdings leider die Vorlesung zuende war; der Teil mit dem &#8220;IDA wiederfinden&#8221; hatte etwas lange gedauert) ist es nun nur noch, die Zuweisung an die überprüfte Variable zu finden. Auch hier hilft wieder die XRefs-Funktion. Es gibt nämlich nur eine, und die schreibt eine $00, also den Ordinalwert für <strong>false</strong>. Man könnte also sagen, die betreffende Variable ist sowas wie IsTutorenVersion.<br />
Kurzer Patch in der Exe der (wir wissen ja: es ist Delphi) eine $01 (für <strong>true</strong>) stattdessen schreibt, und fertig.</p>
<p>Wer das liest und ein berechtigtes Interesse hat, der hat auch Wege mich nach dem Teil zu fragen. Das ist nun grade ein Hack, bei dem ich garantiert kein Responsible Disclosure machen werde. Das wäre nämlich sehr verantwortungslos. Mir selbst gegenüber <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> </p>
<p>Das wars erstmal von meiner Seite,<br />
Martok</p>
]]></content:encoded>
			<wfw:commentRss>http://www.martoks-place.de/2010/11/kleine-hacks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to not be evil [Update]</title>
		<link>http://www.martoks-place.de/2010/10/how-to-not-be-evil/</link>
		<comments>http://www.martoks-place.de/2010/10/how-to-not-be-evil/#comments</comments>
		<pubDate>Mon, 04 Oct 2010 03:03:03 +0000</pubDate>
		<dc:creator>Martok</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Edgemonkey]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JSON]]></category>

		<guid isPermaLink="false">http://www.martoks-place.de/?p=461</guid>
		<description><![CDATA[Wer kennt sie nicht, die beliebte Funktion eval()? Chrome zum Beispiel Das heißt auch, dass die bisher im Edgemonkey verwendete Kombination von eval/uneval zur (de)serialisierung von Einstellung und Speicherung dieser so in Chrome nie funktionieren wird (selbst wenn später einmal eine GM_setValue-Alternative zur Verfügung steht &#8211; stay tuned). Es muss also jedes Vorkommen davon durch [...]]]></description>
			<content:encoded><![CDATA[<p>Wer kennt sie nicht, die beliebte Funktion eval()? Chrome zum Beispiel <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Das heißt auch, dass die bisher im Edgemonkey verwendete Kombination von eval/uneval zur (de)serialisierung von Einstellung und Speicherung dieser so in Chrome nie funktionieren wird (selbst wenn später einmal eine <a href="http://wiki.greasespot.net/GM_setValue">GM_setValue</a>-Alternative zur Verfügung steht &#8211; stay tuned). Es muss also jedes Vorkommen davon durch die eigentlich viel schöneren und moderneren <a href="https://developer.mozilla.org/En/Using_JSON_in_Firefox">JSON.parse und JSON.stringify</a> ersetzt werden. Was aber nicht so einfach ist, da die Migration bisheriger Daten natürlich funktionieren muss.<br />
Was gar nicht so einfach ist &#8211; uneval erzeugt <strong>kein</strong> JSON, sondern nur etwas was <em>so ähnlich</em> aussieht!</p>
<p>Man muss also etwas tun, um die Daten in valides JSON zu konvertieren. Was nicht einfach geht, ohne uneval. Bleibt also nur, den String als solchen zu bearbeiten. And here&#8217;s how:<br />
<span id="more-461"></span></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">JSON.<span style="color: #660066;">convertFromUneval</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>u<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">function</span> protect<span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> s.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/./g</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>m<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">'#'</span><span style="color: #339933;">+</span>m.<span style="color: #660066;">charCodeAt</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">16</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #003366; font-weight: bold;">function</span> unprotect<span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> s.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/#([a-f0-9]+)/g</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>m<span style="color: #339933;">,</span>c<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> String.<span style="color: #660066;">fromCharCode</span><span style="color: #009900;">&#40;</span>parseInt<span style="color: #009900;">&#40;</span>c<span style="color: #339933;">,</span><span style="color: #CC0000;">16</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">return</span> u.
    <span style="color: #006600; font-style: italic;">// remove outer braces</span>
    match<span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/^((.*))$/</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span>.
    <span style="color: #006600; font-style: italic;">// protect strings</span>
    replace<span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/(?::&quot;&quot;)|(?::&quot;(.*?)([^\]&quot;))/g</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>m<span style="color: #339933;">,</span>g1<span style="color: #339933;">,</span>g2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">':&quot;'</span><span style="color: #339933;">+</span><span style="color: #009900;">&#40;</span>isUndef<span style="color: #009900;">&#40;</span>g2<span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span><span style="color: #3366CC;">''</span><span style="color: #339933;">:</span>protect<span style="color: #009900;">&#40;</span>g1<span style="color: #339933;">+</span>g2.<span style="color: #660066;">charAt</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">'&quot;'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.
    <span style="color: #006600; font-style: italic;">// prepare unquoted param names using single ticks</span>
    replace<span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/([{,])s*([^:'{,]+?):/g</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>g<span style="color: #339933;">,</span>g1<span style="color: #339933;">,</span>g2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> g1<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;'&quot;</span><span style="color: #339933;">+</span>g2<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;':&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.
    <span style="color: #006600; font-style: italic;">// remove undefined, JSON has no notation of that data type</span>
    replace<span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/([,{])s?'(?:[^']|(?:(?:\\)*\'))*':(void 0)([,}])?/g</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>g<span style="color: #339933;">,</span>g1<span style="color: #339933;">,</span>g2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>g1<span style="color: #339933;">!==</span><span style="color: #3366CC;">'{'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span>g1<span style="color: #339933;">=</span><span style="color: #3366CC;">''</span><span style="color: #339933;">:</span>g1<span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>g1 <span style="color: #339933;">&amp;&amp;</span> g2<span style="color: #339933;">!==</span><span style="color: #3366CC;">'}'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span><span style="color: #3366CC;">''</span><span style="color: #339933;">:</span>g2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.
    <span style="color: #006600; font-style: italic;">// turn single into double tics</span>
    replace<span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/'(.+?)':/g</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>g<span style="color: #339933;">,</span>g1<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">'&quot;'</span><span style="color: #339933;">+</span>g1.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\'/g</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;'&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/&quot;/g</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\&quot;</span>'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">'&quot;:'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.
    <span style="color: #006600; font-style: italic;">// unprotect strings (unwind x sequences: JSON as a Unicode standard doesn't have ASCII escapes)</span>
    <span style="color: #006600; font-style: italic;">// and do that w/o lookbehinds, which would be waaaay to easy</span>
    replace<span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/:&quot;((#[a-f0-9]+)+)&quot;/g</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>m<span style="color: #339933;">,</span>t<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">':&quot;'</span><span style="color: #339933;">+</span>unprotect<span style="color: #009900;">&#40;</span>t<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/(?:(?:\\)*\)*(\x([0-9A-F]{2}))/g</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>m<span style="color: #339933;">,</span>g1<span style="color: #339933;">,</span>g2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>m.<span style="color: #660066;">length</span><span style="color: #339933;">%</span>2<span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span>m<span style="color: #339933;">:</span>m.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span>g1<span style="color: #339933;">,</span>String.<span style="color: #660066;">fromCharCode</span><span style="color: #009900;">&#40;</span>parseInt<span style="color: #009900;">&#40;</span>g2<span style="color: #339933;">,</span><span style="color: #CC0000;">16</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">'&quot;'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
JSON.<span style="color: #660066;">parseUneval</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>u<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> JSON.<span style="color: #660066;">parse</span><span style="color: #009900;">&#40;</span>JSON.<span style="color: #660066;">convertFromUneval</span><span style="color: #009900;">&#40;</span>u<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Ist diesmal sogar kommentiert, da brauch ich gar nichts weiter schreiben. Schön! Man könnte das ganze zwar sogar noch weiter einkürzen, aber wer will das schon &#8211; soll ja auch noch lesbar sein.<br />
Was jetzt noch zu tun bliebe, wäre JSON (oder uneval&#8217;d code) zweifelsfrei erkennen &#8211; aber hier werde ich wohl trial&#038;error nutzen: &#8220;Wenn es sich nicht als JSON parsen lässt, wirds wohl was anderes sein&#8221;. Soll sich doch Spidermonkey damit rumärgern! <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Dieser Schnipsel steht wie der Rest des Affen unter CC-BY-NC-SA. Ergänzungen und Fixes willkommen, sollte z.B. mein Test-Objekt noch seltsame Sachen nicht enthalten!</p>
<p><strong>Update</strong>: Kommentator BenBE hatte doch richtig vermutet: da war noch einiges holprig drin. Ein 316kByte-Datengewusel ist halt doch ein besserer Testcase als etwas konstruiertes <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /><br />
Der String-protect-Teil ist nach wie vor nicht wirklich korrekt, wie jeder einfache Testcase zeigt. Bis zum Beweis des Gegenteils hoffe ich aber, dass es für den Affen reicht.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.martoks-place.de/2010/10/how-to-not-be-evil/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hackfox &#8211; Foxhacks</title>
		<link>http://www.martoks-place.de/2010/09/hackfox-foxhacks/</link>
		<comments>http://www.martoks-place.de/2010/09/hackfox-foxhacks/#comments</comments>
		<pubDate>Mon, 27 Sep 2010 14:30:57 +0000</pubDate>
		<dc:creator>Martok</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Edgemonkey]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Userscripts]]></category>

		<guid isPermaLink="false">http://www.martoks-place.de/?p=453</guid>
		<description><![CDATA[Viele von denen, die hier lesen dürften mein Projekt EdgeMonkey kennen. Für die paar, die es nicht tun: es handelt sich um ein Userscript für Greasemonkey, welches die Entwickler-Ecke verschönert. Jedenfalls: viele der dort eingesetzten Techniken waren schon immer Bleeding Edge, was Userscripts angeht. Deswegen wirds da auch schnell mal blutig, wenn sich irgendwo etwas [...]]]></description>
			<content:encoded><![CDATA[<p>Viele von denen, die hier lesen dürften mein Projekt <a href="http://github.com/martok/edgemonkey">EdgeMonkey</a> kennen. Für die paar, die es nicht tun: es handelt sich um ein Userscript für Greasemonkey, welches die <a href="http://www.entwickler-ecke.de/index.php">Entwickler-Ecke</a> verschönert.<br />
Jedenfalls: viele der dort eingesetzten Techniken waren schon immer Bleeding Edge, was Userscripts angeht. Deswegen wirds da auch schnell mal blutig, wenn sich irgendwo etwas ändert.</p>
<p>So ist das bereits mehrmals passiert &#8211; die neue Sandbox der Greasemonkey 0.8-Reihe war wohl das offensichtlichste. Aber das war ja noch einfach zu umgehen. Richtig spaßig ist das aber erst viel später auf Firefox 4 geworden, welcher mich auch dazu gebracht hat die hier besprochene Thematik mal genauer zu analysieren.<br />
<span id="more-453"></span></p>
<p><strong>Wie alles anfing&#8230;</strong><br />
Grundsätzlich bestehen die Foren der Entwickler-Ecke meistens aus mehreren Frames. Für viele User ist dabei mindestens die Shoutbox ein IFRAME, zusätzlich existiert auf den &#8220;Beitrag beantworten&#8221;-Seiten eine Kurzansicht der letzten paar Beiträge (&#8220;Topicreview&#8221;). Dieser Aufbau stellt Userscripts vor einige Hürden, werden sie doch für jede Seite separat ausgeführt &#8211; ab GM 0.8 eben sogar in einer getrennten Sandbox, die verhindern soll dass sich Webseiten über den GM Chrome-Privilegien holen können. Man möchte aber an einigen Stellen, dass die Scripte zusammenarbeiten können und Funktionen sowie Daten gemeinsam nutzen.</p>
<p><strong>Erster Ansatz</strong><br />
De Grundidee war nun, dass das zuerst geladene Frame (meistens wohl das Hauptfenster) eine Variable <em>EM</em> in das window injeziert. Später geladene Frames suchen in ihrem window.parent dann danach und weisen dieses Objekt einer eigenen Variable zu:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>SOP_ok <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>isEmpty<span style="color: #009900;">&#40;</span>unsafeWindow.<span style="color: #660066;">parent</span>.<span style="color: #660066;">EM</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  window.<span style="color: #660066;">EM</span> <span style="color: #339933;">=</span> unsafeWindow.<span style="color: #660066;">parent</span>.<span style="color: #660066;">EM</span><span style="color: #339933;">;</span>
  unsafeWindow.<span style="color: #660066;">EM</span> <span style="color: #339933;">=</span> EM<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
  window.<span style="color: #660066;">EM</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  unsafeWindow.<span style="color: #660066;">EM</span> <span style="color: #339933;">=</span> EM<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Dies muss man natürlich immer zweimal tun: einmal für das <em>window</em> aus der Sandbox und einmal für das externe <em>unsafeWindow</em>.</p>
<p>Diese Variante hat gut funktioniert, bis Firefox 4 kam. Dieser erzeugt bei der genutzten Funktion evalInSandbox noch einen weiteren Kontext, so dass <em>window</em> nicht mehr das globale Objekt ist. Damit ändert sich das Verhalten des Codes signifikant, so dass nach ausführung des oberen Blocks</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> foo<span style="color: #339933;">=</span> EM<span style="color: #339933;">;</span></pre></div></div>

<p> nicht funktionieren wird &#8211; <em>EM</em> ist <em>undefined</em>, <em>window.EM</em> wäre es nicht.</p>
<p>Damit war die bisherige Technologie ein Fall für gründliches Überdenken. Mit dem netten Nebeneffekt, dass gleich noch ein weiterer Fehler gefunden wurde. Leider ein konzeptioneller, denn diese Methode hat ziemliche Probleme damit, dass das Topicreview auch eine Pagehacks-Instanz hat. Diese überschreibt dann die der Hauptseite. Nicht gut das ist. Transparenter du denken musst, junger Padawan!</p>
<p><strong>How it should have worked&#8230;</strong><br />
Dann ist mir etwas eingefallen, was ich vor der Lektüre von Crockford&#8217;s <a href="http://www.amazon.de/dp/0596517742/">The Good Parts</a> zwar wusste, aber nicht wirklich angewendet hatte: JavaScripts Prototypische Vererbung. In a nutshell bedeutet diese, dass ein Objekt zuerst nachsieht, ob es eine Eigenschaft selbst enthält, dann bei seinem Protoypten, dann bei dessen Prototypen etc., bis Object() dann keinen mehr hat.<br />
Dies kann man nutzen, um bestimmte Eigenschaften global zu machen und andere Privat zu halten. Praktischerweise lässt einen die Mozilla-JS-Engine auch an das dafür verwendete <em>__proto__</em>-Pseudoproperty ran, so dass man schreiben kann (nicht wörtlich so, aber die Idee kommt so besser rüber als im Orignalcode, welcher noch Code enthält um auf Fertigstellung zu warten):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> newEM <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>SOP_ok <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>isEmpty<span style="color: #009900;">&#40;</span>unsafeWindow.<span style="color: #660066;">parent</span>.<span style="color: #660066;">EM</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  newEM.__proto__ <span style="color: #339933;">=</span> unsafeWindow.<span style="color: #660066;">parent</span>.<span style="color: #660066;">EM</span>.__proto__<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
  newEM.__proto__ <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
window.<span style="color: #660066;">EM</span> <span style="color: #339933;">=</span> newEM<span style="color: #339933;">;</span>
unsafeWindow.<span style="color: #660066;">EM</span> <span style="color: #339933;">=</span> newEM<span style="color: #339933;">;</span></pre></div></div>

<p>Dann gilt für jedes Frame:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">EM.__proto__.<span style="color: #660066;">foo</span><span style="color: #339933;">=</span><span style="color: #CC0000;">42</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// ist danach überall sichtbar</span>
EM.<span style="color: #660066;">bar</span><span style="color: #339933;">=</span><span style="color: #CC0000;">23</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// nur dieses Frame hat die Variable. Andere könnten EM.bar auch als 5 deklarieren!</span></pre></div></div>

<p>Womit das Ziel erreicht wäre: es ist möglich, Felder zwischen Frames zu teilen. Es ist aber auch möglich, private Felder zu deklarieren.<br />
Nun funktioniert dieser Ansatz sehr schön direkt im Browser, als ClientSide-Script. Aber als Greasemonkey-Script&#8230; nunja, ich weiß nicht <em>was</em> da passiert, aber es ist etwas anderes. Wer möchte, kann sich das im <a href="http://www.martoks-place.de/test/js_emtest/">Proof Of Concept</a> ansehen.</p>
<p><strong>&#8230; and what we did instead</strong><br />
Nun ist das Problem nicht ganz unbekannt, weswegen mal jemand den <a href="http://wiki.greasespot.net/Content_Scope_Runner">Content Scope Runner</a> erfunden hat. Keine Rocket Surgery, aber schon soweit genial dass einfach der Code ins DOM injiziert wird und damit im Content Scope läuft. Nett, aber wir brauchen ja die Chrome-Privilegien die uns GM gibt.</p>
<p>Die Lösung ist nun, beide Techniken zu kombinieren: Die Objekt-Verlinkung passiert im Content Scope, der Rest des Scripts läuft wie gewohnt als Userscript. Dies erfordert etwas mehr Aufwand, da die jeweiligen Warteschleifen natürlich auch mit gebaut werden müssen.</p>
<p>Der Loader an sich wird relativ einfach, da alles in 2 Unterfunktionen gemacht wird. <em>Env</em> wird vorher mit Informationen über die Umgebung gefüllt, <em>Env.parentName</em> enthält dann Bezeichner wie <em>&#8220;window.parent&#8221;</em>.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>Env.<span style="color: #660066;">isSOPPass</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    injectInitCode<span style="color: #009900;">&#40;</span>Env.<span style="color: #660066;">parentName</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    waitForObject<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    injectInitCode<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    waitForObject<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>injectInitCode tut nun genau das: einen Code generieren, der bei Ausführung ein neues EM-Objekt erstellt und entweder mit leerem <em>__proto__</em> oder dem <em>__proto__</em> des übergebenen Objektes verknüpft. Sollte etwas übergeben worden sein, muss natürlich gewartet werden, bis das Objekt dann auch verfügbar ist. Dies passiert im Conent Scope, damit funktioniert der Code!</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">function</span> injectInitCode<span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> code<span style="color: #339933;">=</span><span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">'(function(par){'</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">' var newEM = {};'</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">' if (par) {'</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">'  var wait=setTimeout(function() {'</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">'   if (typeof par.EM!==&quot;undefined&quot;) {'</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">'    clearInterval(wait);'</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">'    newEM.__proto__ = par.EM.__proto__;'</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">'    window.EM = newEM;'</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">'   }'</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">'  }, 10);'</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">' } else {'</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">'  newEM.__proto__ = {};'</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">'  window.EM = newEM;'</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">' } '</span><span style="color: #339933;">;</span>
    code<span style="color: #339933;">+=</span><span style="color: #3366CC;">'})('</span><span style="color: #339933;">+</span>p<span style="color: #339933;">+</span><span style="color: #3366CC;">')'</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003366; font-weight: bold;">var</span> script<span style="color: #339933;">=</span>document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'script'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    script.<span style="color: #660066;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'type'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'text/javascript'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    script.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> code<span style="color: #339933;">;</span>
    document.<span style="color: #660066;">documentElement</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>script<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    document.<span style="color: #660066;">documentElement</span>.<span style="color: #660066;">removeChild</span><span style="color: #009900;">&#40;</span>script<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Nun will aber der Rest des Scripts sein gemütliches Chrome Scope nicht verlassen&#8230; also muss die weitere Initialisierung so lange verzögert werden, biss das Content-Script unser Objekt verknotet hat &#8211; danach können wir nach belieben drauf operieren. Auch hier wieder die übliche setInterval-Methode, die nach wenigen (naja, so schnell ist Firefox ja nicht&#8230;) Versuchen ein <em>EM</em>-Objekt im <em>unsafeWindow</em> vorfindet und nach ein paar Scoping-Würgarounds dieses überall bekannt gemacht hat. Wenn das der Fall ist, können noch schnell globale Objekte erstellt werden (hier nur symbolhaft) und die eigentliche, seitenspezifische Initialisierung kann stattfinden. Wie sich vermuten lässt, passiert dies in <em>startup()</em>. Die ist dann auch so uninteressant und total by-the-book, dass sie hier nicht mehr Gegenstand ist.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  <span style="color: #003366; font-weight: bold;">function</span> waitForObject<span style="color: #009900;">&#40;</span>buildglobals<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> wait<span style="color: #339933;">=</span>setInterval<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> unsafeWindow.<span style="color: #660066;">EM</span><span style="color: #339933;">!==</span> <span style="color: #3366CC;">&quot;undefined&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        clearInterval<span style="color: #009900;">&#40;</span>wait<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        window.<span style="color: #660066;">EM</span> <span style="color: #339933;">=</span> unsafeWindow.<span style="color: #660066;">EM</span><span style="color: #339933;">;</span>
        EM <span style="color: #339933;">=</span> window.<span style="color: #660066;">EM</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Für Fx4</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>buildglobals<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          EM.__proto__.<span style="color: #660066;">Ajax</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> AJAXObject<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #006600; font-style: italic;">//awesome, we're done</span>
        startup<span style="color: #009900;">&#40;</span>EM<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">20</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Mein Fazit</strong><br />
Also zuerstmal: meine Aussage steht noch, dass man mit JS wirklich alles lösen kann. Glück gehabt <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
Was lernen wir aus dem Ganzen: man sollte immer mal Out Of The Box denken, gerade wenn man eine Sandbox verlassen will. Um auf diese Idee zu kommen brauchte es immerhin einen <a href="http://github.com/greasemonkey/greasemonkey/issues/issue/1197">Bug-Eintrag</a> bei Greasemonkey. Ich bin immer noch überzeugt, dass das Verhalten von GM hier ein Bug ist. Wenn auch keiner der Sorte &#8220;geht nicht&#8221;, sonder &#8220;geht anders nicht als es nicht gehen sollte&#8221;.</p>
<p>Wichtigste Erkenntnis dürfte aber sein, dass man es mit Security nicht übertreiben sollte. Nicht immer, wenn etwas sicherer wird, wird es auch besser. Ohne die extrem fiese Sandbox müsste ich nichts Injecten und das Window hätte es nicht so leicht, rauszukriegen dass hier ein Edgemonkey am Werk ist. Dies sollte man wohl bei jeder Art Software-Entwicklung bedenken.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.martoks-place.de/2010/09/hackfox-foxhacks/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Aus dem Maschinenraum</title>
		<link>http://www.martoks-place.de/2010/04/aus-dem-maschinenraum/</link>
		<comments>http://www.martoks-place.de/2010/04/aus-dem-maschinenraum/#comments</comments>
		<pubDate>Fri, 30 Apr 2010 21:55:41 +0000</pubDate>
		<dc:creator>Martok</dc:creator>
				<category><![CDATA[Intern]]></category>
		<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://www.martoks-place.de/?p=415</guid>
		<description><![CDATA[Heute mal wieder so ein paar schöne WTF-Momente gehabt. Das ist zwar bei WordPress nix neues, weswegen ich heute auch mit Serendipity experimentiert hab. Das ist zwar toll, aber die Permalinkstruktur gefällt mir nicht wirklich, und der Import hat auch nicht geklappt (konsquent falscher Zeichensatz). Ist aber hier nicht das Thema Was mich heute zum [...]]]></description>
			<content:encoded><![CDATA[<p>Heute mal wieder so ein paar schöne WTF-Momente gehabt. Das ist zwar bei WordPress nix neues, weswegen ich heute auch mit Serendipity experimentiert hab. Das ist zwar toll, aber die Permalinkstruktur gefällt mir nicht wirklich, und der Import hat auch nicht geklappt (konsquent falscher Zeichensatz). Ist aber hier nicht das Thema <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Was mich heute zum wiederholten Mal verwundert hat, sind spontan nicht mehr funktionierende PHP-Skripte.<br />
PHPExec meinte doch eben völlig unmotiviert (&#8220;I didn&#8217;t touch anything! *looks away*&#8221;), mir einen Fehler zu melden, eine Variable wäre nicht initialisiert. Das war sie zwar wirklich nicht, aber das Skript lief ohne Unterschied literally seit Jahren. Fehlerfrei. Ich hab eine glaubhafte Versicherung meines Hosters, dass er auch nix gemacht hat&#8230;</p>
<p>Sowas hatte ich schonmal: ein Datenbank-Wrapper, der schon Wochenlang genutzt wurde, meinte auf einmal, Bind-Variablen nicht mehr richtig übergeben zu wollen. Und Überraschung: laut Manual hätte es nie funktionieren können.</p>
<p>Hatte schonmal jemand ähnliche Effekte? Plötzlich veränderliches Verhalten ist etwas, was ich mir so gar nicht erklären kann.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.martoks-place.de/2010/04/aus-dem-maschinenraum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Optimierung mal anders</title>
		<link>http://www.martoks-place.de/2010/04/optimierung-mal-anders/</link>
		<comments>http://www.martoks-place.de/2010/04/optimierung-mal-anders/#comments</comments>
		<pubDate>Sun, 11 Apr 2010 00:49:55 +0000</pubDate>
		<dc:creator>Martok</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[gcc]]></category>
		<category><![CDATA[Optimierung]]></category>

		<guid isPermaLink="false">http://www.martoks-place.de/?p=399</guid>
		<description><![CDATA[Aus der Kategorie, &#8220;Spaß am Gerät, den man lieber nicht hätte&#8221;: Amoklaufende Optimierung im GCC. Man lese folgenden Code, der alternierend ein LCD mit Zahlen, Buchstaben und &#8220;nichts&#8221; füllt: while &#40;1&#41; &#123; for &#40;unsigned char k=0;k&#60;4;k++&#41; &#123; LCD_setCursorPos&#40;k,0&#41;; LCD_write&#40;&#34;1234567890123456&#34;&#41;; &#125; delay&#40;250&#41;; LCD_clear&#40;&#41;; delay&#40;250&#41;; for &#40;unsigned char k=0;k&#60;4;k++&#41; &#123; LCD_setCursorPos&#40;k,0&#41;; LCD_write&#40;&#34;abcdefghijklmnop&#34;&#41;; &#125; delay&#40;250&#41;; &#125; What could [...]]]></description>
			<content:encoded><![CDATA[<p>Aus der Kategorie, &#8220;Spaß am Gerät, den man lieber nicht hätte&#8221;: Amoklaufende Optimierung im GCC.</p>
<p>Man lese folgenden Code, der alternierend ein LCD mit Zahlen, Buchstaben und &#8220;nichts&#8221; füllt:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> k<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>k<span style="color: #339933;">&lt;</span><span style="color: #0000dd;">4</span><span style="color: #339933;">;</span>k<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>  <span style="color: #009900;">&#123;</span>
		LCD_setCursorPos<span style="color: #009900;">&#40;</span>k<span style="color: #339933;">,</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		LCD_write<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;1234567890123456&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	delay<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">250</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	LCD_clear<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	delay<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">250</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> k<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>k<span style="color: #339933;">&lt;</span><span style="color: #0000dd;">4</span><span style="color: #339933;">;</span>k<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>  <span style="color: #009900;">&#123;</span>
		LCD_setCursorPos<span style="color: #009900;">&#40;</span>k<span style="color: #339933;">,</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		LCD_write<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;abcdefghijklmnop&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	delay<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">250</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>What could possibly go wrong <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_question.gif' alt=':?:' class='wp-smiley' /> </p>
<p>Gut, wir kennen ja Murphy: Alles, was schief gehen kann, geht schief. Und wenn schon der Code kaum Fehlerpotential hat, muss zwangsläufig der Compiler seinen Beitrag dazu leisten <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_exclaim.gif' alt=':!:' class='wp-smiley' /> </p>
<p>Genau das hat er dann auch getan&#8230; erstmal äußerte sich das ganze dann darin, dass wider erwarten nur Zahlen, leere Seite und wieder Zahlen kamen. Und dabei die Seite mit den Zahlen irgendwie &#8220;zu lang&#8221; zu sehen war.<br />
Was war also los?<br />
Wie in Blick in das praktischerweise im Makefile angeforderte Extended Listing verrät, ist avr-gcc der Meinung, die beiden Schleifen würden das Gleiche machen, und kombiniert die in eine Schleife. Durch Ausprobieren anderer Optimierungsstufen zwischen -Os und -O1 kann man dann gcc immerhin überreden, nicht mehr beides in einer Schleife zu erledigen, sondern die zweite komplett zu ignorieren (toll!)&#8230; auch nicht ganz das Wahre. -O0 erzeugt Warnungen in &lt;util/delay.h&gt;, fällt also leider aus.</p>
<p>Die einzige mir bekannte Lösung ist das verlegen der beiden Schleifen in separate Methoden:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> test1<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> k<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>k<span style="color: #339933;">&lt;</span><span style="color: #0000dd;">4</span><span style="color: #339933;">;</span>k<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>  <span style="color: #009900;">&#123;</span>
		LCD_setCursorPos<span style="color: #009900;">&#40;</span>k<span style="color: #339933;">,</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		LCD_write<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;1234567890123456&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	delay<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">250</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> test2<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> k<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>k<span style="color: #339933;">&lt;</span><span style="color: #0000dd;">4</span><span style="color: #339933;">;</span>k<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>  <span style="color: #009900;">&#123;</span>
		LCD_setCursorPos<span style="color: #009900;">&#40;</span>k<span style="color: #339933;">,</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		LCD_write<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;abcdefghijklmnop&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	delay<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">250</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	test1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	LCD_clear<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	delay<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">250</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	test2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Gut, man muss eingestehen, der gcc hier ist schon etwas (avr-gcc (WinAVR 20080610) 4.3.0) älter. Das ist in einigen Kompatibilitätsproblemen mit anderen Projekten geschuldet, die sich auf ein bestimmtes Verhalten verlassen (hey, ich hab das nicht erfunden, ok?)<br />
Kann also sein, dass das mittlerweile nicht mehr so ist. Aber trotzdem toll, dass so ein Bug es tatsächlich in eine Produktiv-Version schafft. Ist das kein Testcase? Naja, gcc halt&#8230; </p>
]]></content:encoded>
			<wfw:commentRss>http://www.martoks-place.de/2010/04/optimierung-mal-anders/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Too much standard compliance</title>
		<link>http://www.martoks-place.de/2009/03/too-much-standard-compliance/</link>
		<comments>http://www.martoks-place.de/2009/03/too-much-standard-compliance/#comments</comments>
		<pubDate>Sun, 22 Mar 2009 18:01:49 +0000</pubDate>
		<dc:creator>Martok</dc:creator>
				<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Standards]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web-Design]]></category>

		<guid isPermaLink="false">http://www.martoks-place.de/?p=231</guid>
		<description><![CDATA[Hi! Ich hab mich hier und anderswo ja schon öfter drüber beschwert, dass sich gewisse Browser nicht an Standards halten. &#8216;Gewisse&#8217; war dabei meist der IE Nun, offenbar tritt auch mal das Gegenteil auf&#8230; aber zum Anfang. Ein Uber-1337-Web2.0-Projekt benutzt unter anderem DOM-Manipulation, dabei werden auch &#60;style>-Nodes injected. Und zwar unterhalb des &#60;body>s. Das funktioniert [...]]]></description>
			<content:encoded><![CDATA[<p>Hi!</p>
<p>Ich hab mich hier und anderswo ja schon öfter drüber beschwert, dass sich gewisse Browser nicht an Standards halten. &#8216;Gewisse&#8217; war dabei meist der IE <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Nun, offenbar tritt auch mal das Gegenteil auf&#8230; aber zum Anfang.</p>
<p>Ein Uber-1337-Web2.0-Projekt benutzt unter anderem DOM-Manipulation, dabei werden auch &lt;style>-Nodes injected. Und zwar unterhalb des &lt;body>s. Das funktioniert prima im Firefox(3) und in Opera, aber NICHT in IE und Safari/Webkit/KHTML/whatever. Woran liegt das? Nun, laut Standard darf ein &lt;style>-Node nur unterhalb von &lt;head> stehen. Meines Wissens sind Firefox und Opera die einzigen, die das ignorieren und die Dinger auch anderswo parsen. Schade eigentlich, denn meine so einfache Lösung wird jetzt durch Sonderbehandlung für die, die sich an Standards halten wieder komplizierter.</p>
<p>Was mich zum Fazit bringt: auch das W3C hat die Weisheit nicht gepachtet, für mich ist dieser Standard inkonsequent: die an sich ähnlich auszulegenden &lt;script>s darf man schließlich auch überall verwenden.</p>
<p>Wer aber ne gute Idee hat, wie man das so hinkriegt, dass die Styles auch da geparst werden, oder wer mir sagen kann wie ich in IE/Webkit DOM-Änderungen Hooken kann (brauch ich fürs aufräumen, wenn ich doch in den &lt;head> injecten muss), der kriegt ein Bienchen und eine About-Erwähnung <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>cu,<br />
Martok</p>
]]></content:encoded>
			<wfw:commentRss>http://www.martoks-place.de/2009/03/too-much-standard-compliance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress: wpautop(), der einfachere Weg</title>
		<link>http://www.martoks-place.de/2008/08/wpautop/</link>
		<comments>http://www.martoks-place.de/2008/08/wpautop/#comments</comments>
		<pubDate>Thu, 14 Aug 2008 17:22:51 +0000</pubDate>
		<dc:creator>Martok</dc:creator>
				<category><![CDATA[Intern]]></category>
		<category><![CDATA[Programmierung]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web-Design]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://www.martoks-place.de/?p=143</guid>
		<description><![CDATA[Hallo! Ich melde mich mal wieder, diesmal mit etwas relativ wichtigem. Vor kurzem wurde WordPress 2.6 freigegeben, im Zuge des Updates musste ich mal wieder den wpautop()-Fix einspielen. Dabei sind mir einige Unzulänglichkeiten aufgefallen, unter anderem dass er sinnlos kompliziert ist Die neue Version kommt mit grade mal 7 neuen und einer geänderten Zeile aus. [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo!</p>
<p>Ich melde mich mal wieder, diesmal mit etwas relativ wichtigem. Vor kurzem wurde WordPress 2.6 freigegeben, im Zuge des Updates musste ich mal wieder den <a href="http://www.martoks-place.de/2007/07/wordpress-wpautop-bug-gefixt/">wpautop()-Fix</a> einspielen.</p>
<p>Dabei sind mir einige Unzulänglichkeiten aufgefallen, unter anderem dass er sinnlos kompliziert ist <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Die neue Version kommt mit grade mal 7 neuen und einer geänderten Zeile aus.</p>
<p>Hier die Diff (wir sind wieder in wp-includes/formatting.php):</p>

<div class="wp_syntax"><div class="code"><pre class="diff" style="font-family:monospace;"><span style="color: #440088;">@@ -65,10 +65,15 @@</span>
 <span style="">&#125;</span>
&nbsp;
 function wpautop<span style="">&#40;</span>$pee, $br = <span style="">1</span><span style="">&#41;</span> <span style="">&#123;</span>
<span style="color: #00b000;">+	$preserving = strpos<span style="">&#40;</span>$pee, '&lt;preserve&gt;'<span style="">&#41;</span> !== false;</span>
<span style="color: #00b000;">+	if <span style="">&#40;</span>$preserving<span style="">&#41;</span> <span style="">&#123;</span></span>
<span style="color: #00b000;">+		$pee = preg_replace_callback<span style="">&#40;</span>'!&lt;preserve&gt;<span style="">&#40;</span>.*?<span style="">&#41;</span>&lt;/preserve&gt;!is', create_function<span style="">&#40;</span>'$matches', 'return &quot;&lt;revert&gt;&quot;.base64_encode<span style="">&#40;</span>$matches<span style="">&#91;</span><span style="">1</span><span style="">&#93;</span><span style="">&#41;</span>.&quot;&lt;/revert&gt;&quot;;'<span style="">&#41;</span>, $pee<span style="">&#41;</span>;</span>
<span style="color: #00b000;">+	<span style="">&#125;</span></span>
<span style="color: #00b000;">+</span>
 	$pee = $pee . &quot;n&quot;; // just to make things a little easier, pad the end
 	$pee = preg_replace<span style="">&#40;</span>'|&lt;br /&gt;s*&lt;br /&gt;|', &quot;nn&quot;, $pee<span style="">&#41;</span>;
 	// Space things out a little
<span style="color: #991111;">-	$allblocks = '<span style="">&#40;</span>?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h<span style="">&#91;</span><span style="">1</span>-<span style="">6</span><span style="">&#93;</span>|hr<span style="">&#41;</span>';</span>
<span style="color: #00b000;">+	$allblocks = '<span style="">&#40;</span>?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h<span style="">&#91;</span><span style="">1</span>-<span style="">6</span><span style="">&#93;</span>|hr|revert<span style="">&#41;</span>';</span>
 	$pee = preg_replace<span style="">&#40;</span>'!<span style="">&#40;</span>&lt;' . $allblocks . '<span style="">&#91;</span>^&gt;<span style="">&#93;</span>*&gt;<span style="">&#41;</span>!', &quot;n$1&quot;, $pee<span style="">&#41;</span>;
 	$pee = preg_replace<span style="">&#40;</span>'!<span style="">&#40;</span>&lt;/' . $allblocks . '&gt;<span style="">&#41;</span>!', &quot;$1nn&quot;, $pee<span style="">&#41;</span>;
 	$pee = str_replace<span style="">&#40;</span>array<span style="">&#40;</span>&quot;rn&quot;, &quot;r&quot;<span style="">&#41;</span>, &quot;n&quot;, $pee<span style="">&#41;</span>; // cross-platform newlines
<span style="color: #440088;">@@ -99,6 +104,9 @@</span>
 	$pee = preg_replace<span style="">&#40;</span> &quot;|n&lt;/p&gt;$|&quot;, '&lt;/p&gt;', $pee <span style="">&#41;</span>;
 	$pee = preg_replace<span style="">&#40;</span>'/&lt;p&gt;s*?<span style="">&#40;</span>' . get_shortcode_regex<span style="">&#40;</span><span style="">&#41;</span> . '<span style="">&#41;</span>s*&lt;/p&gt;/s', '$1', $pee<span style="">&#41;</span>; // don't auto-p wrap shortcodes that stand alone
&nbsp;
<span style="color: #00b000;">+	if <span style="">&#40;</span>$preserving<span style="">&#41;</span> <span style="">&#123;</span></span>
<span style="color: #00b000;">+		$pee = preg_replace_callback<span style="">&#40;</span>'!&lt;revert&gt;<span style="">&#40;</span>.*?<span style="">&#41;</span>&lt;/revert&gt;!is', create_function<span style="">&#40;</span>'$matches', 'return base64_decode<span style="">&#40;</span>$matches<span style="">&#91;</span><span style="">1</span><span style="">&#93;</span><span style="">&#41;</span>;'<span style="">&#41;</span>, $pee<span style="">&#41;</span>;</span>
<span style="color: #00b000;">+	<span style="">&#125;</span></span>
 	return $pee;
 <span style="">&#125;</span></pre></div></div>

<p>Bei der Gelegenheit habe ich den Tag von <em>&lt;nowpautop></em> in <em>&lt;preserve></em> geändert, hier gegebenfalls betreffende Posts/Seiten anpassen.</p>
<p>Die angesprochenen anderen Unzulänglichkeiten hatten damit zu tun, dass nur <em>p</em> und <em>br</em>-Tags verhindert wurden. Alles andere wurde trotzdem munter verändert. Jetzt ist das Verhalten das erwartete: per php generierter HTML-Code wird <strong>genau so</strong> übernommen wie er aus dem Interpreter kommt. Technisch liegt das daran, dass ich jetzt nicht mehr einzelne Zeichen schütze, sondern alles, indem der Code base64-Codiert vor wpautop() versteckt wird.</p>
<p>Viel Spaß damit <img src='http://www.martoks-place.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
Martok</p>
]]></content:encoded>
			<wfw:commentRss>http://www.martoks-place.de/2008/08/wpautop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

