#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxtofrom 10
/* ocountflag means that it will only count
how many entries there are then quit */
long from=0, to=0, end=0;
int inflag=0, outflag=0, ocountflag=0, delflag=0, commaflag=0;
char tester[100000]; /* if you have a line longer than this then you have a problem. */
char *filename;
void prepcomms(char *where)
{
int fromcount=0, tocount=0;
char cfrom[maxtofrom+8];
char cto[maxtofrom+8];
for (int j=0; where[j] && j<=(maxtofrom*2+8); j++) {
if (where[j]==',') { commaflag=1; continue; }
switch (where[j]) {
case 'i': inflag = 1;
break;
case 'p': outflag = 1;
break;
case 'd': delflag = 1;;
break;
case 'c': ocountflag = 1;
break;
}
if (!commaflag) cfrom[fromcount++] = where[j];
else cto[tocount++] = where[j];
}
if (commaflag) {
from = atol(cfrom);
to = atol(cto);
} else {
to = (from=atol(cfrom));
}
if (!from && commaflag && to) {
fputs("clip: must have a number before comma\n", stderr);
free(filename);
exit(1);
}
if (from > to) {
fputs("clip: first number must be less than second\n", stderr);
free(filename);
exit(1);
}
}
void cookargs(int c, char *v[])
{
if (c>1) {
for (int i=1; v[i]; i++) {
if (v[i][0]=='-' && v[i][1] && v[i][1]=='f' && v[i+1]) {
filename = v[i+1];
i++; /* makes cursor skip file name */
}
else prepcomms(v[i]);
}
if (!inflag && !outflag && !delflag && !ocountflag) {
fputs("usage: clip [-f filename] [justcount|in|out #,#|delete #,#]\n", stderr);
free(filename);
exit(1);
}
} else {
fputs("usage: clip [-f filename] [count|in|print #,#|delete #,#]\n", stderr);
free(filename);
exit(1);
}
}
int main(int argc, char *argv[])
{
filename = malloc(3000);
sprintf(filename, "%s/%s", getenv("HOME"), ".clipboard");
char delim[31] = "------------------------------\n";
FILE *filep;
long counter = 0;
cookargs(argc, argv); /* can change file name based on what comes after "-f" */
if ((filep=fopen(filename, "a+"))==NULL) {
fprintf(stderr, "clip: cannot open %s", filename);
free(filename);
exit(1);
}
if (inflag) {
char inbuf[1000000];
fread(inbuf, sizeof(inbuf), 1, stdin);
fprintf(filep, "%s%s", delim, inbuf);
fclose(filep);
free(filename);
exit(1);
}
while (fgets(tester, sizeof(tester), filep))
if (memcmp(tester, delim, sizeof(delim))==0)
end++;
rewind(filep);
if (ocountflag) {
printf("%ld\n", end);
goto ending; /* stops program after outputting count */
}
if (end==0) {
fputs("nothing to act on\n", stderr);
fclose(filep);
free(filename);
exit(1);
}
if (to>end) {
fputs("clip: end point too big\n", stderr);
fclose(filep);
free(filename);
exit(1);
}
if (!from && !to && commaflag) { from=1; to=end; }
if (!from && !to && !commaflag) { from = end; to = end; }
if (delflag) {
FILE *tdelfilep;
int delimflag=0;
if ((tdelfilep=fopen(".clipboard~~~", "w+"))==NULL) {
fputs("clip: cannot create temporary file\n", stderr);
fclose(filep);
free(filename);
exit(1);
}
while (counter <= end && fgets(tester, sizeof(tester), filep)) {
if (memcmp(tester, delim, sizeof(delim))==0) {
counter++;
delimflag=1;
continue;
}
if (counter < from || counter > to) {
fprintf(tdelfilep, "%s%s", delimflag?delim:"", tester);
delimflag=0;
}
}
rename(".clipboard~~~", filename);
goto ending;
}
if (outflag) {
while (counter <= end && fgets(tester, sizeof(tester), filep)) {
if (memcmp(tester, delim, sizeof(delim))==0) {
counter++;
continue;
}
if (counter >= from && counter <= to) {
fputs(tester, stdout);
}
}
}
ending:
free(filename);
fclose(filep);
return 0;
}