Ejemplo n.º 1
0
int main( int argc, char **argv )
{
	char file[MAX_FILENAME_LEN + 1];
	char *line, *prompt="> ";
	int i;

	if ( argc == 2 )
		ystrncpy( file, argv[1], MAX_FILENAME_LEN );
	else
		yerror( "missing filename\n" );

	restores( file );
	prints();
	restorer( file );

	for( i = 0; i < status.datan; i++ )
		readdata( status.dataf[i], i );

	port = gp_open( "400x400" );
	using_history();
	stifle_history(1000);
	sprintf( historyfile, "%s/%s", getenv("HOME"), HISTORYFILE );
	if ( !access (historyfile, R_OK) )
		if ( read_history(historyfile) )
			perror( "reading history" );
	while (1) {
		line=readline( prompt );
		if ( line ) {
			add_history( line );
			parser( line );

		} else printf( "\n" );
	}
	return 0;
}
Ejemplo n.º 2
0
/*
    gets the ICU ERROR CODE, and creates the string in question.
    I think the good way to do this is to set the ICU-error code
    before we call yerror, when yerror eyes the ERROR code, it knows
    it has to call us, and we'll provide the error string going with
    that code.
    TODO: explain how the look for/create database logic works.
*/
void
y_icuerror( int strIndex, const char *handler, const char *variable, UErrorCode errcode )
{
    char buf[80]="" ;
    strcpy(buf,variable );
    strcat (buf," ICU error: " ) ;
    strcat(buf, u_errorName(errcode)) ;
    yerror(strIndex, handler, buf,YX_EXTERNAL_CAUSE ) ;
}
Ejemplo n.º 3
0
void *
ymalloc( size_t sz,const char *fromHandler, const char *forVariable )
{
   void *p = malloc(sz ) ;
   if (p == NULL ) {
        yerror( YMALLOC_ERR, fromHandler, forVariable, YX_EXTERNAL_CAUSE ) ;
   }
   return p ;
}
Ejemplo n.º 4
0
void *
yrealloc( void *ptr, size_t sz, const char *fromHandler, const char * forVariable )
{
   void *p = realloc(ptr, sz ) ;
   if (p == NULL ) {
        yerror( YREALLOC_ERR, fromHandler, forVariable, YX_EXTERNAL_CAUSE ) ;
   }
   return p ;
}
Ejemplo n.º 5
0
/*
Removes any empty lines to avoid "invisible labels", the users comfort,
Returns 1 if the file still has contents,after "linting".
We don't remove any white space if the line has other contents before or after
text.
It is called from: 
*/
int 
labelFileOkAfterLinting(char *labelfn) 
{
    const char procname[]="labelFileOkAfterLinting" ;
	char buf[BUFSIZ];	/* 1024 characters per line on Mac Os X */
    FILE *fin=NULL, *fout=NULL;
    char *lblBckFname = makeBackupName(labelfn ) ;
	int	ret = rename(labelfn, lblBckFname);
    if (ret) {
        yerror(YFILE_RENMV_ERR,procname,lblBckFname,YX_EXTERNAL_CAUSE ) ; 
    }
    /* open the backup file for reading */
	if ((fin = fopen(lblBckFname, "r")) == NULL )  {
        yerror(YFILE_OREAD_ERR,procname,lblBckFname,YX_EXTERNAL_CAUSE ) ; 
    }
    /* reopen the label file for writing */
	if ((fout = fopen(labelfn, "w")) == NULL )  {
        yerror(YFILE_CREAT_ERR,procname,labelfn,YX_EXTERNAL_CAUSE ) ; 
    }

    while (!feof(fin) ) {
        /* read it line by line */
		if (fgets(buf, (int)BUFSIZ , fin )== NULL )  {
            if (ferror(fin)) {
                    yerror(YFILE_FREAD_ERR,procname,lblBckFname,YX_EXTERNAL_CAUSE ) ; 
            }
            break ;
        }
        /* check if the line contains anything but whitespace */
        
        if (!onlyspaces(buf)) {
            if ( fputs(buf,fout) == EOF  ) { /* compatibility */
                    yerror(YFILE_FWRITE_ERR,procname,labelfn,YX_EXTERNAL_CAUSE ) ; 
            }
        }
    }
    fclose(fin) ;
    fclose(fout ) ;
	if ( file_is_empty(labelfn ) ) {
		return 0 ;
	} else {
    	return  1 ;
	}
}
Ejemplo n.º 6
0
/*
 * create_db - execute an editor to allow the person to create the
 *         index definition file.

 * The rules for creating the name of the database file, and the provider
 * of the new name resides in the function newlabelFilename that resides in
 * newlabelFilename 
 */
void
create_db(void)
{
	int pid;

	char *editor;

	register int row;

	char *fname=NULL; 
    set_modes() ;
	/* Clear the screen and move to the top. */
	clear();
	move(0, 0);

	/* Print out the explanatory message.  */
	for (row = 0; message[row].m_line != NULL; row++)
		printw(message[row].m_line, message[row].m_arg);

	/* Give the user a chance to read it.  Wait till they
	 * type a carriage return before proceeding.  */
	prompt_char(++row, 0, "Type RETURN to continue: ", "\n\r");

	/* Use the editor the user prefers, or EDITOR if
	 * he doesn't have anything set.  */
	if ((editor = getenv("EDITOR")) == NULL)
		editor = EDITOR;
	/* get the label file name.  */
    fname = getFullLabelFileName() ;

	/* Go back to normal tty modes.  */
	reset_modes();

	/* Spawn a child process.  */
	if ((pid = fork()) < 0) {
        yerror(YFORK_PROC_ERR,"create_db",editor,YX_EXTERNAL_CAUSE ) ;
	}
	/* Execute the editor. */
	if (pid == 0) {
		reset_modes();
		execl(editor, editor, fname, NULL);
		perror(editor);
		exit(1);
	}
	/* Wait for the editor to finish.  */
	while (wait((int *)0) != pid) ;
    /* loose the reference to the filename */
    fname = NULL; 
	/* Set the tty modes up again.  */
	set_modes();
}
Ejemplo n.º 7
0
void readparams( char *file )
{
	FILE *in;

	if ((in = fopen(file, "r")) == NULL)
		yperror( "can't open config file '%s'", file );

	paramcount = 0;
	while ( !feof(in) ) {
		if ( fscanf( in, PARAM_FMT, param[paramcount].name, param[paramcount].value ) != 2 )
			yerror("file format error in config file '%s'\n", file );
		paramcount++;
	}
/*	qsort( param, paramcount, sizeof(struct params), paramcompar ); */
	fclose(in);
}
Ejemplo n.º 8
0
/*
 * Search file in current runtime path, translate it and
 * execute bytecode by current runtime. Return boolean
 * indicating if translation was sucessful.
 * */
int32_t Yoyo_interpret_file(ILBytecode* bc, YRuntime* runtime, wchar_t* wpath) {
	Environment* env = runtime->env;
	FILE* file = env->getFile(env, wpath);
	if (file == NULL) {
		yerror(ErrorFileNotFound, wpath, yoyo_thread(runtime));
		return false;
	} else {
		YThread* th = yoyo_thread(runtime);
		CompilationResult res = yoyoc((YoyoCEnvironment*) env,
			file_input_stream(env->getFile(env, wpath)), wpath);
		if (res.pid != -1) {
			invoke(res.pid, bc, runtime->global_scope, NULL, th);
//			ILProcedure* proc = bc->procedures[res.pid];
//			proc->free(proc, bc);
			if (th->exception != NULL) {
				YValue* e = th->exception;
				th->exception = NULL;
				wchar_t* wstr = toString(e, th);
				fprintf(th->runtime->env->out_stream, "%ls\n", wstr);
				if (e->type == &th->runtime->ObjectType) {
					YObject* obj = (YObject*) e;
					if (OBJECT_HAS(obj, L"trace", th)) {
						YValue* trace = OBJECT_GET(obj, L"trace", th);
						wchar_t* wcs = toString(trace, th);
						fprintf(runtime->env->out_stream, "%ls\n", wcs);
						free(wcs);
					}
				}
				free(wstr);
				return -1;
			}
			return res.pid;
		}
		fprintf(runtime->env->out_stream, "%ls\n", res.log);
		free(res.log);
	}
	return -1;
}
Ejemplo n.º 9
0
/* using this one.                                          */
int
dbsort(dbrecord * a, dbrecord * b)
{
	register int i, n;

	/* Sort invalid entries to the end.                     */
	if ((a->db_flag & DB_VALID) == 0) {
		if ((b->db_flag & DB_VALID) == 0)
			return (0);

		return (1);
	}

	if ((b->db_flag & DB_VALID) == 0)
		return (-1);

	/* Sort on first field, then try secondary fields.      */
	n = 0;
	if (compareCollator != NULL) {
		for (i = 0; (i < idx.idx_nlines) && (n == 0); i++) {
			UCollationResult res =
			    ucol_strcoll(compareCollator,
					 (UChar *) a->db_lines[i], -1,
					 (UChar *) b->db_lines[i], -1);

			if (res == UCOL_LESS) {
				n = -1;
			} else if (res == UCOL_GREATER) {
				n = 1;
			} else {
				n = 0;
			}
		}
	} else {
        yerror(YICU_COLLATO_ERR,"dbsort","comparecollator",YX_EXTERNAL_CAUSE ) ;
	}
	return (n);
}
Ejemplo n.º 10
0
/*
 * This routine parses the input stream, and
 * returns if it accepts, or if an unrecoverable syntax
 * error is encountered.
 */
