/*	util.c (misc non-gtk stuff) Ver 0.72

This program is free software: you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation, version 3 (or any later).  

This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without 
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
General Public License for more details.  You should have received a copy of the GNU General 
Public License along with this program.  If not, see <http://www.gnu.org/licenses/>.		*/

#include "main.h"

char *EXDline, Me[64];

int buflen (char *buffer) {
	int blen = strlen(buffer), NofL=0, i;
	if (buffer == NULL) return 0;
	for (i=0; i<=blen; i++) 
		if (((buffer[i] == 10)) || ((buffer[i] == 0) && (buffer[i-1] != 10))) NofL++;
	return NofL;
}


int copytmp (char *tmp, char *perm) {
	int retv = 0;
	char *line;
	FILE *fstRO, *fstW;
	if ((fstRO=fopen(tmp, "r")) == NULL) return -4;
	if ((fstW=fopen(perm, "w")) == NULL) {
		fclose(fstRO); return -5;}
	while ((line=linein(fstRO)) != NULL) {fprintf(fstW,"%s",line);free(line);}
	if ((fclose(fstRO)) != 0) retv = -1;
	if ((fclose(fstW)) != 0) retv -= 2;
	if (unlink(tmp)<0) retv -= 10;
	return retv;
}


char *defluff (char *string) {		/* GNOME drag and drop strings can be \r\n terminated */
	int len=strlen(string), i;
	char *new_line=ec_malloc(len+1);
	if (Debug>2) { g_print("defluff() ++%s++\n",string); }
	strcpy(new_line,string);
	for (i=0;i<len;i++) if ((new_line[i]==' ') || (new_line[i]=='\n') || (new_line[i]=='\r')) 
		{ new_line[i]='\0'; break; }
	return new_line;
}
	

void *ec_malloc (size_t bytes) {
	void *assign;
	assign = calloc(bytes,1);	
	if (assign == NULL) {
		fprintf(stderr, "!!! %s ec_malloc(): CALLOC FAILURE, OUT OF MEMORY !!!", Me);
		gtk_main_quit();}
	return assign;
}


int fdreadin (char *source, char *buffer, char end, int max, int offset) {
	int i=0;
	char *errmsg, ch=-9;
	int FDIN=open(source,O_RDONLY);
	if (FDIN<3) {
		errmsg=strerror(errno);
		strcpy(buffer,errmsg);
		return 0;
	}
	if (offset>0) lseek(FDIN,offset,SEEK_SET);
	while ((ch!=end) && (i<max)) {
		if (read(FDIN,&ch,1)!=1) break;
		buffer[i]=ch;
		i++;
	}
	buffer[i]='\0';
	close(FDIN);
	return i;
}


int filelen (char *file) {
	struct stat info;

	if (Debug>1) { g_print("filelen() %s\n",file); fflush(stdout); }

	if (stat(file,&info)<0) { 
		perror("\tstat"); 
		return -1; 
	}
	else return (int)info.st_size;
}


char *linein (FILE *stream) {	/* uses malloc */ 
	int c=0;		
	char *line = NULL, buffer[1024], byte, kb=0, *tmp;
	memset(buffer,0,1024);

	if (Debug>2) { g_print("linein()..."); fflush(stdout); }
	
	while (fread(&byte,1,1,stream)==1) {
		buffer[c]=byte;
		c++;
		if (byte=='\n') break;
		if (c==1024) {
			kb++;
			if (kb>1) { if (!(tmp=realloc(line,1024*kb))) { fprintf(stderr, "!!!%s linein() REALLOC FAILED, OUT OF MEMORY\n", Me); return line; }
				line=tmp; }
			else { line=ec_malloc(strlen(buffer)+1); line[0]='\0'; }
			strcat(line,buffer);
			memset(buffer,0,1024);
			c=0;
		}				
	}		
	if (c==0) return line;
	if (kb) { if (!(tmp=realloc(line,kb*1024+strlen(buffer)+1))) {
		fprintf(stderr, "!!!%s linein() REALLOC FAILED, OUT OF MEMORY\n", Me); return line; }
		line=tmp;
	} else line=ec_malloc(strlen(buffer)+1);
	strcat(line,buffer);
	if (Debug>2) { g_print("%s",line); fflush(stdout); }
	return line;
}


void onenwline (char *buffer) {		/* null terminate at newline */
	int i, len=strlen(buffer);
	for (i=0;i<len;i++) if (buffer[i]=='\n')
		{ buffer[i]='\0'; break; }
}


int regexp (char *string, char *patrn) {	/* used by searchlight() */
	int len=0;			
	regex_t rgT;
	regmatch_t match;
	regcomp(&rgT,patrn,REG_EXTENDED);
	if ((regexec(&rgT,(char*)string,1,&match,0)) == 0) {
		rgxp.bgn = (int)match.rm_so;
		rgxp.end = (int)match.rm_eo;
		len = rgxp.end-rgxp.bgn;
	}
	regfree(&rgT);
	if (Debug>1) g_print("regexp() B=%d E=%d returning %d\n",rgxp.bgn,rgxp.end,len);
	return len;
}


char *returnline (char *file, char *match) {		/* uses malloc */
	int len=strlen(match);				
	char *line, *retline;
	FILE *fstRO = fopen(file, "r");
	if (fstRO == NULL) return NULL;
	while ((line=linein(fstRO))) {
		if (Debug>2) fprintf(stderr,"returnline() %d...\"%s\" \"%s\"\n",len,match,line);
		if (!strncmp(line,match,len)) {
			retline=ec_malloc(strlen(line)-len+1);
			strcpy(retline,&line[len]);	
			free(line);
			if ((fclose(fstRO)) != 0) perror("see.h: in returnline() fclose fail");
			return retline;
		}
		free(line);
	}
	if ((fclose(fstRO)) != 0) perror("see.h: in returnline() fclose fail");
	return NULL;	
}


void sortintray (int *ray, int len) {
	int i, flag=0, tmp;
	if (Debug>1) g_print("sortintray()...%d\n",len);
	if (len<2) return;
	while (flag==0) {
		for (i=0;i<len-1;i++) {
			if (ray[i]>ray[i+1]) {
				tmp=ray[i+1];
				ray[i+1]=ray[i];
				ray[i]=tmp;
				flag++;
			}
		}
		if (flag==0) break;
		flag=0;
	}
}

 
int streamline (FILE *IN, char **line, int bsize) {   /* for loadlist */
	int len;
	char buffer[bsize];
	if (!(fgets(buffer,bsize,IN))) return 0;
	len=strlen(buffer);
	if (buffer[len-1]=='\n') buffer[len-1]=0;   // remove newline
	if (!(*line=malloc(len))) return -1;
	strncpy(*line,buffer,len);
	return len;
}


int strexd (int EXPlen, char *string) {
	char *ptr;
	int len = strlen(string);
	if (EXPlen == 0) {
		EXDline = ec_malloc(len+1);
		strcpy(EXDline,string);
		return len;	
	} else { EXPlen += len;
		ptr = realloc(EXDline,EXPlen+1);
		if (ptr) EXDline=ptr;
		else { 	puts("!!! see: realloc failure in strexd() !!!");
			gtk_main_quit(); }
		strcat(EXDline,string);
		return EXPlen;
	}
}


char *strsub (const char *string, char *newname) {   /* used by exec_proc() */
	char copy[strlen(string)+1], *ptr, *rp;   /* !never screw with a gtk const char directly... */
	strcpy(copy,string);	
	ptr=strstr(copy,"SEEBUF");
	rp=ec_malloc(strlen(string)+(strlen(newname)-6)+8);  /* room for redirect */
	ptr[0]='\0'; /* destructive of copy */
	sprintf(rp,"%s%s%s",copy,newname,&ptr[6]);
	return rp;
}


int utfadj (char *buffer, int pos) {  /* used by searchlight() */
	int i, count=0;
	if (Debug>2) g_print("utfadj() %d...",pos);
	for (i=0;i<pos;i++) {
		if (((unsigned char)buffer[i]>=0x80) && ((unsigned char)buffer[i]<=0xBF)) continue;		
		else count++;
	}
	return count;
}


char *writeout (char *buffer, char *file, int *ptr) {
	int done, size, newfd=open(file,O_WRONLY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE);
	if (newfd==-1) return strerror(errno);
	size=strlen(buffer); 
	done=write(newfd, buffer, size);
	close(newfd);
	if (done==-1) return strerror(errno);
	*ptr=done;
	return NULL;
} 
	
	
