PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : die Config: Formate/Ideen/Probleme/...



dumm'
27.04.2002, 19:10
Da die Config an sich den groessten Teil der Arbeit darstellt, werden hier gesondert, weil es doch einiges ist, Dinge der Config besprochen.

dumm'
27.04.2002, 19:15
Einbinden von externen Dateien in eine lokale Config-Datei

Das einbinden (include) von externen Datei in eine lokale
Datei kann so aufgefasst werden, als wenn man eine Datei in
eine andere von Hand einfuegt. Ein Platzhalter gibt dabei dann
die Position an, an welcher der Inhalt der Datei eingesetzt
werden soll. Dieses Dokument soll beschreiben, wie dieser
Vorgang von statten geht und wie er genutzt werden kann.

Es gibt zwei moegliche Anordnungen unter beruecksichtigung der
Struktur der Config. Einmal waere das als Teil der Datei und
einmal als stand-only Argument. Beide Moeglichkeiten haben die
selbe Syntax, aber bedeuten fuer die Struktur und die Methode
zum parsen der fortlaufenden Config etwas voellig
verschiedenes.

Das Einbinden als Teil der Datei kann man sich, wenn man den c
Praeprozessor kennt, als das Einbinden einer header Datei
vorstellen. Sollte man dies nicht kennen, reicht das Beispiel
von oben vermutlich aus. An der stelle, wo sich die Anweisung
zum Einbinden der Datei befindet wird eine Datei (virtuell)
eingefuegt. Das parsen der Datei laeuft dann an dieser Stelle
nicht mit der naechsten Anweisung der lokalen, sondern mit der
naechsten Anweisung der eingebundenen Datei fort, bis das
parsen dieser Datei abgeschlossen ist.
Um eine Datei so einzubinden, darf diese Anweisung ueberall
stehen, ausser in Eigenschaftsnamen und den Argumenten. Ob von
Bloecken, oder Eigenschaften selbst spielt dabei keine Rollte.
Grundsaetlich gilt, die Anweisung muss als erstes
non-whitespace in der Zeile stehen und darf nur von
Kommentaren und whitespaces bis zum Ende der Zeile gefolgt
werden. Alles andere ist Falsch! Etwa Argumente duerfen nicht
zu einer solchen Anweisung in dieser Form kommen, was auch bei
kuerzerer Ueberlegung keinen Sinn ergeben wird.

Das Einbinden als stand-only Argument bedeutet, dass die
einzubindene Datei den Inhalt des Arguments darstellt, statt
welchem die Anweisung dort steht. Damit ergibt sich die Regel,
dass die Anweisung nur als Argument einer Eigenschaft, oder
eines Blocks vorhanden sein darf. Vor und nach diesem Argument
duerfen allerdings Argumente vorausgehen und folgen. Ebenso
weitere include Anweisungen. Lediglich der Blockname ist
Pflicht. Dieser darf, obwohl intern auch als Argument
behandelt nicht allein eingebunden werden. Sollte eine
Eigenschaft samt Argumenten einbezogen werden sollen, kann
dies durch das vorige Verfahren bewerkstelligt werden.

Die Syntax der include Anweisung lautet als regulaerer Perl
Ausdruck:

/W*\{\W*method:command:path\W*\}

method:
Die methode gibt an, auf welchem Weg die Datei bezogen
werden soll. Sie kann angeben, die Datei von einem der
lokalen Datentraeger zu oeffnen, oder diese
Beispielsweise von einem HTTP Server zu beziehen.

command:
Der command gibt eine, oder mehrere Anweisungen an,
die Ausgefuehrt werden sollen, bevor die Datei
eingebunden wird. command wird auf eine extra lokale
Kopie, oder die Kopie einer nicht lokalen Datei
ausgefuehrt. Einsetztbarkeit beispielsweise bei
gepackten Dateien, die vor dem Einbinden erst entpackt
werden muessen. Da diese Angabe eine enorme
Sicherheitsluecke darstellen kann, sollten mehrere
Mechanismen einmal die Benutztung allg. und die
Benutzung im speziellen kontrollieren.
Um auch Befehlszeilen zu unterstuetzen, wird das '$'
als platzhalter beim Ausfuehren fuer Datei benutzt,
auf die der command angewendet wird.

