home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Vectronix 2
/
VECTRONIX2.iso
/
FILES_01
/
ST_GUIDE.LZH
/
STG-UTIL
/
1ST_CONV
/
1ST_CONV.C
next >
Wrap
C/C++ Source or Header
|
1994-04-27
|
16KB
|
819 lines
#line 1/*ACE 4 0685 */
extern void *malloc();
extern char *suffix(), *basename(), *strdup();
typedef struct flist {
char *file;
char *name;
char *title;
int flags;
struct flist *next;
} FLIST;
typedef struct {
unsigned version;
unsigned headlen;
unsigned nplanes;
unsigned patlen;
unsigned pixelw;
unsigned pixelh;
unsigned linew;
unsigned lines;
unsigned palette[16];
} IMGHEADER;
typedef unsigned char uchar;
typedef unsigned int uint;
extern long gemdos();
#define Cconws(s) gemdos(9,s)
#define Dsetdrv(d) gemdos(14,d)
#define Dsetpath(path) gemdos(59,path)
#define Fcreate(fn,mode) gemdos(60,fn,mode)
#define Fopen(fn,mode) gemdos(61,fn,mode)
#define Fclose(h) gemdos(62,h)
#define Fread(h,cnt,buf) gemdos(63,h,cnt,buf)
#define Fwrite(h,cnt,buf) gemdos(64,h,cnt,buf)
#define Fseek(where,h,how) gemdos(66,where,h,how)
#define NL "\r\n"
FLIST *FBase = 0L; // Basis der Dateiliste
int inhandle; // Handle der aktuellen Eingabedatei
uchar inbuf[4096]; // Dateibuffer fuer Eingabe
uchar *inptr;
long inlen;
uchar inpath[128]; // Pfad der Eingabedatei
uchar mainpath[128]; // Pfad der Hauptdatei
int outhandle; // Handle der Ausgabedatei
uchar outbuf[4096]; // Dateibuffer fuer Ausgabe
uchar *outptr;
uint maxlines;
uint Lineno;
uchar output[128]; // Name der Ausgabedatei
int ExtCnt;
int NeedNL; // vor Warnung NL ausgeben
int use_filenames; // Dateinamen als nodenamen nutzen
int code;
int quiet;
int NoAuto;
char *CurrFile;
/*
* Fehler melden und terminieren
*/
Message(str1, str2)
char *str1, *str2;
{
Cconws(str1);
if (str2) Cconws(str2);
Cconws(NL);
}
error(s1, s2)
char *s1, *s2;
{
Message(s1, s2);
if (outhandle) Fclose(outhandle);
if (inhandle) Fclose(inhandle);
_exit(1);
}
/*
* Ausgabedatei oeffnen
*/
Wopen(char *outfile)
{
if ((outhandle=Fcreate(outfile, 0)) > 5)
outptr = outbuf;
else
error("can't open ", outfile);
Lineno = 0;
}
/*
* Datei zum Lesen oeffnen
*/
Ropen()
{
register FLIST *p;
register char *suf;
char tmp[150];
again:
p = FBase;
while (p) {
if (p->flags==0) break; // ersten suchen, der noch
p = p->next; // nicht gelesen wurde
}
if (p == 0L) return(0); // Ende der Liste erreicht
p->flags = 1; // als gelesen markieren
strcpy(inpath, p->file); // Pfad der Eingabe merken
*basename(inpath) = 0;
if (*inpath == 0)
strcpy(inpath, mainpath);
if ((inhandle=Fopen(p->file, 0))<5) // Datei oeffnen
error("can't open ", p->file);
CurrFile = p->file;
if (quiet==0) {
Cconws("reading ");
Cconws(p->file);
Cconws("\033K\r");
NeedNL = 1;
}
if (p == FBase) { // erste Datei?
fputs("@options \"+x -s");
if (NoAuto) fputs("a");
fputs("\"" NL NL);
}
fputs("@node \""); // Name der Seite
strcpy(tmp, p->name);
ConvKey(tmp);
fputs(tmp);
fputs("\"");
if (p->title) { // evtl. Titel
fputs(" \"");
strcpy(tmp, p->title);
ConvKey(tmp);
fputs(tmp);
fputs("\"");
}
fputs(NL);
inlen = -1;
inptr = inbuf; // Lesezeiger init.
/*
* wenn es ein Bild ist, das der HCP lesen kann,
* dann binden wir es ein
*/
suf = suffix(p->file);
if (strcmp(suf, ".IMG") == 0) {
ImagePage(p);
goto again;
}
return(1); // OK
}
/*
> INF-Datei für aktuellen 1stGuide-Text lesen
*/
OpenINF(char *path)
{
char line[128];
strcpy(line, path);
strcpy(suffix(line), ".prj");
if ((inhandle=Fopen(line, 0)) > 0) {
inlen = -1;
inptr = inbuf; // Lesezeiger init.
while (fgets(line)) {
fputs(line);
fputs(NL);
}
xclose(inhandle);
}
}
/*
* Datei schliessen, dabei evtl. Buffer flushen
*/
xclose(handle)
int handle;
{
long len;
if (handle == outhandle) {
len = (long)(outptr-outbuf);
if (len) {
if (Fwrite(handle, len, outbuf) != len)
error("write error", 0L);
}
}
Fclose(handle);
}
int fgets(line)
register uchar *line;
{
register uchar *p = inptr;
int rv = 1, cnt=0;
do {
if (inlen <= 0L) {
inlen = Fread(inhandle, 4096L, inbuf);
if (inlen < 0L) // Fehler?
error("read error", 0L);
if (inlen == 0L) { // nix gelesen?
rv = 0; // DateiEnde
break;
}
inptr = p = inbuf;
}
if (*p == 10) { // NL
--inlen;
++p;
break;
}
if (*p != 13) { // CR nicht kopieren
*line++ = *p;
++cnt;
}
--inlen; // einer weniger
++p;
} while (cnt<255);
*line = 0; // Zeile abschliessen
inptr = p; // Pos. naechstes Zeichen
return(rv||cnt); // und fertig
}
fputs(line)
register uchar *line;
{
register uchar *p = outptr;
while (*line) {
if (*line == '\n') ++Lineno;
if ( (long)(p-outbuf) == 4096L) {
if (Fwrite(outhandle, 4096L, outbuf) != 4096L)
error("write error", 0L);
p = outptr = outbuf;
}
*p++ = *line++;
}
outptr = p;
}
/*******************************************************************/
/*
* Seitenende erzeugen
* Falls Datei zu lang, neue erzeugen
*/
EndNode()
{
char file[128];
fputs("@endnode" NL NL NL);
xclose(inhandle); // Eingabe schliessen
if (maxlines && Lineno>maxlines) {
strcpy(file, output);
itoa(++ExtCnt, suffix(file)+1, 10);
xclose(outhandle);
Wopen(file);
}
}
ImagePage(p)
FLIST *p;
{
IMGHEADER *img = (IMGHEADER *)inbuf;
uchar *str = inbuf+100;
int cnt;
Fread(inhandle, (long)sizeof(IMGHEADER), img);
cnt = (img->lines+15)/16;
fputs("@image ");
fputs(p->file);
fputs(" 1 ");
ltoa((long)((img->linew+7)/8), str, 10); // Breite in Zeichen
fputs(str);
fputs(" ");
ltoa((long)cnt, str, 10); // Höhe in Zeichen
fputs(str);
fputs(NL);
EndNode();
}
char *Find(char *key)
{
register FLIST *p;
p = FBase;
while (p) {
if (strcmp(p->name, key)==0)
return(0);
p = p->next;
}
return(1);
}
char *GetName(name, key)
char *name, *key;
{
char buf[20], *rv;
/*
* wenn gwünscht, dann immer den Dateinamen als
* Seitennamen verwenden
*/
if (use_filenames) {
rv = name;
goto ende;
}
if (Find(key)) { // suchen nach Titel
rv = key;
}
else {
strcpy(buf, basename(name));
*suffix(buf) = 0;
if (Find(buf)) // Datei ohne Endung
rv = buf;
else {
strcpy(buf, basename(name));
if (Find(buf)) // Datei mit Endung
rv = buf;
else {
rv = name;
}
}
}
ende:
return(strdup(rv));
}
#if 0
char *GetName(name, key, flg)
char *name, *key;
int flg;
{
register FLIST *p;
char buf[20];
register char *new;
int flag;
flag=0;
new = key; // zuerst testen wir das Schlüsselwort
again:
p = FBase;
while (p) {
if (strcmp(p->name, new) == 0) {
if (flag==2) // test auf Dateiname?
return(0L); // ja: geht alles nicht
chk:
++flag; // war test auf Schlüsselwort
new = buf; // jetzt probieren wir den Dateinamen
strcpy(new, basename(name));
if (flag==1) *suffix(new) = 0;
goto again;
}
p = p->next;
}
if (flg==0) {
flg=1;
goto chk;
}
return(strdup(new)); // gefundenen Nodenamen zurück
}
#endif
/*
* Neuen Dateinamen an die Liste zu lesender
* Dateien anhaengen, falls sie noch nicht ex.
*/
FLIST *AddFile(name, key)
char *name, *key;
{
register FLIST *p = FBase, *last = p;
while (p) {
if (strcmp(p->file, name) == 0) return(p);
last = p;
p = p->next;
}
p = malloc(sizeof(FLIST));
if (p == 0L) // Fehler
error("out of memory", 0L);
p->name = GetName(name, key);
p->file = strdup(name); // Namen kopieren
if (strcmp(p->name, key)) { // wenn nodename != key
p->title = strdup(key); // dann key als Titel nehmen
}
else
p->title = 0L;
p->flags = 0; // noch nicht gelesen
p->next = 0L; // immer der letzte
if (last) {
last->next = p;
}
else { // erstes Element
FBase = p;
}
return(p);
}
/**********************************************************/
#define IS_ASCII 1
#define NO_TYPE 2
int FileType(file, key)
char *file, *key;
{
char path[128];
register char *p, *save;
int h;
FLIST *q;
/*
* Dateinamen in Gro₧buchstaben wandeln
* und Pfad ergänzen.
*/
strupr(file);
strcpy(path, inpath);
strcat(path, file);
/*
* Der Pfad könnte '..' Teile enthalten, wegen
* des Vergleiches der Namen löschen wir diese
* Teile
*/
again:
p = path;
save = p;
while (*p) {
if (*p == '\\') {
if (p[1] == '.' && p[2] == '.') {
h = *save == '\\' ? 3 : 4;
strcpy(save, p+h);
goto again;
}
save = p; // letzter Slash
}
++p;
}
/*
* damit die Datei nicht so lang wird, schneiden
* wir den Pfad jetzt noch so weit ab, dass er relativ
* zur Hauptdatei ist
*/
save = (char *)mainpath;
p = path;
while (*p == *save) {
++p;
++save;
}
strcpy(file, p);
p = suffix(file);
/*
* mal sehen, ob es sich um einen der vom 1stView
* unterstützten Dateitypen handelt...
* Wenn ja, dann kann der Compiler damit nichts
* anfangen (keine ASCII-Datei) und wir liefern
* NO_TYPE
*/
if ( strcmp(p, ".RSC") == 0
|| strcmp(p, ".GEM") == 0
|| strcmp(p, ".SAM") == 0
|| strcmp(p, ".SND") == 0
|| strcmp(p, ".OUT") == 0
|| strcmp(p, ".DOK") == 0
//- || strcmp(p, ".IMG") == 0
|| strcmp(p, ".IFF") == 0
)
return(NO_TYPE);
/*
* ...dann ist es wohl eine ASCII-Datei;
* in diesem Fall wollen wir sie nachher noch lesen,
* also kommt sie in die Liste, falls sie geöffnet
* werden kann
*/
if ((h=Fopen(file, 0))>0)
Fclose(h);
else {
if (NeedNL) {
Cconws(NL);
NeedNL = 0;
}
Cconws("*** warning in '");
Cconws(CurrFile);
Message("': missing file ", file);
code = 2;
return(NO_TYPE);
}
q = AddFile(file, key);
strcpy(file, q->name);
return(IS_ASCII);
}
/*
* Sichtbaren Verweis konvertieren
*/
int ConvKey(key)
char *key;
{
char buf[100];
register char *src = key, *dst = buf;
int rv=1;
if (*src == '@' || NoAuto) rv=0; // link erzwingen
while (*src) {
if (*src == '"' || *src == '\\') {
*dst++ = '\\';
rv=0;
}
*dst++ = *src++;
}
*dst = 0;
strcpy(key, buf);
return(rv);
}
int HasBlanks(p)
register char *p;
{
while (*p) {
if (*p == ' ') return(1);
++p;
}
return(0);
}
DoList()
{
uchar line[255], buf[512], file[128], key[100];
register uchar *src, *dst, *p;
uchar *save;
int cnt;
while (Ropen()) { // ueber alle Dateien
again:
while (fgets(line)) { // alle Zeilen
src = line;
dst = buf;
/*
* falls die Zeile ein Infoblock ist, dann
* ignorieren wir sie einfach
*/
if (*src == 0x1F) goto again;
/*
* falls am Anfang ein Kommentarzeichen steht,
* rücken wir es einfach ein, damit der Compiler
* es ignoriert
*/
if (*src == '#' && src[1] == '#')
*dst++ = ' ';
while (*src) { // alle Zeichen
switch (*src) {
case 0x1C: // streckendes Leerzeichen
case 0x1D: // Einzugsleerzeichen
case 0x1E: // variables Leerzeichen
*dst++ = ' ';
++src;
break;
case 27:
++src;
if (*src>=0x80) {
*dst++ = '@';
*dst++ = '{';
*src -= 0x80;
if (*src==0) *dst++ = '0'; // alles aus
if (*src & 1) *dst++ = 'B'; // Fett
if (*src & 2) *dst++ = 'G'; // Hell
if (*src & 4) *dst++ = 'I'; // Kursiv
if (*src & 8) *dst++ = 'U'; // Underlined
*dst++ = '}';
}
else {
*dst++ = 27;
*dst++ = *src;
}
++src;
break;
case '@':
*dst++ = '@';
/* fall thru */
default:
*dst++ = *src++;
break;
case '▌':
p = key;
cnt=0;
save = dst;
do {
*dst++ = *src++;
if (*src == '▌') {
*p = 0;
if (cnt==1) {
++src;
break;
}
else {
p = file;
*dst++ = *src++;
}
++cnt;
}
if (*src == 0) goto more;
*p++ = *src;
} while (1);
dst = save;
if (FileType(file, key) != IS_ASCII)
p = (uchar *)"\\Main";
else {
p = 0L;
cnt = ConvKey(key);
/*
* falls der Autoreferenzer diese
* Stelle auch alleine findet, lassen
* wir ihn das machen
*/
if (cnt && *src < '0' && dst[-1] < '0'
&& (HasBlanks(file)==0)
&& strcmp(key, file) == 0) {
strcpy(dst, key);
while (*dst++);
--dst;
break;
}
}
*dst++ = '@';
*dst++ = '{';
*dst++ = '"';
strcpy(dst, key);
while (*dst++);
--dst;
strcpy(dst, "\" link ");
dst += 7;
ConvKey(file);
*dst++ = '"';
strcpy(dst, file);
while (*dst++);
--dst;
if (p) {
strcpy(dst, p);
while (*dst++);
--dst;
}
*dst++ = '"';
*dst++ = '}';
break;
}
}
more:
*dst=0;
fputs(buf);
fputs(NL);
}
EndNode();
}
}
AddIncludes()
{
char buf[128];
int i;
strcpy(buf, output);
outhandle = Fopen(buf, 1);
outptr = outbuf;
Fseek(0L, outhandle, 2);
for (i=1; i<=ExtCnt; i++) {
strcpy(buf, output);
itoa(i, suffix(buf)+1, 10);
fputs(NL "@include ");
fputs(buf);
}
fputs(NL);
xclose(outhandle);
}
/**************************************************************/
extern int _argc;
extern char **_argv;
_main()
{
main(_argc, _argv);
}
main(argc, argv)
int argc;
char **argv;
{
char outfile[128];
register char *p;
int save;
maxlines = 0;
if (argc < 2) {
error("usage: 1stConv [-NNN -f -q -a] file" NL
" -NNN: max lines per file" NL
" -f : use filenames as nodenames" NL
" -q : be quiet" NL
" -a : explicit links only" NL
, 0L);
_exit(1);
}
save = 0;
do {
++argv;
--argc;
if (**argv == '-') {
p = *argv+1;
if (*p == 'f') {
save = 1;
}
else if (*p == 'q')
++quiet;
else if (*p == 'a')
++NoAuto;
else
maxlines = atoi(p);
}
else {
if (quiet==0) {
Message("1stConv: V(" __DATE__ ") 1stGuide --> ST-Guide sources" NL
" Written by Holger Weets using SOZOBON-C V2.00x10" NL
, 0L);
}
/*
* Ausgabedatei bestimmen
*/
strupr(*argv); // falls aus CLI
strcpy(outfile, *argv);
AddFile(basename(outfile), "Main"); // nur Dateinamen eintragen
use_filenames = save;
p = (char *)mainpath; // Pfad merken
strcpy(p, outfile);
*basename(p) = 0;
/*
* wir setzen das Verzeichnis der Hauptdatei
* als aktuelles Verzeichnis, damit die Pfade
* relativ angegeben werden können und somit
* die Ausgabedatei kürzer und transportabler
* wird.
*/
if (p[1] == ':')
Dsetdrv(*p-'A');
Dsetpath(p);
strcpy(suffix(outfile), ".stg");
Wopen(outfile);
OpenINF(outfile);
strcpy(output, outfile);
ExtCnt=0;
DoList();
xclose(outhandle);
if (ExtCnt) AddIncludes();
if (NeedNL) Cconws(NL);
break;
}
} while (argc>1);
_exit(code);
}