yyparse()
{
	register int *ps, n, *p;
	int paniced, *panicps, idfail;

	yystate = 0;
	yychar = yylex();
	OY.Yychar = -1;
	yyshifts = 3;
	paniced = 0;
	ps = &yys[0]-1;
	yypv = &yyv[0]-1;
#ifdef PXP
	yypw = &yyw[0]-1;
#endif

stack:
	/*
	 * Push new state and value.
	 */
	if (yypv >= &yyv[MAXDEPTH-1]) {
		yerror("Parse stack overflow");
		pexit(DIED);
	}
	*++ps = yystate;
	*++yypv = yyval;
#ifdef PXP
	yypw++;
#endif
newstate:
	/*
	 * Locate parsing actions for the
	 * new parser state.
	 */
	p = &yyact[ yypact[yystate+1] ]; 
actn:
	/*
	 * Search the parse actions table
	 * for something useful to do.
	 * While n is non-positive, it is the negation
	 * of the token we are testing for.
	 */
#ifdef PI
	if ((n = *p++) <= 0) {
		if (yychar < 0)
			yychar = yylex();
		do
			if ((n += yychar) != 0)
				p++;
		while ((n = *p++) <= 0);
	}
#else
	while ((n = *p++) <= 0)
		if ((n += yychar) != 0)
			p++;
#endif
	switch (n >> 12) {

		/*
		 * Shift.
		 */
		case 2:
#ifdef PXP
			yypw[1].Wseqid = yyseqid;
			yypw[1].Wcol = yycol;
#endif
			OYcopy();
			yystate = n & 07777;
			yyval = yylval;
#ifdef PI
			yychar = -1;
#else
			yychar = yylex();
#endif
			yyshifts++;
			yytshifts++;
			goto stack;

		/*
		 * Reduce.
		 */
		case 3:
			n &= 07777;
			N = yyr2[n];
			if (N == 1 && OY.Yychar == YID && !yyEactr(n, yypv[0])) {
				idfail = 1;
				goto errin;
			}
			OY.Yychar = -1;
			ps -= N;
			yypv -= N;
#ifdef PXP
			yypw -= N;
#endif
			yyval = yypv[1];
			yyactr(n);
			/*
			 * Use goto table to find next state.
			 */
			p = &yygo[yypgo[yyr1[n]]];
			while (*p != *ps && *p >= 0)
				p += 2;
			yystate = p[1];
			goto stack;

		/*
		 * Accept.
		 */
		case 4:
			return;

		/*
		 * Error.
		 */
		case 1:
			idfail = 0;
errin:
			if ((paniced || yyshifts != 0) && yyrecover(ps, idfail)) {
				paniced = 0;
				ps = Ps;
				yystate = *ps;
				goto newstate;
			}
			/*
			 * Find a state where 'error' is a
			 * legal shift action.
			 */
			if (paniced && yyshifts <= 0 && ps >= panicps) {
				yypv -= (ps - panicps) + 1;
#ifdef PXP
				yypw -= (ps - panicps) + 1;
#endif
				ps = panicps - 1;
			}
			while (ps >= yys) {
				for (p = &yyact[ yypact[*ps+1] ] ; *p <= 0; p += 2)
					if (*p == -256) {
						panicps = ps;
						yystate= p[1] & 07777;
						yyOshifts = yyshifts;
						yyshifts = 0;
						paniced = 1;
						goto stack;
					}
				--ps;
				--yypv;
#ifdef PXP
				--yypw;
#endif
#ifdef PI
				if (OY.Yychar != YID)
					syneflg = TRUE;
#endif
				OY.Yychar = -1;
			}
			if (yychar == YEOF)
				yyunexeof();
			if (yystate == 1)
				yyexeof();
			yerror("Unrecoverable syntax error - QUIT");
			return;
	}
	panic("yyparse");
}
Ejemplo n.º 11
0
/* save the database to disk.                                   */
void save_db(void)
{
    const char procname[] = "save_db" ;
	FILE *fp;

	struct stat st;

	register int i, j;

	char *realfile=NULL, *bakfile=NULL;
    /* vi oppretter bakfile første gangen vi kaller rutinen
    hvis bakfile ikke er opprettet? 
    */
	char buf[BUFSIZ];

	/* If it doesn't need saving, never mind.                   */
	if (!dbmodified)
		return;

	/* Create name of file and a backup file.                   */
    realfile = getFullDbName() ; 
    bakfile = getDbBackupFileName()  ;
	/* Default creation mode.                                   */
	/* TODO: into header with this one                         */
	st.st_mode = 0400;
	/* better still use ... UMOD? */

	/* If file already exists, rename it to backup file name.   */
	if (stat(realfile, &st) == 0) {
	    int	ret = rename(realfile, bakfile);
        if (ret) {
           yerror(YFILE_RENMV_ERR,procname,bakfile,YX_EXTERNAL_CAUSE ) ; 
        }
    }
	/* Open new file.                                           */
	if ((fp = fopen(realfile, "w")) == NULL)
        yerror(YFILE_CREAT_ERR,procname,realfile,YX_EXTERNAL_CAUSE ) ; 
	/* Make sure database is sorted.                             */
    if (dbentries > 1 ) {
	    UErrorCode status = U_ZERO_ERROR;

	    compareCollator = ucol_open(getCollation(), &status);
	    if (U_SUCCESS(status)) {
		    qsort(db, (size_t) dbentries, sizeof(dbrecord),
	    	      (compFunc) dbsort);
	    } else {
            y_icuerror( YICU_CRECOLL_ERR, procname, "compareCollator", status ) ;
	    }
	    ucol_close(compareCollator);
    }
	/* START: */
	/* Write out entries.                                       */
	/* BUG: det som skjer er at feltet er tomt, så det får ikke noe nytt
	   innhold! */
	for (i = 0; i < dbentries; i++) {
		if ((db[i].db_flag & DB_VALID) == 0)
			continue;

		for (j = 0; j < idx.idx_nlines; j++) {
			if (db[i].db_lens[j] > 0) {
				/* if (usz > 0 ) { */
				(void)utf8FromUnicode(buf, (int32_t) BUFSIZ,
						      db[i].db_lines[j],
						      u_strlen(db[i].
							       db_lines[j]));
				fprintf(fp, "%s\n", buf);
			} else {
				fprintf(fp, "\n");
			}

		}
	}

	/* Set file mode to mode of orig file. Mark db as unmodified. */
	fchmod(fileno(fp), (mode_t) (st.st_mode & (mode_t) 0777));
	dbmodified = 0;

	fclose(fp);
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
/*
 * Trenger begrenset lengde på feltnavn: 100 tegn * 6 for multibyte.
 * Dette skal la oss ende på 100 widechar tegn.
 *
 * Så vidt jeg har skjønt er sammenhengene slik:
 *
 * http://www.unicode.org/faq/utf_bom.html
 * utf8:  1-4 bytes
 * utf16: 2-4 bytes ( to 16 bit verdier)
 * utf32  4 bytes ( 1 32 bit verdi) widechar. ncurses jobber bra med widechars på 32 bit.
 *
 * Dette betyr at: jeg trenger 400 bytes satt av for å lagre hva som helst på 100 tegn.

 * New business rules, in the advent of ability of creation of db files from the commandline.
   This is the entry point for that functionality.

   if the databasefile, is merely specified, AND the file doesn't yet exist, AND we don't find
   any label file. (open_label_file() returns NULL ), THEN we create a new label file for the
   non-existant db file. Of course, should we be so happy to find one along the path then
   we'll use this one?

 * */
void
read_labelfile(void)
{
    const char procname[]="read_labelfile" ;
	FILE *fp;

	register int len;

	char buf[BUFSIZ];	/* 1024 characters per line on Mac Os X */
    /* we have gotten the name when we come here */
    fp = open_label_file() ;
    if ((fp == NULL ) && (!hasPattern()) && (shouldCreateMissingLabelFile()|| dbFileHasNoPath())) {
       newLabelFilePath() ; 
       create_db() ;
        char *labelfn =  getFullLabelFileName() ; 
        if ( file_is_empty(labelfn) || (!labelFileOkAfterLinting(labelfn))) {
            ysimpleError("Index: User redecided creating a new database and thereby quitted.",YX_ALL_WELL) ;
        } 
        /* we remove any trailing line-endings here */
        setLabelFileCreated() ;
        fp = fopen(labelfn,"r") ;
 /*       if (dbFileHasNoPath() ) {

        } */
        
    } else if (fp == NULL ) {
           char *labelfn =  getFullLabelFileName() ; 
           yerror(YFILE_FINDF_ERR,procname,labelfn,YX_EXTERNAL_CAUSE ) ; 
    }
    

	/* Zero out structure.                                      */
    memset(&idx,(int)0, sizeof(idxfile) ) ;
	/* Read lines from file.                                    */
	while (idx.idx_nlines < MAXDBLINES) {
		/* End of file.                                         */
		if (fgets(buf, (int)BUFSIZ , fp) == NULL)
			break;

		/* Strip newline. replace with a colon                  */
		len = strlen(buf) - 1;
		if (!len) {
			buf[len] = '\0';
		} else {	/* check for a colon! */
			if (buf[(len - 1)] == ':') {
				buf[len] = '\0';
			} else {	/* no colon, so we insert one! */
				buf[len] = ':';
			}
		}
		/* If first char is '!', then this line should not      */
		/* participate in searches.  Save stuff after the '!'.  */
		/* Otherwise this line does participate in searches,    */
		/* save  the whole line.                                */
		if (*buf == '!') {
			idx.idx_lines[idx.idx_nlines] = mbstowcs_alloc(&buf[1]);
			idx.idx_search[idx.idx_nlines] = 0;
			len--;
		} else {
			idx.idx_lines[idx.idx_nlines] = mbstowcs_alloc(buf);
			idx.idx_search[idx.idx_nlines] = 1;
		}
		/* Increment number of lines.                           */
		idx.idx_nlines++;

		/* Save the length of the longest field name.           */
		if (len > idx.idx_maxlen)
			idx.idx_maxlen = len;
	}

	/* Close file.                                              */
	fclose(fp);
}
Ejemplo n.º 14
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);
}
Ejemplo n.º 15
0
/* TODO: all length calculations of the string must be rebuilt.
 *
 * BUG:
 *          Når jeg står på slutten av linjen så blir cursor pos
 *          justert mot venstre selv om jeg ikke sletter noe.
 *
 * */
void
prompt_str(int row, int col, const char *promptstr, wchar_t * answer)
{
	wchar_t *line = answer;

	int len, col0;

	/* struct sgttyb _tty ; */
	register int code, i, j;

	/* Converts  the promptstr to a  wide version.              */
	wchar_t *wpromptstr = mbstowcs_alloc(promptstr);

	if (wpromptstr == NULL) {
        yerror( YMBS_WCS_ERR,"prompt_str->mbstowcs_alloc", "wpromptstr", YX_EXTERNAL_CAUSE ) ;
    }

	wchar_t ch;

	/* Print the wide prompt at (row,col).                          */
	mvaddwstr(row, col, wpromptstr);

	refresh();

	/* Calc "column zero", which is at right end of prompt.     */
	col += wcslen(wpromptstr);
	col0 = col;
	mvaddwstr(row, col, answer);
    len = wcslen(answer) ;
    col += len ; 
	/* Read chars till we get what we want. Useris allowed      */
	/* basic EMACS-style line editing.                          */
	while ((code = get_wch(&ch)) != EOF) {
		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 there's stuff in the string,
			 * delete this character.
			 */
			if (col == (col0 + (int)wcslen(line))) {
				col--;
			} else if (len) {
				/* Calc string pos of char to delete.           */
				i = col - col0;

				/* Shuffle the string "left" one place.         */
				while (i < len) {
					line[i] = line[i + 1];
					i++;
				}

				/* Delete char on the screen.                   */
				len -= 1;
				delch();	/* prob ok that isn't wide. */
                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 stuff in the string, delete char.             */
			if (len && ((col - 1) >= col0)) {
				/* Calc pos in string of char to delete         */
				int l = col - col0 - 1;
				if (l < 0)
					break;
				/* Shuffle the string "left" one place.         */
				while (l < len) {
					line[l] = line[l + 1];
					l++;
				}

				len -= 1;
				/* Delete the character on the screen.          */
				move(row, --col);
				delch();
			}
			break;
		case CTRL('k'):	/* kill line                    */
			/* Clear the string.                                */
			if (len) {
				i = col - col0;

				line[i] = '\0';
				len = i;

				clrtoeol();
			}
			break;
		case CTRL('l'):	/* redraw screen                */
			wrefresh(curscr);
			break;
		case KEY_ENTER:
		case '\r':	/* return the string            */
		case '\n':	/* return the string            */
			line[len] = '\0';
			return;
		default:	/* regular character            */
			if (ch == KEY_DL) {
				move(row, col0);
				clrtoeol();
				col = col0;

				*line = '\0';
				len = 0;
			} else if (code != KEY_CODE_YES) {
				if (iswctype(ch, wctype("print"))) {
					if (col == (COLS - 1)) {
						beep();
						break;
					}
					/* Calculate position of char in string.    */
					i = col - col0;

					/* If we have to, move string "right" one   */
					/* place 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);
					/* ins_wch(&ch); */
				}
			}
			break;
		}

		/* Move the cursor.                                     */
		move(row, col);
		refresh();
	}
}