📄 remap.c
字号:
/*
* Copyright 2005 Computing Research Labs, New Mexico State University
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
* OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef lint
#ifdef __GNUC__
static char rcsid[] __attribute__ ((unused)) = "$Id: remap.c,v 1.1.1.1 2005/09/21 21:40:39 mleisher Exp $";
#else
static char rcsid[] = "$Id: remap.c,v 1.1.1.1 2005/09/21 21:40:39 mleisher Exp $";
#endif
#endif
#include <stdio.h>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#else
#include <stdlib.h>
#include <unistd.h>
#endif
/*
* Structure for managing simple lists in place.
*/
typedef struct {
unsigned char *bfield;
unsigned long bsize;
unsigned long bused;
unsigned char **field;
unsigned long size;
unsigned long used;
} list_t;
/*
* Callback type used with the high speed text file reader function.
*/
typedef int (*scanlines_callback_t)(unsigned char *line, unsigned long linelen,
unsigned long lineno, void *client_data);
/*
* Various utility routines.
*/
#define setsbit(m, cc) (m[(cc) >> 3] |= (1 << ((cc) & 7)))
#define sbitset(m, cc) (m[(cc) >> 3] & (1 << ((cc) & 7)))
/*
* An empty string for empty fields.
*/
static unsigned char empty[1] = { 0 };
/*
* Assume the line is NULL terminated and that the `list' parameter was
* initialized the first time it was used.
*/
static void
splitline(unsigned char *separators, unsigned char *line,
unsigned long linelen, list_t *list)
{
int mult, final_empty;
unsigned char *sp, *ep, *end;
unsigned char seps[32];
/*
* Initialize the list.
*/
list->used = list->bused = 0;
/*
* If the line is empty, then simply return.
*/
if (linelen == 0 || line[0] == 0)
return;
/*
* If the `separators' parameter is NULL or empty, split the list into
* individual bytes.
*/
if (separators == 0 || *separators == 0) {
if (linelen > list->bsize) {
if (list->bsize)
list->bfield = (unsigned char *) malloc(linelen);
else
list->bfield = (unsigned char *) realloc(list->bfield, linelen);
list->bsize = linelen;
}
list->bused = linelen;
(void) memcpy(list->bfield, line, linelen);
return;
}
/*
* Prepare the separator bitmap.
*/
(void) memset((char *) seps, 0, 32);
/*
* If the very last character of the separator string is a plus, then set
* the `mult' flag to indicate that multiple separators should be
* collapsed into one.
*/
for (mult = 0, sp = separators; sp && *sp; sp++) {
if (*sp == '+' && *(sp + 1) == 0)
mult = 1;
else
setsbit(seps, *sp);
}
/*
* Break the line up into fields.
*/
for (final_empty = 0, sp = ep = line, end = sp + linelen;
sp < end && *sp;) {
/*
* Collect everything that is not a separator.
*/
for (; ep < end && *ep && !sbitset(seps, *ep); ep++) ;
/*
* Resize the list if necessary.
*/
if (list->used == list->size) {
if (list->size == 0)
list->field = (unsigned char **)
malloc(sizeof(unsigned char *) << 3);
else
list->field = (unsigned char **)
realloc((char *) list->field,
sizeof(unsigned char *) * (list->size + 8));
list->size += 8;
}
/*
* Assign the field appropriately.
*/
list->field[list->used++] = (ep > sp) ? sp : empty;
sp = ep;
if (mult) {
/*
* If multiple separators should be collapsed, do it now by
* setting all the separator characters to 0.
*/
for (; ep < end && *ep && sbitset(seps, *ep); ep++)
*ep = 0;
} else
/*
* Don't collapse multiple separators by making them 0, so just
* make the one encountered 0.
*/
*ep++ = 0;
final_empty = (ep > sp && *ep == 0);
sp = ep;
}
/*
* Finally, NULL terminate the list.
*/
if (list->used + final_empty + 1 >= list->size) {
if (list->used == list->size) {
if (list->size == 0)
list->field = (unsigned char **)
malloc(sizeof(unsigned char *) << 3);
else
list->field = (unsigned char **)
realloc((unsigned char *) list->field,
sizeof(char *) * (list->size + 8));
list->size += 8;
}
}
if (final_empty)
list->field[list->used++] = empty;
if (list->used == list->size) {
if (list->size == 0)
list->field = (unsigned char **)
malloc(sizeof(unsigned char *) << 3);
else
list->field = (unsigned char **)
realloc((char *) list->field,
sizeof(unsigned char *) * (list->size + 8));
list->size += 8;
}
list->field[list->used] = 0;
}
static int
scanlines(int fd, scanlines_callback_t callback, void *client_data,
unsigned long *lineno)
{
unsigned long lno;
int n, res, done, refill, bytes, hold;
char *ls, *le, *pp, *pe, *hp;
char buf[65536];
if (callback == 0)
return -1;
lno = 1;
(void) memset(buf, 0, 65536);
res = done = 0;
pp = ls = le = buf;
bytes = 65536;
while (!done && (n = read(fd, pp, bytes)) > 0) {
/*
* Determine the new end of the buffer pages.
*/
pe = pp + n;
for (refill = 0; done == 0 && refill == 0; ) {
while (le < pe && *le != '\n' && *le != '\r')
le++;
if (le == pe) {
/*
* Hit the end of the last page in the buffer.
* Need to find out how many pages to shift
* and how many pages need to be read in.
* Adjust the line start and end pointers down
* to point to the right places in the pages.
*/
pp = buf + (((ls - buf) >> 13) << 13);
n = pp - buf;
ls -= n;
le -= n;
n = pe - pp;
(void) memcpy(buf, pp, n);
pp = buf + n;
bytes = 65536 - n;
refill = 1;
} else {
/*
* Temporarily NULL terminate the line.
*/
hp = le;
hold = *le;
*le = 0;
if (callback && *ls != '#' && *ls != 0x1a && le > ls &&
(res = (*callback)((unsigned char *) ls, le - ls, lno,
client_data)) != 0)
done = 1;
else {
ls = ++le;
/*
* Handle the case of DOS CRLF sequences.
*/
if (le < pe && hold == '\n' && *le =='\r')
ls = ++le;
}
/*
* Increment the line number.
*/
lno++;
/*
* Restore the character at the end of the line.
*/
*hp = hold;
}
}
}
/*
* Return with the last line number processed.
*/
*lineno = lno;
return res;
}
static unsigned char a2i[128] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char odigits[32] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static unsigned char ddigits[32] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -