|
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: 9099 (0x238b) Types: TextFile Names: »stringfunc.c,v«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89 └─⟦34cc4e2f7⟧ »./UNRELEASED/xgdb3.2.tar.Z« └─⟦80fac5d7c⟧ └─⟦this⟧ »./RCS/stringfunc.c,v«
head 1.1; access ; symbols ; locks hubbard:1.1; strict; comment @ * @; 1.1 date 89.07.05.15.36.42; author hubbard; state Exp; branches ; next ; desc @Initial checkin, Beta version 0.1. @ 1.1 log @Initial revision @ text @\f #ifndef lint static char rcsid[] = "$Header$"; #endif /* * * Copyright 1988, 1989 * PCS Computer Systeme, GmbH * Munich, West Germany * * All rights reserved. * * This is unsupported software and is subject to change without notice. * PCS makes no representations about the suitability of this software * for any purpose. It is supplied "as is" without express or implied * warranty. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of PCS Computer Systeme not be used in * advertising or publicity pertaining to distribution of the software * without specific, written prior permission. * */ /* * Author: Jordan K. Hubbard * For: PCS Computer Systems, GmbH. * When: February 10th, 1989. * * $Log$ * */ #include "xgdb.h" #include <ctype.h> /* * Various silly string utilities.. */ /* * Given a string, return everything up to the first newline or the end. */ String oneLine(s) String s; { static char line[256]; int i = 0; Entry("oneLine"); if (!s) { Leave(NULL); } while (s && s[i] != '\n' && i < 255) { line[i] = s[i]; i++; } line[i] = '\0'; Leave(line); } /* * Given a path name, return just the file name with all preceeding directory * components stripped off. */ String strip_directory_prefix(s) String s; { Cardinal n; Entry("strip_directory_prefix"); if (!s) { Leave(s); } n = strlen(s); while (n) { if (s[n] == '/') break; n--; } Leave((s + (n ? n + 1 : 0))); } /* * Given a path name, return the directory components sans filename. * (counterpart to above). */ String strip_file_component(s) String s; { int len; char target[MAXPATHLEN]; Entry("strip_file_component"); if (!s || !strlen(s)) { Leave(NULL); } len = strlen(s); while (len && s[len] != '/') len--; if (len) { CPYN(target, s, len); Leave(target); } else Leave(s); } #define upper(c) if (c >= 'a' && c <= 'z') c -= 32 /* * Kludge, but close enough by government standards. Tries to derive * a class name from an application name. */ String class_from_name(s) String s; { static char name[50]; Entry("class_from_name"); if (s && strlen(s) > 1) { strcpy(name, s); upper(name[0]); upper(name[1]); Leave(name); } else Leave(s); } /* * Removes characters from "s" that fall into the range between s1 and * s2. Returns the number of characters clipped. */ int clipString(s, s1, s2) String s; int s1, s2; { int len; Entry("clipString"); ASSERT(NULLP(s)); len = strlen(s); if (s2 >= len) { s[s1] = '\0'; Leave(len - s1); } else { bcopy(s + s2, s + s1, len - s2); s[len - (s2 - s1)] = '\0'; Leave(s2 - s1); } } /* * Insert "len" characters from src into dest, starting at destlen. If * srclen + destlen > maxlen, roll off some characters, breaking at line * boundries if possible. */ int insertString(dest, destlen, maxlen, src, srclen) String dest, src; int destlen, maxlen, srclen; { int rolloff = 0; Entry("insertString"); ASSERT(NULLP(src) || NULLP(dest)); if (destlen + srclen > maxlen) { rolloff = (destlen + srclen) - maxlen; for (i = 0; i < destlen; i++) { if (dest[i] == '\n' && i >= rolloff) { rolloff = i + 1; break; } } destlen -= rolloff; bcopy(dest + rolloff, dest, destlen); } bcopy(src, dest + destlen, srclen); Leave(srclen + destlen); } /* * Convert number to string. */ String itoa(i) int i; { static char ret[32]; Entry("itoa"); sprintf(ret, "%d", i); Leave(ret); } /* * Do various rude things to a string, like expand tabs and * make control characters visible. * The expanded string is static storage and should be copied if * you want to save it across subsequent calls. * Strings expanding to more than MAX_EXPAND bytes are truncated. * * If map_newlines is set, newlines are presumed to be evil for some reason * and are mapped to this character. */ #define MAX_EXPAND 2500 String expand_string(s, map_newlines) register String s; char map_newlines; { register int i = 0, i2 = 0, col = 0; int len; static char tmp[MAX_EXPAND]; Entry("expand_string"); ASSERT(NULLP(s)); len = strlen(s); while (i < len && i2 < MAX_EXPAND) { if (isprint(s[i])) { tmp[i2++] = s[i]; col++; } else if (s[i] == '\t') { int tb = 4 - (col % 4), i3; for (i3 = 0; i3 < tb; i3++) { tmp[i2++] = ' '; col++; } } else if (s[i] == '\n') { if (!map_newlines) tmp[i2++] = s[i]; else tmp[i2++] = map_newlines; col = 0; } else { tmp[i2++] = '^'; tmp[i2++] = s[i] + 64; col += 2; } i++; } tmp[i2] = '\0'; Leave(tmp); } /* * Return span of string from p1 to p2, null terminating the * result. String spans > MAXSTR chars are trunctated. String * span is static storage and should be copied if you want to save * it across subsequent calls. */ #define MAXSTR 512 String substr(s, p1, p2) register String s; register int p1, p2; { static char ret[MAXSTR]; register int i = 0; Entry("substr"); ASSERT(NULLP(s)); if (p1 > p2) { puke("%p: start %d, end %d. start must be <= end", p1, p2); Leave(NULL); } if (p2 - p1 > MAXSTR) { puke("%p: end - start is > max len of %d", MAXSTR); Leave(NULL); } while (p1 <= p2) ret[i++] = s[p1++]; ret[i] = '\0'; Leave(ret); } /* * Concatenate two strings into static area, returning pointer to * result. */ String strconcat(s1, s2) register String s1, s2; { static char ret[MAXSTR]; Entry("strconcat"); strcpy(ret, s1); strcat(ret, s2); Leave(ret); } /* * Return integer subscript of character 'c' in string 's'. * (why doesn't this already exist in Unix?). */ int iindex(s, c) register char *s, c; { register char *cp; Entry("iindex"); if (NULLP(s)) Leave(-1); cp = index(s, c); if (cp) { Leave(cp - s); } else { Leave(-1); } } #define DIGIT(x) (isdigit(x) ? (x) - '0' : \ islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A') /* * Convert backslash notation to control characters, in place. * We can do this in place since the converted string will always smaller * than the original. * * Code grubbed from something by Jef Poskanzer (PD printf()), though * the parsing of numeric constants has been re-done. */ void ctrl(s) register String s; { register String op = s; register Cardinal c; unsigned int base = 0; int value = 0; ASSERT(NULLP(s)); while ((c = *s) != 0) { if (base == 0 && c != '\\') { *op = c; op++; s++; continue; } else if (c == '\\') s++; switch (*s) { case '\0': /* end-of-string: user goofed */ s--; break; case 'n': /* newline */ *op++ = '\n'; break; case 's': /* space */ *op++ = ' '; break; case 't': /* horizontal tab */ *op++ = '\t'; break; case 'r': /* carriage-return */ *op++ = '\r'; break; case 'f': /* form-feed */ *op++ = '\f'; break; case 'b': /* backspace */ *op++ = '\b'; break; case 'v': /* vertical tab */ *op++ = '\13'; break; /* A number. Hmmm. Might be octal, might be hex, might be decimal. */ case '0': if (base == 0) { if (s[1] == 'x' || s[1] == 'X') /* 0x.. is hex */ base = 16; else base = 8; /* 0xxx is octal */ value = 0; } case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* First time through means decimal */ if (base == 0) { base = 10; value = 0; } value = base * value - DIGIT(*s); if (!isdigit(s[1])) { /* that was the last number */ *op++ = abs(value); base = 0; } break; case 'X': case 'x': if (base != 16) /* not part of hex constant, back up */ s--; break; case '&': /* special zero-width `character' */ break; default: *op++ = *s; } s++; } *op = '\0'; } @