Category : C Source Code
Archive   : UNIXSTR.ZIP
Filename : STRKEY.C

 
Output of file : STRKEY.C contained in archive : UNIXSTR.ZIP
/* File : strkey.c
Author : Richard A. O'Keefe.
Updated: 20 April 1984
Defines: strkey()

strkey(dst, head, tail, options)
copies tail-head characters from head to dst according to the
options. If tail is NullS, it copies up to the terminating
NUL of head. This function is meant for doing comparisons as
by sort(1). The options are thus a string of characters
taken from "bdfin". In case the options came from somewhere
else other letters are ignored.

-b: leading layout characters are not copied.

-d: only letters, digits, and blanks are copied.
-i: only graphic characters (32..126) are copied.
-n: a numeric string is copied.
These options are incompatible, and the last is taken.

-f: upper case letters are copied as lower case.

The question of what to do with a numeric string is an interesting
one, and I don't claim that this is a brilliant answer. However,
the solution used here does mean that the caller can compare two
strings as strings without needing to know that they are numeric. A
number is copied as <9 digits>., where
is '-' for a negative number and '0' for a positive number.
The magic number 9 is defined to be DigitMagic.

The idea is that to compare two lines using the keys
-tx +m1.n1 -m2.n2
you do
h1 = strfield(line1, m1, n1, 0, 'x');
t1 = strfield(h1, 1, 0, 0, 'x');
strkey(buff1, h1, t1, "flags");
h2 = strfield(line2, m2, n2, 0, 'x');
t2 = strfield(h2, 1, 0, 0, 'x');
strkey(buff2, h2, t2, "flags");
... strcmp(buff1, buff2) ...

The point of all this, of course, is to make it easier to write new
utilities which are compatible with sort(1) than ones which are not.
*/

#include "strings.h"

#define DigitMagic 9

char *strkey(dst, head, tail, flags)
register char *dst, *head, *tail;
char *flags;
{
register int c;
int b = 0; /* b option? */
int f = 0; /* f option? */
int k = 0; /* 3->n, 2->d, 1->i, 0->none of them */

while (*flags) switch (*flags++|32) {
case 'b': b++; break;
case 'f': f++; break;
case 'i': k = 1; break;
case 'd': k = 2; break;
case 'n': k = 3; break;
default : /*ignore*/break;
}
flags = dst; /* save return value */

if (tail == NullS) for (tail = head; *tail; tail++) ;

if (b) while (head != tail && *head <= ' ') head++;

switch (k) {
case 0:
if (f) {
while (head != tail) {
c = *head++;
if (c >= 'A' && c <= 'Z') c |= 32;
*dst++ = c;
}
} else {
while (head != tail) *dst++ = *head++;
}
break;
case 1:
if (f) {
while (head != tail) {
c = *head++;
if (c >= 32 && c <= 126) {
if (c >= 'A' && c <= 'Z') c |= 32;
*dst++ = c;
}
}
} else {
while (head != tail) {
c = *head++;
if (c >= 32 && c <= 126) *dst++ = c;
}
}
break;
case 2:
if (f) f = 32;
while (head != tail) {
c = *head++;
if (c >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c == ' ') {
*dst++ = c;
} else
if (c >= 'A' && c <= 'Z') {
*dst++ = c|f;
}
}
break;
case 3:
if (*head == '-' && head != tail) {
*dst++ = *head++;
head++;
} else {
*dst++ = '0';
}
b = 0;
while (head != tail) {
c = *head;
if (c < '0' || c > '9') break;
b++, head++;
}
f = DigitMagic-b;
while (--f >= 0) *dst++ = '0';
head -= b;
while (--b >= 0) *dst++ = *head++;
if (*head == '.' && head != tail) {
*dst++ = *head++;
while (head != tail) {
c = *head++;
if (c < '0' || c > '9') break;
*dst++ = c;
}
/* now remove trailing 0s and possibly the '.' as well */
while (*--dst == '0') ;
if (*dst != '.') dst++;
}
break;
}
*dst = NUL;
return flags; /* saved initial value of dst */
}



  3 Responses to “Category : C Source Code
Archive   : UNIXSTR.ZIP
Filename : STRKEY.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/