|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 14865 (0x3a11) Types: TextFile Names: »str.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦this⟧ »DVIware/laser-setters/dvi-to-ps/TeXPS/lib/str.c«
/* Copyright 1988 Stephan v. Bechtolsheim */ /* This file is part of the TeXPS Software Package. The TeXPS Software Package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Refer to the TeXPS Software Package General Public License for full details. Everyone is granted permission to copy, modify and redistribute the TeXPS Software Package, but only under the conditions described in the TeXPS Software Package General Public License. A copy of this license is supposed to have been given to you along with TeXPS Software Package so you can know your rights and responsibilities. It should be in a file named CopyrightLong. Among other things, the copyright notice and this notice must be preserved on all copies. */ /* Procedures for string handling. */ #include <stdio.h> #if SYS_V == 1 #include <string.h> #else #include <strings.h> #endif #define TRUE 1 #define FALSE 0 #define MAX_LINE_LENGTHS 512 /* Externals. */ extern char * Malloc(); extern void Fatal4(); /* Forward declarations. */ char * StrcpyAlloc(); char * StrncpyAlloc(); /* Global variables. */ /* To generate a variable number of indentation, using some index a string with 4 * index number of spaces is returned. */ char* StringsOfSpaces[] = { "", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "}; /* * CompareStringError * ****************** * Compare two strings, and raise hell, if they aren't the same. * * s1: the string, which you found. * s2: the string, which you expected. * where: give some indication of where the error occured. */ void CompareStringError(s1, s2, where) char * s1; char * s2; char * where; { if (strcmp(s1, s2) == 0) return; Fatal4 ("CompareStringError(): %s, seen: \"%s\", expected: \"%s\".", where, s1, s2); } /* * ComputeStringCheckSum * ********************* * That function isn't ok yet. * Compute an integer checksum of string s, where ck is the * starting value of the checksum. This way this rountine can * be called repeatedly as the string grows longer and longer. * * s: string, for which checksum is computed. * ck: starting value of checksum. */ int ComputeStringCheckSum(s, ck) char * s; int ck; { while (*s != '\0') { ck = (ck + *s) % 837872738; s++; } return (ck); } /* * CountNewLinesInString * ********************* * Count the number of \n s in a string. If the last character * in the string was not a \n, one is added to the result because * the assumption is that there is indeed a line at the end * and return that number. * * st: the string. */ int CountNewLinesInString (st) char * st; { int count; count = 0; while (*st) { if (*st == '\n') count++; st++; } if (*--st != '\n') count++; return (count); } /* * IsBeginningOfLine * ***************** * Check whether string "keyst" occurs at the beginning of line "s". * If so return TRUE and remove the string (including any spaces or tabs * following it) from the line. If not return FALSE. * * s: a string * keyst: key string for which we test the beginning of "s" for. * RET: TRUE: "keyst" appears at the beginning of the line * (and was removed) * FALSE: "keyst" did not appear at the beginning of the line. */ int IsBeginningOfLine (line, keyst) char * line; char * keyst; { char * s_org; /* Return if no match. */ if (strncmp(line, keyst, strlen(keyst)) != 0) return (FALSE); /* Match: remove keyword itself and spaces following it. */ s_org = line; line += strlen(keyst); line += SkipSpacesEtc(line); while (*s_org++ = *line++); return (TRUE); } /* * IsEmptyLine * *********** * Test whether a line is "in effect" empty, i.e. * the line may be really empty or contain white space (tabs, * spaces and return) and still count as empty * * s: line we test for. * RET: TRUE if line is empty or has white space only. */ int IsEmptyLine(s) char *s; { while (*s != '\0') { if (*s!=' ' && *s!= '\t' && *s!='\n') return(FALSE); s++; } return (TRUE); } /* * IsPrefix * ******** * Check whether s2 is a prefix of s1. * * s1: main string. * s2: string which is tested whether it's a prefix to s1 or not. * RET: !=0 if s2 is a prefix of s1, ==0 otherwise. */ int IsPrefix (s1, s2) char *s1; char *s2; { return (Strncmp(s1, s2, Strlen(s2)) == 0); } /* * IsPostFix * ********* * Check whether s2 is a postfix of s1. * * s1: main string. * s2: string which is tested whether it's a postfix of s1 or not. * RET: !=0 if s2 is a postfix of s1, ==0 otherwise. */ int IsPostFix (s1, s2) char *s1; char *s2; { int l1, l2; l1 = Strlen(s1); l2 = Strlen(s2); if (l1 < l2) /* Main string too short. */ return (FALSE); return (Strcmp(s1 + l1 - l2, s2) == 0); } /* * RemoveInLine * ************ * Remove n characters from the beginning of a string buffer. * * b: buffer. * n: number of bytes to remove. */ void RemoveInLine (b, n) char *b; int n; { char *p1, *p2; p1 = b; p2 = b+n; while (*p2 != '\0') { *p1++ = *p2++; } *p1 = '\0'; } /* * RemoveLeadingWhiteSpace * *********************** * Remove leading spaces and tabs from a string. * * p: pointer to a string. */ void RemoveLeadingWhiteSpace(p) char *p; { int n; if ((n=SkipSpacesEtc(p)) == 0) return; RemoveInLine(p, n); } /* * RemoveTrailingWhiteSpace * ************************ * Remove trailing spaces and tabs from a string. * The string is simply shortened (if necessary) by adding * \0 at the end of the string. * * p: pointer to a string. */ void RemoveTrailingWhiteSpace(p) char *p; { char *ptr; if (Strlen(p) == 0) return; ptr = p + Strlen(p) - 1; while (ptr >= p) { if (*ptr == ' ' || *ptr == '\t') *ptr-- = '\0'; else return; } } /* * SkipSpacesEtc * ************* * Skip white space in some string. Return how many characters * were skipped. * * p: pointer to some string. * RET: how many leading spaces and tabs are there. */ int SkipSpacesEtc(p) char * p; { int count = 0; while (*p != '\0') { if (*p != ' ' && *p != '\t') return (count); count++; p++; } return (count); } /* * SkipUntilString * *************** * Continue reading from a file until you find a particular * string at the beginning of a line. * * f: file to read from. * st: string to be searched for. */ int SkipUntilString(f, st) FILE *f; char *st; { char line [MAX_LINE_LENGTHS]; while (ReadLineIntoBuffer(f, line, MAX_LINE_LENGTHS) != EOF) { if (IsPrefix(line, st)) return (TRUE); } return (FALSE); } /* * StrcpyAlloc * *********** * String copy routine with allocation of space for the * buffer the string is copied to. * * source: source string. * RET: a pointer to the copy of the source. */ char * StrcpyAlloc (source) char *source; { if (source == NULL) return (NULL); return (strcpy (Malloc(strlen(source)+1), source)); } /* * StrncpyAlloc * ************ * String copy routine with previous allocation of space. * * source: source text. * n: how many bytes to copy. * RET: a pointer to the copy of the source. */ char* StrncpyAlloc (source, n) char *source; int n; { char *s; s = strncpy (Malloc(n+1), source, n); *(s + n) = '\0'; return (s); /* Terminate string with a zero. */ } /* * Strcmp * ****** * Compare to strings, but check on whether one or both are NULLs. * A NULL string pointer is treated as an empty string. * * s1: first string * s2: second string */ int Strcmp (s1, s2) char *s1; char *s2; { if (s1 == NULL) s1 = ""; if (s2 == NULL) s2 = ""; return(strcmp (s1, s2)); } /* * Strncmp * ******* * Compare to strings, but check on whether one or both are NULLs. * A NULL string is treated as an empty string. * Comparison is only performed on the first n characters. * * s1: first string. * s2: second string. * n: number of characters to compare. */ int Strncmp (s1, s2, n) char *s1; char *s2; { if (s1 == NULL) s1 = ""; if (s2 == NULL) s2 = ""; return(strncmp (s1, s2, n)); } /* * Strlen * ****** * String length operator. Returns also zero, if the string pointer is NULL. * * s: string (also NULL). * RETURN: length of the string. */ int Strlen(s) char *s; { if (s==NULL) return (0); return (strlen(s)); } /* * LineLengthCountingTabs * ********************** * Count the number of characters in a line, regarding tabs * as the appropriate number of spaces. The strings ends with * either a \n or a \0. String can be NULL. * * s: string. * tab: how many tabs are there to a space. * RETURN: length of string. */ int LineLengthCountingTabs(s, tab) char *s; int tab; { int ret; char c; if (Strlen(s) == 0) return (0); ret = 0; while ((c = *s++) != '\0') { ret++; if (c == '\n') return (ret-1); if (c == '\t') { while ((ret%tab) != 0) ret++; } } return (ret); } /* * ReplaceTabsBySpaces * ******************* * In a line containing text with tabs those tabs are replaced by the * appropriate number of spaces. A string is terminated by a \0, * and must not contain a \n. The two buffers must be distinct. * * in_line: line of text including tabs. * out_line: buffer for a line of text, with the tabs replaced by spaces. * tab_size: how many space are there to the tab. */ void ReplaceTabsBySpaces (in_line, out_line, tab_size) char *in_line; char *out_line; int tab_size; { int c; /* Character from the in_line */ int i; /* index into the in_line */ int j; /* index into the out_line */ int k; /* index for inserting spaces */ int ns; /* number of spaces to insert */ i = 0; j = 0; while (((c = *(in_line+i)) != '\0') && (c != '\n')) { if (c == '\t') { /* A tab */ ns = tab_size - (j%tab_size); for (k=1; k<=ns; k++) { *(out_line+j) = ' '; j++; } i++; } else { /* Not a tab */ *(out_line+j) = c; i++; j++; } } /* while */ if (c == '\n') Fatal ("ReplaceTabsBySpaces(): \\n found in string"); *(out_line+j) = '\0'; return; } /* * ReplaceSpacesByTabs * ******************* * A string in in_line must not contain tabs or \ns. * * in_line: line of text including tabs. * out_line: buffer for a line of text, with the tabs replaced by spaces. * tab_size: how many space are there to the tab. */ void ReplaceSpacesByTabs (in_line, out_line, tab_size) char *in_line; char *out_line; int tab_size; { int c; /* Character from the in_line. */ int i; /* Index into the in_line. */ int i1; /* Second index into in_line */ int j; /* Index into the out_line. */ j = 0; /* Index output buffer, initial value */ #ifdef DEBUG fprintf (stderr, "\nWord: %s\n", in_line); #endif /* Loop */ for (i=0;;i++) { /* Copy to output buffer. */ if ((c = in_line[i]) == '\t' || c == '\n') Fatal ("ReplaceSpacesByTabs: \\t or \\n in string."); #ifdef DEBUG fprintf (stderr, "i = %2d, j = %2d, char ' '%o (%c)\n", i, j, c, c); #endif out_line[j] = c; if (c == '\0') return; /* Trailing '\0' was just appended. */ /* We must watch for spaces to be replaced by tabs if we have gone beyond "tab_size_stop zero", if we are at a tab_size stop, and if at least two characters preceding the tab_size are spaces. */ if ((i%tab_size) == 0 && i>0 && in_line[i-1] == ' ' && in_line[i-2] == ' ') { /* j points to the mod tab_size == 0 character. Characters with index j-1 and j-2 as well as i-1 and i-2 are spaces. Go further back looking for spaces. */ j -= 3; i1 = i-3; while (i1 >= 0 && in_line[i1] == ' ' && (i1%tab_size) != (tab_size-1)) { #ifdef DEBUG fprintf (stderr, "[space] i1 = %2d, j = %2d, char ' '%o (%c)\n", i1, j, in_line[i1], in_line[i1]); #endif j--; i1--; } if (i1 == -1) { out_line[0] = '\t'; out_line[1] = c; j = 1; /* Will be incremented shortly. */ } else { out_line[++j] = '\t'; out_line[++j] = c; } #ifdef DEBUG fprintf (stderr, "[space done] i1 = %2d, j = %2d\n", i1, j); #endif } /* endif of "If there needs a tab to be inserted". */ j++; /* Point to next free entry of the output buffer. */ } /* for */ } /* * ReplaceASubString * ***************** * This function replaces a substring which must occur at the beginning * of a master string. If the string which replaces is longer than the * substring which is being replaced then the caller of this program * must make sure that the master string is long enough. * * str: a master string (long enough..., as indicated above) * le: length of substring which occurs at the beginning of * str which will be replaced by a new string. * repls: substring being put in place instead of the substring * of length le. */ void ReplaceASubString(str, le, repls) char *str; int le; char *repls; { int main_le; /* Main string length. */ int repls_le; /* Replacement string length. */ int diff; int i; /* Loop counter. */ repls_le = Strlen(repls); /* Substring length. */ main_le = Strlen(str); /* Main string length. */ /* Replacement string is as long as the string it replaces. */ if (repls_le == le) { for (i=0; i<le; i++) *(str+i) = *(repls+i); return; } /* Replacement string is longer as the string it replaces. The master string must be shifted to the right first. */ if (repls_le > le) { diff = repls_le - le; /* Difference in length. */ for (i=main_le; i>=0; i--) /* Shift string to the right by diff, including */ *(str+i+diff) = *(str+i); /* the trailing \0. */ for (i=0; i<repls_le; i++) /* Put in replacement string. */ *(str+i) = *(repls+i); return; } /* Replacement string is shorter than the string it replaces. The master string must be shifted to the left. */ diff = le - repls_le; /* Difference in length. */ for (i=repls_le; i<=main_le; i++) /* Shift string by diff to the left, including */ *(str+i) = *(str+diff+i); /* the trailing \0. */ for (i=0; i<repls_le; i++) /* Put in replacement string. */ *(str+i) = *(repls+i); return; }