📄 fea_edit.c
字号:
/* fea_edit - edit an ESPS FEA file * * This material contains proprietary software of Entropic Speech, Inc. * Any reproduction, distribution, or publication without the prior * written permission of Entropic Speech, Inc. is strictly prohibited. * Any public distribution of copies of this work authorized in writing by * Entropic Speech, Inc. must bear the notice * * "Copyright (c) 1987 Entropic Speech, Inc.; All rights reserved" * * This program is an ESPS feature file editor. It puts the feature * file into a temp file in ascii and calls the editor named by the * environment variable "EDITOR" or vi if that is NULL. Usage is * * fea_edit [-x debug-level] [-n] [-g] file [output-file] * * -x is debug option * -n causes the original header not be saved as a embedded header * -g causes the generic headers to be present for editing also * file is the file to edit * output-file is an optional output file. If no output file is given * then the changed file overwrites the input file. If an output file * is given, then the input file is not changed. * * Author: Alan Parker, EPI, Washington, DC * -g option by Ajaipal S. Virdy **/#include <stdio.h>#include <esps/esps.h>#include <esps/fea.h>#include <assert.h>#include <ctype.h>#ifdef SCCS static char *sccs_id = "@(#)fea_edit.c 1.6 7/16/87 ESI";#endif#define VERSION "1.6"#define DATE "7/16/87"#define PROG "fea_edit"#define BUFSIZE 1024#define DEFAULT_ED "vi"/* * U N I X * R O U T I N E S * R E F E R E N C E D */double atof ();int atoi ();long atol ();void exit ();void perror ();int rename();void rewind ();char *calloc ();char *realloc ();char *getenv ();char *mktemp ();char *strcat ();char *strcpy ();char *strncat ();char *strtok ();/* * E S P S * R O U T I N E S * R E F E R E N C E D */float **f_mat_alloc ();char *get_cmd_line ();long get_fea_siz ();int lin_search2 ();char *savestring ();short get_fea_type ();short fea_encode ();/* L O C A L R O U T I N E S */void clear_fea_rec ();char **fill_codes1 ();void print_rec ();short type_str ();/* G L O B A L V A R I A B L E S */char buf[BUFSIZE];char *editor;int debug = 0;main (argc, argv)int argc;char **argv;{ int c, flag = 1, rec_count = 0; extern optind, errno; extern char *optarg; char *ProgName = "fea_edit"; char *template = "/tmp/feXXXXXX"; FILE *in, *tstrm, *out; struct header *ih, *oh; struct fea_data *fea_rec; struct fea_header *fea; int i, j, k, nflag = 0, update = 0, gflag = 0; int type_tmp, tag_tmp, segment_tmp, ngen; char **gen_names, **genhd, *outfile, **code_ptr, **cc_ptr, **enums = NULL; double *dptr; float *fptr; long *lptr, *dimens = NULL, size; short *sptr, rank, type; char *cptr, *dimen_chr, *name, *type_chr, *size_chr, *rank_chr; int getopt (); while ((c = getopt (argc, argv, "x:ng")) != EOF) { switch (c) { case 'x': debug = atoi (optarg); break; case 'n': nflag++; break; case 'g': gflag++; break; } } switch (argc - optind) { case 1: update = YES; break; case 2: update = NO; break; default: Fprintf (stderr, "usage: fea_edit [-x debug_level] [-g] [-n] file [output]\n"); exit (1); break; } outfile = argv[argc - 1]; if (debug > 0) if (!update) Fprintf (stderr, "%s: input file is %s, output file is %s.\n", ProgName, argv[optind], outfile); else Fprintf (stderr, "%s: input file %s will be updated.\n", ProgName, argv[optind]); TRYOPEN ("fea_edit", argv[optind], "r", in); if (!(ih = read_header (in))) NOTSPS ("fea_edit", argv[optind]); if (ih -> common.type != FT_FEA) { Fprintf (stderr, "fea_edit: %s not a FEA file.\n", argv[optind]); exit (1); } if ((tstrm = fopen (mktemp (template), "w")) == NULL) CANTOPEN ("fea_edit", template); fea_rec = allo_fea_rec (ih); fea = ih -> hd.fea; Fprintf (tstrm, "%x %x %x << do not edit >>\n", ih -> common.tag, fea -> fea_type, fea -> segment_labeled); for (i = 0; i < fea -> field_count; i++) { Fprintf (tstrm, "%s %s ", fea -> names[i], type_codes[fea -> types[i]]); Fprintf (tstrm, "%ld %d ", fea -> sizes[i], fea -> ranks[i]); if (fea -> ranks[i] > 1) for (j = 0; j < fea -> ranks[i]; j++) Fprintf (tstrm, "%ld ", fea -> dimens[i][j]); Fprintf (tstrm, "\n"); if (fea -> types[i] == CODED) { char **s; s = fea -> enums[i]; while (*s != NULL) { Fprintf (tstrm, " %s\n", *s++); } } } if (gflag) { gen_names = genhd_list (&ngen, ih); for (i = 0; i < ngen; i++) { char *cptr; double *dptr; float *fptr; long *lptr; short *sptr; type = genhd_type (gen_names[i], &size, ih); Fprintf (tstrm, "\n"); Fprintf (tstrm, "@%s %s %ld ", gen_names[i], type_codes[type], size); k = 0; cptr = get_genhd(gen_names[i], ih); if (type == CODED) { char **s; s = genhd_codes(gen_names[i], ih); Fprintf (tstrm, "[ "); while (*s != NULL) Fprintf (tstrm, "%s ", *s++); Fprintf (tstrm, "] "); } if ((type == CHAR) && (size > 1)) { Fprintf (tstrm, "%s ", cptr); } else for (j = 0; j < size; j++) { k++; if (k > 7) { Fprintf (tstrm, "\n"); k = 0; } switch(type) { case DOUBLE: dptr = (double *)get_genhd(gen_names[i],ih); Fprintf (tstrm, "%lg ",dptr[j]); break; case FLOAT: fptr = (float *)get_genhd(gen_names[i],ih); Fprintf (tstrm, "%g ",fptr[j]); break; case SHORT: sptr = (short *)get_genhd(gen_names[i],ih); Fprintf (tstrm, "%d ",sptr[j]); break; case LONG: lptr = (long *)get_genhd(gen_names[i],ih); Fprintf (tstrm, "%ld ",lptr[j]); break; case CHAR: cptr = get_genhd(gen_names[i],ih); Fprintf (tstrm, "0x%x",cptr[j]); break; case CODED: { char **codes = genhd_codes(gen_names[i],ih); sptr = (short *)get_genhd(gen_names[i],ih); if (idx_ok(sptr[j],codes)) Fprintf (tstrm, "%s ",codes[sptr[j]]); else Fprintf (tstrm, "invalid code %d ",sptr[j]); break; } } } } if (ngen > 0) Fprintf (tstrm, "\n"); } while (get_fea_rec (fea_rec, ih, in) != EOF) { Fprintf (tstrm, "\n"); print_rec (fea_rec, ih, tstrm); } (void ) fclose (in); (void ) fclose (tstrm);again: if ((editor = getenv ("EDITOR")) == NULL) editor = DEFAULT_ED; (void) sprintf (buf, "%s %s", editor, template); if (system (buf) != NULL) { Fprintf(stderr,"fea_edit: Cannot run editor. Buffer: %s\n",buf); (void) unlink(template); } Fprintf(stderr,"fea_edit: Make changes? [return for yes, n for abort] "); if (getchar() != 'n') { if (update) { Fprintf (stderr,"fea_edit: Making changes to input file, "); (void) sprintf (buf, "%s.bak", argv[optind]); if (rename (argv[optind], buf) != 0) { perror ("fea_edit"); (void) unlink(template); exit (1); } Fprintf (stderr,"original %s saved in %s\n", argv[optind], buf); } else Fprintf(stderr,"fea_edit: Creating output file %s\n", outfile); TRYOPEN ("fea_edit", outfile, "w+", out); TRYOPEN ("fea_edit", template, "r", tstrm); oh = new_header (FT_FEA); if (!nflag) { add_source_file (oh, argv[optind], ih); oh->variable.refhd = ih->variable.refhd; } (void) add_comment (oh, get_cmd_line (argc, argv)); (void) strcpy(oh->common.prog, PROG); (void) strcpy(oh->common.vers, VERSION); (void) strcpy(oh->common.progdate, DATE); if (!gflag) { genhd = genhd_list(&ngen,ih); while (ngen--) { int size; short type; type = genhd_type (genhd[ngen], &size, ih); (void) add_genhd (genhd[ngen],type, size, get_genhd(genhd[ngen], ih), genhd_codes(genhd[ngen], ih), oh); } } if (fgets (buf, BUFSIZE, tstrm) == NULL) goto trouble; (void) sscanf (buf, "%x %x %x", &tag_tmp, &type_tmp, &segment_tmp); oh -> common.tag = tag_tmp; oh -> hd.fea -> fea_type = type_tmp; oh -> hd.fea -> segment_labeled = segment_tmp; if (fgets (buf, BUFSIZE, tstrm) == NULL) goto trouble; while (buf[0] != '\n') { if ((name = strtok (buf, " \t")) == NULL) goto trouble; if ((type_chr = strtok (0, " \t")) == NULL) goto trouble; if ((size_chr = strtok (0, " \t")) == NULL) goto trouble; if ((rank_chr = strtok (0, " \t")) == NULL) goto trouble; size = atol (size_chr); rank = atoi (rank_chr); dimens = NULL; enums = NULL; if (rank > 1) { int r = rank; long *dp; dp = dimens = (long *) calloc ((unsigned)rank, sizeof (long)); while (r--) { if ((dimen_chr = strtok (0, " \t")) == NULL) break; *dp++ = atol (dimen_chr); } } type = type_str (type_chr); if (type == CODED) { int k = 0; name = savestring (name); enums = (char **) calloc (1, sizeof (char *)); while (1) { if (fgets (buf, BUFSIZE, tstrm) == NULL) goto trouble; if (*buf != ' ') break; enums[k++] = savestring (strtok (buf + 1, "\n")); enums = (char **) realloc ((char *) enums, (k + 1) * sizeof (char *)); enums[k] = NULL; } } if (add_fea_fld(name, size, rank, dimens, type, enums, oh) != 0) { Fprintf (stderr, "fea_edit: Trouble creating field for %s.\n", name); goto trouble; } if (type != CODED) if (fgets (buf, BUFSIZE, tstrm) == NULL) goto trouble; } /* end while (buf[0] != '\n') */ /* * A single carriage return has just been read. * Next fgets() either gets generic header stuff (i.e. buf[0] * is '@') or data (buf[0] = '#') depending upon the gflag. */ /* Now process the generic header stuff (if any) */ if (gflag) { if (fgets (buf, BUFSIZE, tstrm) == NULL) /* buf[0] is '@' */ goto trouble; while (buf[0] != '\n') { if (flag == 0 || *buf == '\n') { if (fgets (buf, BUFSIZE, tstrm) == NULL) break; } else if (*buf == '@') { if (debug > 0) Fprintf (stderr, "%s: buf = %s\n", ProgName, buf); if ((name = strtok (buf, " \t")) == NULL) goto trouble; name = savestring (name); name++; if ((type_chr = strtok (0, " \t")) == NULL) goto trouble; if ((size_chr = strtok (0, " \t")) == NULL) goto trouble; type = type_str (type_chr); size = atol (size_chr); if (debug > 2) Fprintf (stderr, "%s: name = %s, type = %s, size = %ld\n", ProgName, name, type_codes[type], size); if (type == CODED) { char **tmp_codes = (char **) calloc (1, sizeof (char *)); int gen_fields = 0; cc_ptr = (char **) calloc (1, sizeof (char *)); code_ptr = fill_codes1 (cc_ptr, size, name, oh, tstrm, '@', &gen_fields); if (debug > 5) Fprintf (stderr, "gen_fields = %d\n", gen_fields); (void) add_genhd_e (name, NULL, size, code_ptr, oh); } else (void) add_genhd (name, type, size, NULL, (char **) NULL, oh); switch (type) { case SHORT: sptr = (short *) get_genhd (name, oh); flag = fill_shorts (sptr, size, tstrm, '@'); break; case LONG: lptr = (long *) get_genhd (name, oh); flag = fill_longs (lptr, size, tstrm, '@'); break; case FLOAT: fptr = (float *) get_genhd (name, oh); flag = fill_floats (fptr, size, tstrm, '@'); break; case DOUBLE: dptr = (double *) get_genhd (name, oh); flag = fill_doubles (dptr, size, tstrm, '@'); break; case CHAR: cptr = get_genhd (name, oh); flag = fill_chars (cptr, size, tstrm, '@'); break; case CODED: sptr = (short *) get_genhd (name, oh); flag = fill_gencoded (sptr, size, name, oh, tstrm, '@', code_ptr); break; } } else if (*buf == '#') break; } /* end while (buf[0] != '\n') */ } flag = 1; /* reset flag */ write_header (oh, out); fea_rec = allo_fea_rec (oh); /* A single carriage return following the generic header (if any) * has just been read. Next fgets() gets data (i.e. buf[0] = '#'). */ if (fgets (buf, BUFSIZE, tstrm) == NULL) { Fprintf (stderr, "fea_edit: No data to process back in?\n"); exit (0); } while (1) { if (flag == 0 || *buf == '\n') { put_fea_rec (fea_rec, oh, out); clear_fea_rec (fea_rec, oh); rec_count++; if (fgets (buf, BUFSIZE, tstrm) == NULL) break; } else if (*buf == '#') { if (debug > 0) Fprintf (stderr, "fea_edit: %s", buf); if ((name = strtok (buf, " \t")) == NULL) goto trouble;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -