Example #1
0
static STRBUF *conv(iconv_t ic, STRBUF *buf)
{
	/* FIXME: This functionality belongs into strbuf.c */
	ICONV_CHAR *doc;
	char *out, *outbuf;
	size_t inleft, outleft = 0;
	size_t r;
	size_t outlen = 0;
	const size_t alloc_step = 4096;
	STRBUF *output;

	inleft = strbuf_len(buf);
	doc = (ICONV_CHAR*)strbuf_get(buf);
	outlen = alloc_step; outleft = alloc_step;
	outbuf = ymalloc(alloc_step);
	out = outbuf;
	outleft = alloc_step;

	do {
		if (!outleft) {
			outlen += alloc_step; outleft += alloc_step;
			yrealloc_buf(&outbuf, &out, outlen);
		}
		r = iconv(ic, &doc, &inleft, &out, &outleft);
		if (r == (size_t)-1) {
			if(errno == E2BIG) {
				outlen += alloc_step; outleft += alloc_step;
				if (outlen > (strbuf_len(buf) << 3)) {
					fprintf(stderr, "Buffer grew to much. "
						"Corrupted document?\n");
					exit(EXIT_FAILURE);
				}
				yrealloc_buf(&outbuf, &out, outlen);
				continue;
			} else if ((errno == EILSEQ) || (errno == EINVAL)) {
				char skip = 1;

				/* advance in source buffer */
				if ((unsigned char)*doc > 0x80)
					skip += utf8_length[(unsigned char)*doc - 0x80];
				doc += skip;
				inleft -= skip;

				/* advance in output buffer */
				*out = '?';
				out++;
				outleft--;

				continue;
			}
			fprintf(stderr, "iconv returned: %s\n", strerror(errno));
			exit(EXIT_FAILURE);
		}
	} while(inleft != 0);

	if (!outleft) {
		outbuf = yrealloc(outbuf, outlen + 1);
	}
	*out = '\0';

	output = strbuf_slurp_n(outbuf, (size_t)(out - outbuf));
	strbuf_setopt(output, STRBUF_NULLOK);
	return output;
}
Example #2
0
/* This version creates records stored in uniocde internally.   */
void
read_database()
{
	FILE *fp;
    const char procname[]="read_database" ;
	register int i;

	char mbsbuf[BUFSIZ] ;	/* 1024 characters per
							   line on Mac Os X */
	/* Det ser mere ut som om det er en db-entry som er på 1024 tegn!i den må
	   bli litt større 256 tegn per linje er passe stort nok! 64 tegn per felt
	   skulle også holde, også! */
    
    /* If a file didn't exist from the commandline, an index file has been
    created if we come here. there is more, if we then choose not to make
    a single entry before we quit, then the file will be deleted in the
    finish() handler. */
    
    fp = open_db() ;
	/* Allocate some entries in array.  16 is  arbitrary nr.    */
	dbsize = MAXDBLINES;
	dbentries = 0;

	if ((db = (dbrecord *)calloc((size_t) dbsize ,sizeof(dbrecord))) == NULL) {
            yerror(YMALLOC_ERR,procname,"db",YX_EXTERNAL_CAUSE ) ;
    }
	/* Until we hit end of file...                              */
	while (!feof(fp)) {
		/* If we need to, allocate more entries.                */
		if (dbentries >= dbsize) {
			dbsize *= 2;
			db = yrealloc(db, dbsize * sizeof(dbrecord),procname,"db");

		}
		/* Read in one entry at a time.                         */
		for (i = 0; i < idx.idx_nlines; i++) {	/* GLOBAL */
			/* If we hit end of file before getting complete    */
			/* entry, then toss this one.                       */
            /* TODO: BUFSIZ skiftes ut */
			if (fgets(mbsbuf, (int)BUFSIZ, fp) ==
			    NULL)
				goto out;
			register size_t mbuflen = (strlen(mbsbuf) - 1);

			/* Save length of line                              */
			mbsbuf[mbuflen] = '\0';	/* remove newline           */

			/* hva gjør vi med tomme linjer?? */
			if (mbuflen > 0) {
				int32_t reslen = 0;
                /* TODO: we also need to improve errors in uniocFromUTF8_alloc
                   that would be the simplest so we never check for null upon 
                   return from it.(can be too many causes for errors to analyze
                   hindsightly. */
				db[dbentries].db_lines[i] =
				    unicodeFromUTF8_alloc(&reslen, mbsbuf,
							  (size_t) mbuflen);
				if (db[dbentries].db_lines[i] == NULL)
                    yerror(YMALLOC_ERR,procname,"db[dbentries].dblines[i]",YX_EXTERNAL_CAUSE ) ;

				db[dbentries].db_lens[i] = reslen;
			} else {
				db[dbentries].db_lines[i] = NULL;
				db[dbentries].db_lens[i] = 0;
			}

		}
		/* Mark entry as valid, increase number of entries.     */
		db[dbentries].db_flag = DB_VALID;
		dbentries++;
	}
 out:
	fclose(fp);
	UErrorCode status = U_ZERO_ERROR;

	compareCollator = ucol_open(getCollation(), &status);
	if (U_SUCCESS(status)) {
        if (!reverse_data) { 
		qsort(db, (size_t) dbentries, sizeof(dbrecord),
		      (compFunc) dbsort);
        } else {
		    qsort(db, (size_t) dbentries, sizeof(dbrecord),
		      (compFunc) reverse_dbsort);
            
        }
	} else {
        y_icuerror( YICU_CRECOLL_ERR, procname, "compareCollator", status ) ;
	}
	ucol_close(compareCollator);

	return;
}
Example #3
0
static void yrealloc_buf(char **buf, char **mark, size_t len) {
	ptrdiff_t offset = *mark - *buf;
	*buf = yrealloc(*buf, len);
	*mark = *buf + offset;
}
Example #4
0
 /*
    Returns whether we should save our changes or not.

    Edits an existing an entry. This routine is far to big, and handles
    everything, from movement between fields, and editing fields, even
    painting the screen.

 */
