#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <vector>
struct Node{
Node() {memset(this,0,sizeof*this);}
byte magic; // = 0, niemals 1. Byte bei Namen
union{
const char*name[10]; // 10 Zeiger auf Namen oder auf Node für die Wählziffern '0'..'9'
Node*node[10];
};
// operator const char*() const {return (const char*)this;}
static void insert(Node*&,const char*number, const char*name);
void emit(const char*varname);
};
Node*root;
void Node::insert(Node*&n,const char*number, const char*name) {
if (!n) n=new Node;
if (number[1]) { // Weitere Ziffern folgen?
insert(n->node[*number-'0'],number+1,name);
}else{ // einzige oder letzte Ziffer
if (n->name[*number-'0'])
printf("Doppelte Nummer für %s\n",name);
n->name[*number-'0']=name; // Name eintragen (Slot sollte noch 0 enthalten!)
}
}
int nodecount;
void Node::emit(const char*varname) {
char subname[8];
if (strcmp(varname,"root")) strcpy(subname,varname);
else strcpy(subname,"n");
char*submod=subname+strlen(subname);
submod[1]=0;
int i;
for (i=0; i<10; i++) {
if (node[i] && !node[i]->magic) {
*submod=i+'0';
node[i]->emit(subname);
}
}
nodecount++;
printf("%s={\t",varname);
for (i=0; i<10; i++) {
if (node[i]) {
if (node[i]->magic) {
printf("\"%s\",\t",name[i]);
}else{
*submod=i+'0';
printf("(char*)%s,\t",subname);
}
}else{
printf("0,\t\t");
}
}
printf("}%c\n",strcmp(varname,"root")?',':';');
}
EXTERN_C void mainCRTStartup() {
char line[256];
std::vector<const char*>names;
int stringsize=0;
while (fgets(line,256,stdin)) {
char*t=strchr(line,'\t');
if (t && t!=line) {
*t=0;
char*e=strchr(++t,'\n');
if (e) *e=0;
const char*nn=0;
for (const char**in=names.begin(); in!=names.end(); in++) {
if (!strcmp(*in,t)) {nn=*in; break;}
}
if (!nn) {
nn=_strdup(t);
names.push_back(nn);
int l=strlen(nn);
// if (l>20) l=16; // max. 20 oder 16 Zeichen annehmen für ATmega-Implementierung
stringsize+=l;
}
Node::insert(root,line,nn);
}
}
printf("typedef const char* Node[10];\n");
printf("static const Node\n");
root->emit("root");
printf("//nodecount: %d (%d bytes)\n",nodecount,nodecount*20);
printf("//stringsize: %d (%d strings)\n",stringsize,names.size());
printf("//needflash: %d ohne \\0, %d mit \\0\n",nodecount*20+stringsize,nodecount*20+stringsize+names.size());
ExitProcess(0);
}
// Lösung für AVR-Mikrocontroller:
// Die 840 Einträge lange Nodeliste in ein Array packen
// und durch negative Indizes adressieren (max. -839).
// Die Strings: Umlaute durch 7-Bit-ASCII ersetzen ('Ä'='[' usw.)
// und Strings mit gesetztem Bit 7 terminieren.
// Dann genügen 16 Bit für alle Adressen,
// ohne (statt der möglichen Adressierung mit Stringnummer)
// 60 KB Flash parsen zu müssen.
// Auch gut für einen 128-KB-seriellen EEPROM 24FC1025 geeignet,
// da zur Nummernsuche nur wenige Zugriffe erforderlich sind
Detected encoding: ANSI (CP1252) | 4
|
|