path:
Path gibt je nach method den Pfad an, von welchem die
Datei bezogen werden soll. Fuer lokale Dateien, wessen
Pfad auf unix und windows Maschinen unterschiedlich
ist, wird dieser zu gunsten von unix bei windows
Maschinene intern auf dessen Dateisystempfade
emuliert. Dies kann allerdings vom Callback abhaengig
gemacht werden, welche die Datei letztendlich bezieht.

ich erhoff mir durch diese art des einbindens eine einfache aber funktionelle und schnelle methode dateien einzubinden. Schneller als bei HTML Stylesheets und sonstwas *g*.

Wenn ihr was nicht versteht, oder verbesserungsvorschlaege habt ... postet. :)

stefan

dumm'
04.05.2002, 14:31
----------------------------
revision 1.4
date: 2002/05/04 13:42:10; author: stefan; state: Exp; lines: +751 -245
include anweisung und byte ausdruecke komplett implementiert (conf_parse_byte_expr in conf_getvblock; conf_parse_include_cmd in conf_parse_line). conf_parse_line komplett umgeschrieben, conf parse_block ebenso. Die cleanups sind selbstverstaendlich auch drin, der include und byte anweisungen.
----------------------------
revision 1.3
date: 2002/04/27 18:41:50; author: stefan; state: Exp; lines: +36 -2
conf_perror implementiert, die dazu dient die cerrno Fehlercodes in eine fuer menschen auch verstaendliche Darstellungsform (Text) zu bringen. ;)
----------------------------
revision 1.2
date: 2002/04/27 14:02:59; author: stefan; state: Exp; lines: +197 -794
Funktion zum parsen von Byte Ausdruekcen eingebaut (conf_parse_byte_expr) und Dokumentation und Fehlerhafte Funktionen rausgenommen
----------------------------

fazit:
die byte anweisungen ... naja ... sind noetig, kann man aber viel falsch machen, wenn man nicht aufpasst. :|
die include anweisung ist eigentlich super praktisch. Sowas fehlt imo in html. Eine datei waehrend des parsens einfach virtuell einzubinden. Man koennte konstante teile einer datei ganz einfach aus dem hdd cache laden, ... praktisch im moment, weil ich einfach, wenn ich die geschw. testen will, die tiefe der include-verschachtelungen hochsetzte und eine rekurive config nehm. ;)

stefan

dumm'
14.05.2002, 18:31
ich muss dringend was ueberlegen, wie ich die config ausles. Das ist irgendwie immernoch mein hauptproblem. ich komm da nicht voran und immer wieder treten neue probleme auf, und irgendwie immer die gleichen. Das problem besteht darin, dass ich keinen bock hab fuere jeden block (category,forum,topic), jeweils eine funktion fuer eine funktion zu schreiben (preprocess,free,compare,...) und das dann fuer backend und jconfig.

hmm. zumindest die proprocessing sachen muesste ich in die conf bekommen. aufgaben waeren dabei einmal substitution von symbolischen durch numerische ("true" gegen 1 z.b.) werte und bestimmte dinge einfach waehrend der laufzeit an aktueller position zu erstellen. (categorien,foren, oder sonstwas. oder einfach werte zu setzten, zur initialisierung). das dumme an der sache nur, dass die bisherige art, ueber das format zu ueberladen wird.
bisher wird immer das format und dann optionale angaben wie blockgroesse, bytejumps, ... uebergeben. wenn dann noch die anderen sachen kommen, blickt das niemand mehr. ;)

hab schon ueberlegt eine struktur dazu zu verwenden ... nur ... muesste die so konzipiert werden, dass diese einfach und ueberhaupt initialisiert werden. vielleicht auch direkt das format in dem sinne abzuloesen und nur auf strukturen ueberzugehen.

#define READ_OUT "<block",/*arg1*/{"%s",callback,...subs},\
..args,">",...

ausserdem besteht ein performance problem in der funktion zum auslesen der zeilen. bei tiefen verschachtelungen werden ruft sich die funktion immer auf die gesamte tiefe des stacks fuer die includes auf. und das kann enorm weit sein!! *g*


----------------------------------------------
6508500 conf_parse_line [4]
0.00 0.00 1/13014 conf_parse [2]
1.97 0.22 13013/13014 conf_parse_block [3]
[4] 98.5 1.97 0.22 13014+6508500 conf_parse_line [4]
0.19 0.00 6521514/6521514 vec_init [5]

bei nur 1000 rekuriven includes. ich habs bisher vo geloesst, das ich einen statusstruktur jeweils uebergeben hab und die jeweils die infos fuer die naechst tiefere verschachtelung hat. NUR ... es kann probleme geben weil die erste struktur aus einer der struktur statischen variable geholt wird, sofern gegeben, was probleme beim lesen aus zwei config gleichzeitig geben kann. naja ... aber man kann sie uebergeben. ;) nur gibt es probleme wenn dies funktionsuebergreifend tun moechte, wie ich es auch tue, und nicht den ansporn fand die status struktur durch alle funktion zu tragen. deshalb der statische ansatz. aber da ich nun eine variable auf den tiefsten eintrag im include stack brauch laesst es sich wohl nicht vermeiden, dass ich die config struktur drin hatte, wie es bisher nicht der fall war. das einzige was mir daran nicht gefaellt ist aber, dass ich die funktion bisher auch zum lesen der formatangaben beim auslesen benutzt hab und dazu eine config nun braeuchte, welche allerdings leer bleiben wuerde. aber komisch siehts aus. :) aber wenn ich jetzt das von oben aendern wuerde fuer das auslesen, wurde ich so dieses probleme elegant umgehen. *g* :)

hm ... irgendwo war nochein fehler *vergessenhab*

aber das sollte denk ich mein wochenende auch fuellen. und wenn nicht ... gibt genug zu tun.

stefan

Smartie
14.05.2002, 21:17
ich kann nur wiederholen, was schon mal gesagt wurde :)
XML und XML-Parser :)
Dafür müsstest du halt dann deine Datei neu aufbauen, wäre aber für nachfolger die alles verstehen wollen leichter

dumm'
26.05.2002, 18:34
leichter wuerde es denen glaube ich nicht machen. Wenn spaeter alles sauber dokumentiert ist, wird das wohl nicht viel anders sein. Eher einfach weil die conf nicht so viele Funktionen hat, wie XML. :) An der config (dem parser), wenn sie fertig ist, muesste sie ja nichtmehr veraendert werden. Der XML Parser ja auch nicht. Und fuer mich, ist es eine gute Erfahrung so gesehen. Denn am schreiben der config, hab ich imo bisher am meisten gelernt. Besonders, dass man lieber 2, oder 2 mal drueber nachdenken sollte, was man tut, bevor man es implementiert und dass auch nicht immer alles so laeuft, wie ich es gern haette. ;)

Ausserdem hat eine eigene configsyntax und struktur den grossen vorteil, dass man diese viel besser, auch direkt durch aendern selbiger optimieren koennte! Die alte version lief ja einige Zeit auf dem JBB und hat dort unmengen an traffic produziert. Und wenn man dies dann auf das bubo, oder ein anderes groesseres board umrechnet ... *winkewinke*. Auch wenn ich mir anguck, wie sich mein styl veraendert hat. Inzwischen hab ich mich auch dran gewoehnt bei pointer ein p vorzusetzen, und vielleicht mal ein space mehr zu machen, als zu wenig, ... . Schon sehr praegend. :)

Und ich bin auch schon so so lange dabei, die config zu schreiben ... ich glaub ich wuerde mir in den arsch beissen, wenn ich damit aufhoeren wurde. *g* :) Und die sachen, die ich aktuell einbaue (substituion, ...) haette ich bei XML im nachhinein durchfuehren muessen. Also ... eigentlich alles garkein problem. *geducktsmile*

stefan

dumm'
25.08.2002, 13:11
so .... mal wieder. langs ists her, aber die probleme haben sich nicht geaendert :D.

es gilt immernoch


<jbb>
<topic>
</topic>
</jbb>

in


jbb->category_l->forum_l->topic_l

