svex

tsv explorer
git clone git://nsmpr.xyz/svex.git
Log | Files | Refs | README

svex.c (2209B)


      1 /* following line is required to make dprintf work */
      2 // #define _POSIX_C_SOURCE 200809L
      3 
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <unistd.h>
      7 #include <fcntl.h>
      8 #include <string.h>
      9 
     10 #include "arg.h"
     11 
     12 char *argv0;
     13 
     14 char *fname;
     15 
     16 char *buff;
     17 long blen;
     18 long curp, addr[2];
     19 
     20 void load(void);
     21 int parseaddr(char*, long*);
     22 char* getrow(long);
     23 int printrow(long);
     24 void edit();
     25 
     26 void
     27 usage (void)
     28 {
     29 	dprintf(2, "usage: %s file.tsv\n", argv0);
     30 	exit(0);
     31 }
     32 
     33 int
     34 main (int argc, char *argv[])
     35 {
     36 	buff = 0;
     37 	blen = 0;
     38 	ARGBEGIN{
     39 	default: usage();
     40 	} ARGEND
     41 	if (argc > 1) usage();
     42 	if (argc == 1) { 
     43 		fname = argv[0];
     44 		load();
     45 	}
     46 	curp = 1;
     47 	for (;;){
     48 		long n;
     49 		char ibuf[1024];
     50 		char *cmd;
     51 		n = read(0, ibuf, 1024);
     52 		ibuf[n] = 0;
     53 		cmd = ibuf + parseaddr(ibuf, addr);
     54 		switch (cmd[0]){
     55 		case 'p':
     56 			printrow(addr[0]);
     57 			break;
     58 		case '\0':
     59 		case 'q':
     60 			exit(0);
     61 			break;
     62 		default :
     63 			printf("?\n");
     64 		}
     65 		curp = addr[1];
     66 	}
     67 	return 0;
     68 }
     69 
     70 void
     71 edit(void)
     72 {
     73 	for (;;) {
     74 		
     75 	}
     76 }
     77 
     78 int
     79 parseaddr(char *buf, long *addr)
     80 {
     81 	long n;
     82 	char *bp;
     83 	*addr = curp; 
     84 	bp = buf;
     85 	switch (buf[0]){
     86 	case '.':
     87 		// current position
     88 		*addr = curp;
     89 		bp++;
     90 		break;
     91 	case '$':
     92 		// last line
     93 		break;
     94 	case '/':
     95 		// regex search forward
     96 		break;
     97 	case '?':
     98 		// regex search backward
     99 		break;
    100 	default:
    101 		n = strtol(buf, &bp, 10);
    102 		if (bp != buf) *addr = n;
    103 	}
    104 	return (bp - buf);
    105 }
    106 
    107 void
    108 load(void)
    109 {
    110 	int f;
    111 	long n;
    112 	char b[1024];
    113 	f = open(fname, O_RDONLY);
    114 	if (f == -1) {
    115 		dprintf(2, "failed to open file %s!\n", fname);
    116 		exit(-1);
    117 	}
    118 	while ((n = read(f, b, 1024)) > 0){
    119 		buff = realloc(buff, blen + n);
    120 		memcpy(buff+blen, b, n);
    121 		blen += n;
    122 	}
    123 	close(f);
    124 }
    125 
    126 char*
    127 getrow(long rn)
    128 {
    129 	char *p;
    130 	long n;
    131 	n = 1;
    132 	p = buff;
    133 	if (blen == 0) return 0;
    134 	while (n < rn) {
    135 		if (*p == '\n') n++;
    136 		p++;
    137 		if (p > buff + blen) return 0;
    138 	}
    139 	return p;
    140 }
    141 
    142 int
    143 printrow(long rn)
    144 {
    145 	char *p;
    146 	int col;
    147 	col = 0;
    148 	p = getrow(rn);	
    149 	if (p == 0) return 0;
    150 	printf("----[ %ld ]---------\n", rn);
    151 	for (;;) {
    152 		switch (*p){
    153 		case '\t':
    154 			write(1, "\n", 1);
    155 			col++;
    156 			break;
    157 		case '\n':
    158 			write(1, "\n\n", 2);
    159 			return 0;
    160 		default:
    161 			write(1, p, 1);
    162 		}
    163 		p++;
    164 		if (p > buff+blen) return -1;
    165 	}
    166 	return 0;
    167 }