home *** CD-ROM | disk | FTP | other *** search
- /*
- **************************** NOTICE! **************************
- * Contrary to the current trend in MS-DOS software this *
- * program, for whatever it is worth, is NOT copyrighted *
- * (with the exception of the runtime library from Borland *
- * International's Turbo C)! The program, in whole or in *
- * part, may be used freely in any fashion or environment *
- * desired. If you find this program to be useful to you, *
- * do NOT send any contribution to the author; in the words *
- * of Rick Conn, 'Enjoy!' However, if you make any *
- * improvements, I would enjoy receiving a copy of the *
- * modified source. I can be reached, usually within 24 *
- * hours, by messages on any of the Phoenix systems, *
- * particularly: *
- * *
- * Bob's Answering Machine [OPUS] *
- * (602) 242-3158 1200/2400 bps *
- * Radioactive West [PCBOARD] *
- * (602) 873-0810 1200/2400 bps *
- * The Tool Shop BBS [PCBOARD] *
- * (602) 279-2673 1200/2400/9600 bps *
- * (Good luck trying! VERY BUSY!) *
- * Technoids Anonymous [PCBOARD] *
- * (602) 899-4876 300/1200/2400 bps *
- * *
- * All can be reached through PC Pursuit. *
- * *
- * or: *
- * on GEnie, mail address: DON-WILL *
- * on CompuServ: 75410,543 *
- * *
- * Every effort has been made to avoid error and moderately *
- * extensive testing has been performed on this program, *
- * however, the author does not warrant it to be fit for any *
- * purpose or to be free from error and disclaims any *
- * liability for actual or any other damage arising from the *
- * use of this program. *
- *****************************************************************
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
-
- #include "queue.h"
-
- #define LINE_LENGTH 256
- #define OFF 0
- #define ON 1
-
- struct KeyEntry {
- int Begin;
- int Len;
- char Case;
- };
-
- void GetArgs (int argc, char *argv[]);
- void InvalArgu (char *Msg);
- int KeyComp (char *Str1, char *Str2, QUE_DEF *Q);
- void Usage (void);
-
- char InName[65] = "";
- FILE *F1 = NULL;
- FILE *F2;
- QUE_DEF *Keys;
-
- void
- main (int argc, char *argv[]) {
- char BakName[65];
- char IntName[65];
- char Line[LINE_LENGTH + 3];
- char *OldLine = NULL;
- char *p;
- struct KeyEntry *t;
- int Lnno = 0;
-
- fprintf(stderr, "UNEEK- Version 1.0.0 May 21, 1990\n");
- if (argc < 2) Usage();
- Keys = malloc(sizeof(QUE_DEF));
- InitQueue(Keys);
- GetArgs(argc, argv);
-
- if (F1 == NULL) {
- if (InName[0] == '\0') {
- fprintf(stderr, "You must supply an input file name.\n");
- Usage();
- }
- strcpy(BakName, InName);
- if ( (p = strrchr(BakName, '.')) != NULL) *p = '\0';
- strcat(BakName, ".BAK");
- strcpy(IntName, InName);
- if ( (p = strrchr(IntName, '\\')) == NULL) p = IntName;
- else ++p;
- strcpy(p, "UNIQUE.$$$");
-
- if ( (F1 = fopen(InName, "r")) == NULL) {
- fprintf(stderr, "I can't open input file: %s", InName);
- perror("");
- exit(1);
- }
- setvbuf(F1, NULL, _IOFBF, 16384);
- if ( (F2 = fopen(IntName, "w")) == NULL) {
- fprintf(stderr, "I can't create output file: %s", IntName);
- perror("");
- exit(1);
- }
- setvbuf(F2, NULL, _IOFBF, 16384);
- }
-
- if (Keys->Count == 0) {
- t = malloc(sizeof(struct KeyEntry));
- t->Begin = 0;
- t->Len = 0;
- Enque(Keys, t);
- }
-
- while (fgets(Line, LINE_LENGTH, F1) != NULL) {
- Lnno++;
- if (Line[strlen(Line)-1] != '\n') {
- fprintf(stderr, "File: %s Line #%d too long - truncated.\n",
- InName, Lnno);
- strcat(Line, "\n");
- while (fgetc(F1) != '\n');
- }
- if (OldLine == NULL) OldLine = malloc(LINE_LENGTH + 3);
- else {
- if (KeyComp(OldLine, Line, Keys)) fputs(OldLine, F2);
- }
- strcpy(OldLine, Line);
- }
-
- fputs(OldLine, F2);
- if (F1 != stdin) {
- fclose(F1); fclose(F2);
- unlink(BakName);
- if (rename(InName, BakName)) {
- fprintf(stderr, "Rename of file: %s failed", InName);
- perror("");
- }
- if (rename(IntName, InName)) {
- fprintf(stderr, "Rename of file: %s failed", IntName);
- perror("");
- }
- }
- }
-
-
-
- void
- GetArgs (int argc, char *argv[]) {
- int i;
- char *p1, *p2;
- struct KeyEntry *t;
-
- for (i=1; i < argc; ++i) {
- if (argv[i][0] != '-') continue;
- if (!strcmp(argv[i], "-")) {
- F1 = stdin;
- F2 = stdout;
- continue;
- }
- switch (tolower(argv[i][1])) {
- default:
- fprintf(stderr, "Invalid option: %s\n", argv[i]);
- Usage();
- }
- }
-
- for (i=1; i < argc; ++i) {
- if (argv[i][0] == '-') continue;
- if ( (F1 == NULL) && (InName[0] == '\0') ) {
- if (InName[0] == '\0') {
- strcpy(InName, argv[i]);
- continue;
- }
- }
- p1 = argv[i];
- if ( !isdigit(p1[0]) ) InvalArgu(argv[i]);
- p2 = &p1[strspn(p1, "0123456789")];
- t =malloc( sizeof(struct KeyEntry) );
- t->Case = OFF;
- t->Begin = atoi(p1) -1;
- if (*p2 == ':') t->Len = atoi(++p2);
- else if (*p2 == '-') t->Len = atoi(++p2) - t->Begin;
- else InvalArgu(argv[i]);
- p1 = p2;
- p2 = &p1[strspn(p1, "0123456789")];
- if (*p2 == ':') {
- p1 = ++p2;
- while (*p1 != '\0') {
- switch (tolower(*p1++)) {
- case 'i':
- t->Case = OFF;
- break;
- case 'c':
- t->Case = ON;
- break;
- default:
- InvalArgu(argv[i]);
- }
- }
- }
- else if (*p2 != '\0') InvalArgu(argv[i]);
- Enque(Keys, t);
- }
- }
-
-
-
- void
- InvalArgu (char *Msg) {
- fprintf(stderr, "Invalid argument: %s.\n", Msg);
- Usage();
- }
-
-
-
- int
- KeyComp (char *Str1, char *Str2, QUE_DEF *Q) {
- int Result, La, Lb;
- QUE_ENTRY *t;
- struct KeyEntry *p;
- char *S1, *S2, HoldA, HoldB;
-
- La = strlen(Str1); Lb = strlen(Str2);
- for (Result=0, t = Q->Head; (Result == 0) && (t != NULL); t = t->Next) {
- p = t->Body;
- if (p->Len == 0) {
- if (p->Case == OFF) Result = stricmp(Str1, Str2);
- else Result = strcmp(Str1, Str2);
- break;
- }
- else {
- if (p->Begin > La) S1 = "";
- else S1 = &Str1[p->Begin];
- if (p->Begin > Lb) S2 = "";
- else S2 = &Str2[p->Begin];
- if (S1[0] != '\0') {
- if (p->Begin + p->Len < La) {
- HoldA = S1[p->Len];
- S1[p->Len] = '\0';
- }
- }
- if (S2[0] != '\0') {
- if (p->Begin + p->Len < Lb) {
- HoldB = S2[p->Len];
- S2[p->Len] = '\0';
- }
- }
-
- if (p->Case == OFF) Result = stricmp(S1, S2);
- else Result = strcmp(S1, S2);
- if ( (S1[0] != '\0') && (p->Begin + p->Len < La) )
- S1[p->Len] = HoldA;
- if ( (S2[0] != '\0') && (p->Begin + p->Len < Lb) )
- S2[p->Len] = HoldB;
- }
- }
- return(Result);
- }
-
-
-
- void
- Usage (void) {
- fprintf(stderr, "USAGE: unique [- | file_name] [field_spec ...]\n");
- fprintf(stderr, " field_spec = b:l[:o] or b-e[:o] where b is the beginning\n");
- fprintf(stderr, " character position of the field and l is the length\n");
- fprintf(stderr, " in characters or e is the ending character position\n");
- fprintf(stderr, " of the field (inclusive). o, if supplied is 'i' for\n");
- fprintf(stderr, " a case insensitive match (default) or 'c' for a case\n");
- fprintf(stderr, " sensitive match.\n");
- exit(1);
- }