zu stecken ... aber es klappt nicht ;( . *g*

warum? easy ... normalerweise wuerde obiges in


jbb->topic_l

gelesen werden. Also


struct {
struct {
...
} *topic_l;
} jbb;

es geht also darum, dazwischen noch eine category und ein forum zu quetschen. Nur geht das nicht (so einfach).
idealerweise wuerde die struktur fuer das gesamte spaeter so aussehen


struct {
struct category {
struct category *next;

struct forum {
struct forum *next;

struct forum *forum_l;
struct topic {
struct topic *next;
} *topic_l;
} *forum_l;
} *category_l;
} jbb;

mal nur von den bloecken. die sachen mit _l am ende sind die anfaenge von listen. next jeweils der folgende eintrag auf den aktuellen eintrag. (wird zwar rueckwaerts eingelesen, aber tut nichts zur sache *g*)

die routinen in der config sind nun genauso konstruiert, diese modell zu erstellen und damit zu arbeiten. Dazu wird zuerst ein baum mit den gesamten infos der config erstellt, wie diese formatiert eingelesen werden soll. Da kann man dann die blocknamen setzen die formate der argumente, die eigenschaften der bloecke, callback, substitutionsregeln und was weiss ich nicht alles. die offset auf den ersten eintrag der lsite in der parent struktur und de xoffset (next_offset) in sich selbst.

bei einer struktur von


struct {
struct topic {
char *test_string;

struct topic *next;
} *topic_l;
} jbb;

wuerde man es dann so machen, dass offset


(int)&((struct jbb*)NULL)->topic_l

ist und xoffset


(int)&((struct topic*)NULL)->next

das wird gebraucht, weil intern die config routine nicht weiss, was wohin verlinkt wird. Ausgeben kann man sich das dann z.b. mit


struct topic *p = jbb->topic_l;
while(p){
printf("test_string: %s\n",p->test_string);

p = p->next;
}

wie genau das gemacht wird intern ist eigentlich nicht wichtig, obwohl ... naja ... weiss nicht.

mit dem callback kann man nun ausserhalb der routinen, wie man grade lustig ist bloecke manipuieren, bis man alles kaputt macht. Eigentlich war das auch so geplant, dass das callback dazu verwendet wird die aufgabe zu uebernehmen topic und was weiss ich von woanders an die stelle zu linken, wo sie eigentlich hin sollen (ueber das ich hier rede). Nur geht das nicht, weil erstens die infos ueber die bloecke fehler (offset und xoffset) und das alles irgendwie recht kompliziert ist.

ich bekomm vom callback ein paar daten. Das sind das letzte element in der liste, die infos zum aktuellen block, der puffer fuer den block, und der blockname, was allerdings irgendwie garkeinen sinn macht, wie mir aufgefallen ist. Der rueckgaebwert fuer das callback regelt dann, wie in der conf routine weitergemacht wird. Der block kann uebersprunge werden, die routine kann normal weiterlaufen, dann werden pops und arg geparsed und alle subbloecke, oder das callback kann angeben, dass alles schon erledigt ist, was irgendwie voellig sinnfrei ist, weil das callback sonst kilometer lang wuerde. Fazit: scheiss interface :D
ich muesste da einen category block erstellen, nehmen wir mal an, ich hab ein topic in einem jbb block, dann aber in diesem wieder forum block, weil topics nur in einem forum auftauchen duerfen. Allerdings hab ich keinerlei infos ueber die listenstruktur, um mich zu bewegen. Sollte es schon ein category geben, die anonym ist, weil das ist sinn der sache, wenn ein topic ueberall anders als in einem forum ist, muesste man die erst finden, weil mehrere anonyme categorien sind schwachsinn.

alles assi. *g*

ps. *verwirrt*

stefan

dumm'
27.08.2002, 20:52
aus ...


<jbb "Joel's Bulletin Board">
<forum 34 "forum im jbb">
</forum>

<category 345 "Entwicklerzone">
<forum 45 "ToDo">
<topic 546 "1 Million für den besten Postschinder!">
</topic>

<topic 1 1>
</topic>

<topic 2 2>
</topic>

<topic 3 3>
</topic>
</forum>

<topic 56 "topicname in cat">
</topic>
<topic 123 "zweites topic in cat">
</topic>
</category>

<forum 5 "forum im jbb">
</forum>

<category 44 "... nach dem forum im jbb">
</category>

<topic 400 "topic im jbb">
</topic>
</jbb>

mache ...


jbb:
title: Joel's Bulletin Board
category:
id: 0
name: anon
forum:
id: 0
name: anon
topic:
id: 400
name: topic im jbb
forum:
id: 5
name: forum im jbb
forum:
id: 34
name: forum im jbb
category:
id: 44
name: ... nach dem forum im jbb
category:
id: 345
name: Entwicklerzone
forum:
id: 0
name: anon
topic:
id: 123
name: zweites topic in cat
topic:
id: 56
name: topicname in cat
forum:
id: 45
name: ToDo
topic:
id: 3
name: 3
topic:
id: 2
name: 2
topic:
id: 1
name: 1
topic:
id: 546
name: 1 Million für den besten Postschinder!

und es funktioniert und ich bin eigentlich zufrieden. "Vielleicht" muss ich den code noch auf ein fuer menschen lesbares format bringen *g*, aber es funktioniert!! und ohne gross sachen zu aendern, die ich nicht aendern wolte. *huepf* *freu*

stefan