#include #include #define MAXLINES 10000 #define MAXLEN 1024 char *lineptr[MAXLINES]; FILE *infile, *outfile; /*--------------------------------------------------------------------------*/ void info(){ char p[]="%"; printf(" %s%s +-----------------------------------------------------------------+\n", p, p); printf(" %s%s | BIBLIOGRAPHY FOR ARTS, Version 1.1, <2. FEB 1996>, Timo Baumann |\n", p, p); printf(" %s%s | |\n", p, p); printf(" %s%s | BIBARTS.STY und GBIBARTS.STY sind LaTeX-Dokumenten-Stil- |\n", p, p); printf(" %s%s | Optionen. Sie k\"onnen alternativ aufgerufen werden; das `g\' |\n", p, p); printf(" %s%s | steht f\"ur die Verwendung zusammen mit GERMAN.STY. |\n", p, p); printf(" %s%s | Die Dokumentationen sind BIBARTS.TEX und GBIBARTS.TEX. |\n", p, p); printf(" %s%s | |\n", p, p); printf(" %s%s | GBIBSORT.EXE ist eine Alternative zu den Sortier-Befehlen, die |\n", p, p); printf(" %s%s | jedes Betrieb-System besitzt: Es liest das angegebene File und |\n", p, p); printf(" %s%s | sortiert zeilenweise Zeichen vor Buchstaben (a vor A ...), dann |\n", p, p); printf(" %s%s | Zahlen. ABER: Die LaTeX-Sonderzeichen \\\"a und \"a werden als |\n", p, p); printf(" %s%s | ae usw. begriffen und \'\\\', \'{\', \'}\', \' \' nicht gewichtet. |\n", p, p); printf(" %s%s | Ein [File].BAR erzeugt LaTeX, wenn man (g)BIBARTS\' verwendet. |\n", p, p); printf(" %s%s | |\n", p, p); printf(" %s%s | EINGABE: gbibsort [File] [[Schreib-File]] |\n", p, p); printf(" %s%s | |\n", p, p); printf(" %s%s | Falls BIBARTS.BAT und GBIBARTS.BAT fehlen --- |\n", p, p); printf(" %s%s | hier ist ihr wesentlicher Inhalt: |\n", p, p); printf(" %s%s | IF EXIST %s1.bar GBIBSORT %s1.bar %s1.phy |\n", p, p, p, p, p); printf(" %s%s | IF EXIST %s1.bar MAKEINDX %s1.bar |\n", p, p, p, p); printf(" %s%s | IF EXIST %s1.tex CALL LATEX %s1 |\n", p, p, p, p); printf(" %s%s +-----------------------------------------------------------------+\n", p, p); } /*--------------------------------------------------------------------------*/ /* CopyLeft: a) Verantwortung - b) Benutzung - c) Distribuntion */ /* a) Keinerlei Haftung ! */ /* b) Keine Funktions-Garantie ! */ /* Der Anwender erkennt die Punkte a) - c) an. */ /* c) GBIBSORT.C und GBIBSORT.EXE d"urfen nur dann */ /* weitergegeben werden, wenn */ /* 1. daf"ur keine Kosten erhoben werden, */ /* die "uber diejenigen f"ur ihren */ /* Transfer hinausgehen ! */ /* 2. vorgenommene "Anderungen */ /* kommentiert sind ! */ /* Dazu, wie GBIBARTS.EXE "ubersetzt wurde und wie sich daraus */ /* Einschr"ankungen bez"uglich ihrer Verbreitung ergeben k"onnten, */ /* siehe das File _BIBARTS.1ST. */ /*--------------------------------------------------------------------------*/ /* Neugewichtung der Zeichen 48 - 126 des ASCII-Codes. */ /* 1-47 [und ggf. 127-254] bleiben gleich! -> default */ /* Im Deutschen werden Zeichen vor Buchstaben und */ /* Buchstaben vor Zahlen einsortiert. */ /* Im Konfliktfall stehen Kleinbuchstaben vor grossen. */ /* Da der ASCII-Code eine andere Reihenfolge hat, */ /* muss den Zeichen innerhalb des angegebenen Bereichs */ /* eine neue INTEGER-Zahl zugeordnet werden. */ int bewerten(char zz) { switch(zz) { case ':': return 48; /* ASCII 58 \ */ case ';': return 49; /* ASCII 59 | */ case '<': return 50; /* ASCII 60 | */ case '=': return 51; /* ASCII 61 | */ case '>': return 52; /* ASCII 62 | */ case '?': return 53; /* ASCII 63 | */ case '@': return 54; /* ASCII 64 | */ /* | */ case '[': return 55; /* ASCII 91 \ */ case '\\':return 56; /* ASCII 92 > Zeichen vor Buchstaben */ case ']': return 57; /* ASCII 93 / */ case '^': return 58; /* ASCII 94 | */ case '_': return 59; /* ASCII 95 | */ case '`': return 60; /* ASCII 96 | */ /* | */ case '{': return 61; /* ASCII 123 | */ case '|': return 62; /* ASCII 124 | */ case '}': return 63; /* ASCII 125 | */ case '~': return 64; /* ASCII 126 / */ case 'a': return 65; /* ASCII 97 \ */ case 'A': return 66; /* ASCII 65 | */ case 'b': return 67; /* ASCII 98 | */ case 'B': return 68; /* ASCII 66 | */ case 'c': return 69; /* ASCII 99 | */ case 'C': return 70; /* ASCII 67 | */ case 'd': return 71; /* ASCII 100 | */ case 'D': return 72; /* ASCII 68 | */ case 'e': return 73; /* ASCII 101 | */ case 'E': return 74; /* ASCII 69 | */ case 'f': return 75; /* ASCII 102 | */ case 'F': return 76; /* ASCII 70 | */ case 'g': return 77; /* ASCII 103 | */ case 'G': return 78; /* ASCII 71 | */ case 'h': return 79; /* ASCII 104 | */ case 'H': return 80; /* ASCII 72 | */ case 'i': return 81; /* ASCII 105 | */ case 'I': return 82; /* ASCII 73 | */ case 'j': return 83; /* ASCII 106 | */ case 'J': return 84; /* ASCII 74 | */ case 'k': return 85; /* ASCII 107 | */ case 'K': return 86; /* ASCII 75 | */ case 'l': return 87; /* ASCII 108 | */ case 'L': return 88; /* ASCII 76 | */ case 'm': return 89; /* ASCII 109 | */ case 'M': return 90; /* ASCII 77 | */ case 'n': return 91; /* ASCII 110 | */ case 'N': return 92; /* ASCII 78 | */ case 'o': return 93; /* ASCII 111 | */ case 'O': return 94; /* ASCII 79 | */ case 'p': return 95; /* ASCII 112 \ */ case 'P': return 96; /* ASCII 80 > Buchstaben: a, A, ... */ case 'q': return 97; /* ASCII 113 / */ case 'Q': return 98; /* ASCII 81 | */ case 'r': return 99; /* ASCII 114 | */ case 'R': return 100; /* ASCII 82 | */ case 's': return 101; /* ASCII 115 | */ case 'S': return 102; /* ASCII 83 | */ case 't': return 103; /* ASCII 116 | */ case 'T': return 104; /* ASCII 84 | */ case 'u': return 105; /* ASCII 117 | */ case 'U': return 106; /* ASCII 85 | */ case 'v': return 107; /* ASCII 118 | */ case 'V': return 108; /* ASCII 86 | */ case 'w': return 109; /* ASCII 119 | */ case 'W': return 110; /* ASCII 87 | */ case 'x': return 111; /* ASCII 120 | */ case 'X': return 112; /* ASCII 88 | */ case 'y': return 113; /* ASCII 121 | */ case 'Y': return 114; /* ASCII 89 | */ case 'z': return 115; /* ASCII 122 | */ case 'Z': return 116; /* ASCII 90 / */ case '0': return 117; /* ASCII 48 \ */ case '1': return 118; /* ASCII 49 | */ case '2': return 119; /* ASCII 50 | */ case '3': return 120; /* ASCII 51 | */ case '4': return 121; /* ASCII 52 \ */ case '5': return 122; /* ASCII 53 > Zahlen */ case '6': return 123; /* ASCII 54 / */ case '7': return 124; /* ASCII 55 | */ case '8': return 125; /* ASCII 56 | */ case '9': return 126; /* ASCII 57 / */ default : return zz; } } /*--------------------------------------------------------------------------*/ /* Dies ist die eigentliche Sortier-Funktion. */ /* Sie zerteilt das Sortierproblem in viele triviale: */ /* Wie sind z w e i Eintr"age zu sortieren? */ void QQsort(void *v[], int left, int right, int (*comp)(void *, void *)) { int i, last; void swap (void *v[], int, int); if (left >= right) return; swap(v, left, (left + right)/2); last = left; for (i = left + 1; i <= right; i++) if ((*comp)(v[i], v[left]) < 0) swap(v, ++last, i); swap(v, left, last); QQsort(v, left, last - 1, comp); QQsort(v, last + 1, right, comp); } /*--------------------------------------------------------------------------*/ /* Wenn zwei Eintr"age in der falschen Reihenfolge */ /* sortiert sind, werden die Zeiger, die auf sie */ /* weisen, ausgetauscht. */ void swap(void *v[], int i, int j) { void *temp; temp = v[i]; v[i] = v[j]; v[j] = temp; } /*--------------------------------------------------------------------------*/ /* Hier werden Leerzeichen, Backslash, geschweifte */ /* Klammern, Tilden und Minus-Zeichen gleich "uber- */ /* gangen, um \"a und "a, \ss und \ss{}, a~b und a b, */ /* Info und In\-fo gleich gewichtet zu bekommen. */ /* \ss und "s werden als ss, "[x] und \"[x] als [x]e */ /* sortiert, aber original ausgedruckt. */ /* `[x], ^[x] und '[x] werden als [x] gewichtet. */ /* \newumlaut muss nicht beachtet werden, denn mit */ /* dem GBIBARTS.STY-Makro \@sIcHerUnG konnte es unter- */ /* dr"uckt werden, dass dies in [File].BAR erscheint. */ /* Da in [File].BAR die Umlaute und "s immer expan- */ /* diert sind, muss auf die Ein-Zeichen-Umlaute, wie */ /* sie im erweiterten ASCII-Code definiert sind, */ /* keine R"ucksicht genommen werden. */ int vergleich(const void *s1,const void *s2) { int a1=1, b1=1, a2=1, b2=1, a3=1, b3=1, a=1, b=1; while (a == b) { /* In der Gewichtung */ while ( /* "ubergangen werden: */ ( (*((char *)s1)) == (' ') ) /* Leerzeichen */ || ( (*((char *)s1)) == ('\\') ) /* backslash */ || ( (*((char *)s1)) == ('{') ) /* geschweifte */ || ( (*((char *)s1)) == ('}') ) /* Klammern */ || ( (*((char *)s1)) == ('~') ) /* Tilde */ || ( (*((char *)s1)) == ('-') ) /* Trennhilfe */ || ( (*((char *)s1)) == ('\'') ) /* accent aigu */ || ( (*((char *)s1)) == ('`') ) /* accent grave */ || ( (*((char *)s1)) == ('^') ) /* accent circonflex */ ) { s1=(char *)s1 + 1; } while ( ( (*((char *)s2)) == (' ') ) || ( (*((char *)s2)) == ('\\') ) || ( (*((char *)s2)) == ('{') ) || ( (*((char *)s2)) == ('}') ) || ( (*((char *)s2)) == ('~') ) || ( (*((char *)s2)) == ('-') ) || ( (*((char *)s2)) == ('\'') ) || ( (*((char *)s2)) == ('`') ) || ( (*((char *)s2)) == ('^') ) ) { s2 = (char *)s2 + 1; } a3 = a2; b3 = b2; a2 = a1; b2 = b1; a1 = bewerten(*((char *)s1)); b1 = bewerten(*((char *)s2)); s1 = (char *)s1 + 1; s2 = (char *)s2 + 1; a = a2 ; b = b2 ; if ( /* Abpr"ufen, ob ein Um- */ ( a2 == bewerten('\"') ) /* laut vorhanden ist */ ) { a = a1; } if ( ( b2 == bewerten('\"') ) ) { b = b1; } if ( ( a3 == bewerten('\"') ) && ( a2 != bewerten('s') ) /* "s ist kein Umlaut */ ) { a = bewerten('e'); } /* "a als ae etc. */ if ( ( b3 == bewerten('\"') ) && ( b2 != bewerten('s') ) ) { b = bewerten('e'); } } if (a > b ) {return 1;} else {return -1;} } /*--------------------------------------------------------------------------*/ int getline(char s[], int lim) { int c,i; i=0; while(--lim > 0 && (c=fgetc(infile)) != EOF && c != '\n') s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i; } /*--------------------------------------------------------------------------*/ void writelines(char *lineptr[], int nlines) { while(nlines-- > 0) fprintf(outfile,"%s\n",*lineptr++); } int readlines(char *Lineptr[], int maxlines) { int len, nlines; char *p, line[MAXLEN]; nlines = 0; while ((len = getline(line,MAXLEN)) > 0) if (nlines >= maxlines || (p = malloc(len*sizeof(char))) == NULL) return -1; else { line[len-1] = '\0'; strcpy(p, line); Lineptr[nlines++] = p; } return nlines; } /*--------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { char p[]=" %% "; int nlines=0; int i; if (argc == 1) { info(); exit(1); } else if (argc == 2) { infile = fopen(argv[1],"r"); outfile = stdout; } else if (argc == 3) { if (strcmp(argv[1], argv[2]) == 0) { printf("\n%s Quelle und Ziel d\"urfen nicht identisch sein.\n", p); exit(1); } infile = fopen(argv[1],"r"); outfile = fopen(argv[2],"w"); } else { printf("\n%s Zu viele Argumente.\n", p); exit(1); } if (infile == NULL) { printf("\n%s \"%s\" kann nicht gelesen werden.\n", p, argv[1]); exit(1); } if (outfile == NULL) { printf("\n%s Betriebsystem verhindert Ausgabe in \"%s\".\n", p, argv[2]); printf("%s Gegebenenfalls Schutz gegen \"Uberschreiben entfernen.\n", p); exit(1); } if ((nlines = readlines(lineptr, MAXLINES)) >= 0) { QQsort((void **) lineptr, 0, nlines-1, (int (*)(void*,void*))(vergleich)); writelines(lineptr, nlines); printf("\n%s GBIBSORT.EXE sortierte \"%s\"\n", p, argv[1]); printf("%s am %s alphabetisch ", p, __DATE__); if (argv[2] == NULL) printf("auf die Standard-Ausgabe.\n"); else printf("in \"%s\".\n", argv[2]); return 0; } else { printf("Fehler: Datei zu gross.\n"); return 1; } } /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/