|
|
1.1 ! root 1: #include "../h/rt.h" ! 2: ! 3: /* ! 4: * map(s1,s2,s3) - map s1, using s2 and s3. ! 5: */ ! 6: Xmap(nargs, arg3, arg2, arg1, arg0) ! 7: int nargs; ! 8: struct descrip arg3, arg2, arg1, arg0; ! 9: { ! 10: register int i; ! 11: register char *s1, *s2, *s3; ! 12: char sbuf1[MAXSTRING], sbuf2[MAXSTRING], sbuf3[MAXSTRING]; ! 13: static char maptab[MAXSTRING]; ! 14: extern char *alcstr(); ! 15: ! 16: /* ! 17: * s1 must be a string; s2 and s3 default to &ucase and &lcase, ! 18: * respectively. ! 19: */ ! 20: if (cvstr(&arg1, sbuf1) == NULL) ! 21: runerr(103, &arg1); ! 22: defany(&arg2, &ucase); ! 23: defany(&arg3, &lcase); ! 24: ! 25: /* ! 26: * If s2 and s3 are the same as for the last call of map, ! 27: * the some old values, namely maps2, maps3, and maptab ! 28: * can be reused. Otherwise, the information must be ! 29: * recomputed. ! 30: */ ! 31: if (maps2.type != arg2.type || maps3.type != arg3.type || ! 32: BLKLOC(maps2) != BLKLOC(arg2) || BLKLOC(maps3) != BLKLOC(arg3)) { ! 33: maps2 = arg2; ! 34: maps3 = arg3; ! 35: /* ! 36: * s2 and s3 must be strings and of the same length. ! 37: */ ! 38: if (cvstr(&arg2, sbuf2) == NULL) ! 39: runerr(103, &arg2); ! 40: if (cvstr(&arg3, sbuf3) == NULL) ! 41: runerr(103, &arg3); ! 42: if (STRLEN(arg2) != STRLEN(arg3)) ! 43: runerr(208, NULL); ! 44: /* ! 45: * The array maptab is used to perform the mapping. First, maptab[i] ! 46: * is initialized with i for i from 0 to MAXSTRING-1 (256). Then, ! 47: * the for each character in s2, the position in maptab corresponding ! 48: * the value of the character is assigned the value of the character ! 49: * in s3 that is in the same ordinal position as the character from s2. ! 50: * For example, if s2 is "abc", and s3 is "123", the assignments are: ! 51: * maptab['a'] = '1' ! 52: * maptab['b'] = '2' ! 53: * maptab['c'] = '3' ! 54: * Note that the 0..256 (really should be 0..255!) initialization ! 55: * causes unmapped characters to be themselves, for example, ! 56: * maptab['d'] == 'd'. ! 57: */ ! 58: s2 = STRLOC(arg2); ! 59: s3 = STRLOC(arg3); ! 60: for (i = MAXSTRING - 1; i >= 0; i--) ! 61: maptab[i] = i; ! 62: for (i = 0; i < STRLEN(arg2); i++) ! 63: maptab[s2[i]&0377] = s3[i]; ! 64: } ! 65: ! 66: if (STRLEN(arg1) == 0) { ! 67: arg0.type = D_NULL; ! 68: INTVAL(arg0) = 1; ! 69: return; ! 70: } ! 71: ! 72: /* ! 73: * The result is a string the size of s1, so ensure that much space. ! 74: */ ! 75: i = STRLEN(arg1); ! 76: sneed(i); ! 77: s1 = STRLOC(arg1); ! 78: ! 79: /* ! 80: * Create the result string, but specify no value for it. ! 81: */ ! 82: STRLEN(arg0) = i; ! 83: STRLOC(arg0) = s2 = alcstr(NULL, i); ! 84: /* ! 85: * Buzz through the string using values in maptab to do the mapping. ! 86: */ ! 87: while (i-- > 0) ! 88: *s2++ = maptab[(*s1++)&0377]; ! 89: } ! 90: ! 91: Procblock(map,3)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.