int
edit_entry(dbrecord * entry, const char *operationDesc, const char *entryDesc)
{
	int *len;
	int col0;
	wchar_t *line=NULL;
	char tbuf[MAXSCREENWIDTH];
	int code = 0;
	wchar_t ch;
	dbbuffer tmp;
	register int i, j, row, col;
    initHeading() ;
	/* Where is "column zero"? To right of longest field name.  */
	col0 = idx.idx_maxlen + 2;

	 clear();		/* Clear the screen.                            */
    initEntryLine() ;
    paintHeading(operationDesc) ;
	/* get max col TODO: change this when sigwhinch */
    /* first time: allocat wchar fulldbdir name
       fulldbdir is a static.*/
	for (row = STARTROW; row < (idx.idx_nlines+STARTROW); row++) { 
		/* print field names.                                   */
		mvaddwstr(row, 0, idx.idx_lines[row-STARTROW]);
	}
	/* Allocate some space in a temporary entry, and copy entry */
	/* to be edited into it.  This way they can abort the edit. */
	/* Here we need to allocate some extra space so we can edit */

	for (i = STARTROW; i < (idx.idx_nlines+STARTROW); i++) {
        int k = i-STARTROW ;
		if (entry->db_lens[k] == 0) {
			/* Allocate memory for this line.                   */
            size_t linelen = (MAXSCREENWIDTH * sizeof(wchar_t));
			tmp.db_lines[k] =
                 (wchar_t *) ymalloc(linelen,
                    "edit_entry","tmp.db_lines[k]" );
            memset(tmp.db_lines[k],0,linelen);
			tmp.db_lens[k] = 0;
		} else {
			/* Copy and print the line from the entry.          */
			tmp.db_lines[k] =
			    wcsFromUnicode_alloc((size_t *) & tmp.db_lens[k],
						 entry->db_lines[k],
						 (int32_t) entry->db_lens[k]);
			if (tmp.db_lines[k] == NULL) {
                yerror( YICU_CONV_ERR ,"edit_entry->wcsFromUnicode_alloc", "tmp.db_lines[k]", YX_EXTERNAL_CAUSE ) ;
			}
			/* reallocates more space to maximum linebuffer size. */
			tmp.db_lines[k] =
			    (wchar_t *) yrealloc(tmp.db_lines[k], (size_t)
						(MAXSCREENWIDTH * sizeof(wchar_t)),"edit_entry","tmp.db_lines[k]");
		}

		move(i, col0);
		clrtoeol();
		if (tmp.db_lens[k] > 0) {
			addwstr(tmp.db_lines[k]);
		}
	}			/* *could* have factored out the index code.              */
	col = col0;
	row = STARTROW;		/* row er hvilke rad i recorden (felt). */

	move(row, col);
	refresh();
	/* Editing entry. We provide basic EMACS-style cntrl chars. */
	while ((code = get_wch(&ch)) != EOF) {
		/* Get the current line and line length.                */
		line = tmp.db_lines[row-STARTROW];
		/* f.p. *len = &tmp.db_lens[row]; */
		len = &tmp.db_lens[row-STARTROW];
		switch (ch) {
		case CTRL('a'):	/* beginning of line            */
			col = col0;
			break;
		case KEY_LEFT:
		case CTRL('b'):	/* back character               */
			if (col > col0)
				col--;
			break;
		case CTRL('d'):	/* delete character             */
			if (col == (col0 + (int)wcslen(line))) {
				col--;
			} else if (*len) {
				/* Calculate position of character in string.   */
				int l = col - col0;

				/* Shuffle the string to the "left".            */
				while (l < *len) {
					line[l] = line[l + 1];
					l++;
				}
				*len -= 1;
				/* Delete the character on the screen.          */
				delch();
                if (col== (col0 + (int)wcslen(line)) ) {
                    --col ;
                }
			}

			break;
		case CTRL('e'):	/* end of line                  */
			col = col0 + *len;
			break;
		case KEY_RIGHT:
		case CTRL('f'):	/* forward character            */
			if ((col - col0) < *len)
				col++;
			break;
		case KEY_BACKSPACE:
		case CTRL('h'):	/* backspace delete             */
		case '\177':
			if (*len && ((col - 1) >= col0)) {
				/* Calculate position of character to delete.   */
				int l = col - col0 - 1;
				if (l < 0)
					break;
				/* Shuffle string "left".                        */
				while (l < *len) {
					line[l] = line[l + 1];
					l++;
				}

				*len -= 1;

				/* Delete the character from the screen.        */
				move(row, --col);
				delch();
			}
			break;
		case CTRL('k'):	/* kill line                    */
			if (len) {
                
			    int l = col - col0;

				line[l] = (wchar_t) '\0';
				*len = l;

				clrtoeol();
			}
			break;
		case CTRL('l'):	/* redraw screen                */
			wrefresh(curscr);
			break;
		case KEY_DOWN:
		case CTRL('n'):	/* next line                    */
			/* Wrap around to the top if necessary.             */
			if (++row >= (idx.idx_nlines+STARTROW))
				row = STARTROW; 
			/* If nothing in this column, move to nearest       */
			/* non-empty column.                                */
			if ((col - col0) > tmp.db_lens[row-STARTROW])
				col = col0 + tmp.db_lens[row-STARTROW];
			line[*len] = (wchar_t) '\0';
			break;
		case KEY_UP:
		case CTRL('p'):	/* previous line                */
			/* Wrap around if necessary.                        */
			if (--row < STARTROW)
				row = (idx.idx_nlines+STARTROW) - 1;

			/* If nothing in this column, move to nearest       */
			/* on-empty column.                                 */
			if ((col - col0) > tmp.db_lens[row-STARTROW])
				col = col0 + tmp.db_lens[row-STARTROW];
			line[*len] = (wchar_t) '\0';
			break;
		case CTRL('['):	/* save entry:  ESC or something...  */
			if (line[*len] != (wchar_t) '\0')
				line[*len] = (wchar_t) '\0';
			sprintf(tbuf, "Save %s entry in database (y/n)? ", entryDesc);
			ch = prompt_char(idx.idx_nlines + 2+ STARTROW, 0, tbuf, "yYnN");

			/* See what they said.                              */
			switch (ch) {
			case '\n':	/* never mind                       */
				move(idx.idx_nlines + 2, 0);
				clrtoeol();
				break;
			case 'Y':	/* save entry                       */
			case 'y':
				/* Copy the temporary entry into the real entry. */
				/* if there isn't anything to copy, then the entry db gets the value
				   NULL, and length 0 */
				for (i = 0; i < idx.idx_nlines; i++) {

					/* remove old contents in entry             */
					if (entry->db_lens[i] > 0) {
						free(entry->db_lines[i]);
						entry->db_lines[i] = NULL;
						entry->db_lens[i] = 0;
					} 
                    
                    if (tmp.db_lens[i] > 0) {
                        entry->db_lens[i]=tmp.db_lens[i] ;
						entry->db_lines[i] =
						    unicodeFromWcs_alloc((size_t *) &entry->db_lens[i],tmp.db_lines[i]);

					    if (entry->db_lines[i] == NULL) {
                            yerror( YICU_CONV_ERR ,"edit_entry->unicodeFromWcs_alloc", "entry->db_lines[i]", YX_EXTERNAL_CAUSE ) ;
                        }
                    } /* had a dangling else bug here ? */
					free(tmp.db_lines[i]);
                    tmp.db_lines[i] = NULL ;
				    tmp.db_lens[i] = 0;
				}
				return (1);
			case 'N':	/* don't save entry                 */
			case 'n':
				/* Free temporary memory.                       */
				for (i = 0; i < idx.idx_nlines; i++) {
					tmp.db_lens[i] = 0;
					free(tmp.db_lines[i]);
					tmp.db_lines[i] = NULL;
				}
				return (0);
			}
			break;
		case '\r':	/* return the string            */
		case '\n':	/* go to next line                  */
			/* Wrap around if necessary.                        */
			if (++row >= (idx.idx_nlines+STARTROW))
				row = STARTROW;
			col = col0;
			break;
		default:	/* something else                   */
			/* User's kill character: accepted to del line too. */
			if (ch == KEY_DL) {
				move(row, col0);
				clrtoeol();
				col = col0;

				*line = (wchar_t) '\0';
				*len = 0;
			} else if (code != KEY_CODE_YES) {
				/* If it's a printable character, insert it into */
				/* the string.                                  */
				if (iswctype(ch, wctype("print"))) {
					if (col == (COLS - 1)) {
						beep();
						break;
					}
					/* Calculate character position.            */
					i = col - col0;

					/* If necessary, move string * to "right"   */
					/* to insert the character.                 */
					if (i < *len) {
						for (j = *len; j >= i; j--)
							line[j + 1] = line[j];
					}

					line[i] = ch;
					*len += 1;
					col++;

					/* Insert the character on the screen.       */
					InsWch((chtype) ch);

				}
			}
			break;
		}

		/* Move to the current row/column.                       */
		move(row, col);
		refresh();
	}
	return (0);
}