_Pipelines for Macintosh_ by Kris Coppieters Listing One /* copy.c -- The generic version of processchar that should be used as * a base for new pipes. Contains the routine ProcessChar(int chr). * ProcessChar should call PutChar(chr) after or while processing incoming * characters. At the end of the file, there is an extra call to ProcessChar * with chr == cEOF to signal EOF. chr an unsigned char in the range 0 to 255 * when calling ProcessChar with a valid character. * There is no harm done by calling PutChar(chr) with chr == cEOF. */ #ifndef _processchar_ #include "processchar.h" #endif /**************************************************************************** * Empty filter. Use as a starter for new filters */ void ProcessChar(int chr) { if (chr != cEOF) { PutChar(chr); } } /* ************************************************************************ */ /* This routine will be called at startup with the name of the application * You can set some of your global variables to influence ProcessChar. * All characters are converted to lowercase before the call. */ void AcceptAppNam(char *appNam) { } /* ************************************************************************ */ /* This routine is called for each command-line parameter encountered. You * should test the parameters and return TRUE if the parameter needs a value, * FALSE if not. All characters are converted to lowercase before the call. * Example: sort ascending column 3-5 * ParamNeedsValue("ascending") should return FALSE * ParamNeedsValue("column") should return TRUE * You can use if (strcmp(param,"name") == 0) for comparisons... */ int ParamNeedsValue(char *param) { return(FALSE); } /* ************************************************************************ */ /* Called for each value-less command-line parameter encountered. * All characters are converted to lowercase before the call. * Example: sort ascending column 3-5 * AcceptParameter("ascending") is called * You can use if (strcmp(param,"name") == 0) for comparisons... */ void AcceptParameter(char *param) { } /* ************************************************************************* */ /* Called for a single-valued command-line parameter. All characters are * converted to lowercase before the call. * Example: sort ascending field 3,4 * AcceptParameterValue("field","3") and AcceptParameterValue("field","4") * are called. * You can use if (strcmp(param,"name") == 0) for comparisons... * Use atoi() for converting numeric strings into integers. */ void AcceptParameterValue(char *param,char *value) { AcceptParameterFromTo(param,value,value); } /* ************************************************************************* */ /* This routine is called for a two-valued command-line parameter. * All characters are converted to lowercase before the call. * Example: sort ascending field 3-4,5-7 * AcceptParameterFromTo("field","3","4") and * AcceptParameterFromTo("field","5","7") are called * You can use if (strcmp(param,"name") == 0) for comparisons... * Use atoi() for converting numeric strings into integers. */ void AcceptParameterFromTo(char *param,char *valueFrom,char *valueTo) { } Listing Two /* sort.c -- Store input file in unbalanced binary tree. Sort criterium can * either be complete lines, range of character columns, or range of tabbed * text fields. */ #ifndef _processchar_ #include "processchar.h" #endif /* ************************************************************************* * SORT filter */ typedef struct SLine { char *line; int from; int to; struct SLine *pSmaller; struct SLine *pGreater; } TLine; typedef TLine *TpLine; /* Some globals */ TpLine gpTreeLine = NULL; char gLine[cMaxStrLen+1]; char *gpLine = gLine; int gLen = 0; int gFromPos = 0; int gToPos = 0; int gFieldCount = 1; /* Parameters */ int gAscending = TRUE; int gCharFromPos = 1; int gCharToPos = cMaxStrLen; int gFromField = 1; int gToField = cMaxStrLen; void AddLine(char *line, int len, int from, int to) { TpLine pLine; TpLine pPrvLine; int direction; pLine = gpTreeLine; pPrvLine = NULL; direction = 0; while (pLine != NULL) { char *pStr1; char *pStr2; char c1, c2; pPrvLine = pLine; pStr1 = pLine->line + pLine->from - 1; c1 = *(pLine->line + pLine->to); *(pLine->line + pLine->to) = '\0'; pStr2 = line + from - 1; c2 = *(line + to); *(line + to) = '\0'; direction = strcmp(pStr1,pStr2); *(pLine->line + pLine->to) = c1; *(line + to) = c2; if (direction > 0) pLine = pLine->pSmaller; else pLine = pLine->pGreater; } pLine = (TpLine) NewPtr(sizeof(TLine)); if (pLine != NULL) { pLine->pSmaller = NULL; pLine->pGreater = NULL; pLine->from = from; pLine->to = to; pLine->line = (TpChr) NewPtr(len+1); if (pLine->line != NULL) strcpy(pLine->line,line); else { DisposePtr((Ptr) pLine); pLine = NULL; } } if (pLine != NULL) { if (pPrvLine == NULL) gpTreeLine = pLine; else { if (direction > 0) pPrvLine->pSmaller = pLine; else pPrvLine->pGreater = pLine; } } } void DumpTree(TpLine pLine) { if (pLine != NULL) { if (gAscending) DumpTree(pLine->pSmaller); else DumpTree(pLine->pGreater); PutStr(pLine->line); PutChar('\n'); if (gAscending) DumpTree(pLine->pGreater); else DumpTree(pLine->pSmaller); DisposePtr((Ptr) pLine->line); DisposePtr((Ptr) pLine); } } void ProcessChar(int chr) { if (chr == '\n' || (chr == cEOF && gLen > 0)) { *gpLine = '\0'; if (gFromPos == 0) { gToPos = 0; gFromPos = 1; } AddLine(gLine,gLen,gFromPos,gToPos); gpLine = gLine; gLen = 0; gFromPos = 0; gToPos = 0; gFieldCount = 1; } else if (chr != cEOF) { if (gLen < cMaxStrLen) *(gpLine++) = chr; gLen++; if (gFromPos == 0) { if (gFromField <= gFieldCount && gCharFromPos <= gLen) gFromPos = gLen; } if (gFieldCount <= gToField && gLen <= gCharToPos) gToPos = gLen; if (chr == '\t') gFieldCount++; } if (chr == cEOF) { DumpTree(gpTreeLine); gpTreeLine = NULL; } } /* ************************************************************************* */ /* This routine will be called at startup with the name of the application * You can set some of your global variables to influence ProcessChar. * All characters are converted to lowercase before the call. */ void AcceptAppNam(TpChr appNam) { } /* ************************************************************************* */ /* Called for each command line parameter encountered. You should * test parameters and return TRUE if parameter needs a value, FALSE if not. * All characters are converted to lowercase before the call. * Example: sort ascending column 3-5 * ParamNeedsValue("ascending") should return FALSE * ParamNeedsValue("column") should return TRUE */ int ParamNeedsValue(char *param) { return(strcmp(param,"column") == 0 || strcmp(param,"field") == 0 || strcmp(param,"col") == 0 || strcmp(param,"fld") == 0 || strcmp(param,"c") == 0 || strcmp(param,"f") == 0); } /* ************************************************************************* */ /* Called for each value-less command-line parameter encountered. * All characters are converted to lowercase before the call. * Example: sort ascending column 3-5 * AcceptParameter("ascending") is called */ void AcceptParameter(char *param) { if (strcmp(param,"ascending") == 0 || strcmp(param,"asc") == 0 || strcmp(param,"a") == 0) gAscending = TRUE; else if (strcmp(param,"descending") == 0 || strcmp(param,"desc") == 0 || strcmp(param,"d") == 0) gAscending = FALSE; } /* ************************************************************************* */ /* This routine is called for a single valued command line parameter. * All characters are converted to lowercase before the call. * Example: sort ascending field 3 * AcceptParameterValue("field","3") is called */ void AcceptParameterValue(char *param,char *value) { AcceptParameterFromTo(param,value,value); } /* ************************************************************************* */ /* This routine is called for a two-valued command-line parameter. * All characters are converted to lowercase before the call. * Example: sort ascending field 3-4 * AcceptParameterFromTo("field","3","4") is called */ void AcceptParameterFromTo(char *param,char *valueFrom, char *valueTo) { if (strcmp(param,"field") == 0 || strcmp(param,"fld") == 0 || strcmp(param,"f") == 0) { gFromField = atoi(valueFrom); gToField = atoi(valueTo); } else if (strcmp(param,"column") == 0 || strcmp(param,"col") == 0 || strcmp(param,"c") == 0) { gCharFromPos = atoi(valueFrom); gCharToPos = atoi(valueTo); } }