📄 msgcat.c
字号:
c = '\f'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; case 'r': c = '\r'; break; case '\\': c = '\\'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c -= '0'; d = getc(fp); if (d >= '0' && d <= '7') { c = c*8 + d - '0'; d = getc(fp); if (d >= '0' && d <= '7') c = c*8 + d - '0'; else if (d != EOF) ungetc(d,fp); } else if (d != EOF) ungetc(d, fp); if (c == '\0') continue; /* XXX */ break; default: /* Ignore the quote. */ break; } } if (i >= read_buf_len) { if (!read_buf) read_buf = malloc(read_buf_len = 40); else read_buf = realloc(read_buf, read_buf_len *= 2); if (!read_buf) { cat_errno = E_NOMEM; return 0; } } read_buf[i++] = c; } p = malloc(i + 1); if (!p) { cat_errno = E_NOMEM; return 0; } memcpy(p, read_buf, i); p[i] = '\0'; return p;} /* 0 success, -1 error */staticint parse_command(fp, table, setnump, quotep)FILE *fp;struct message **table;unsigned *setnump;int *quotep;{ char buf[128]; if (fgets(buf, 128, fp) == NULL) { cat_errno = ferror(fp) ? E_INPUT : E_EOF; return -1; } if (buf[0] == ' ' || buf[0] == '\t' || buf[0] == '\n') /* a comment */; else if (strncmp(buf, "set", 3) == 0) { if (sscanf(buf + 3, "%u", setnump) != 1) { cat_errno = E_BADARG; return -1; } } else if (strncmp(buf, "delset", 6) == 0) { unsigned num; if (sscanf(buf + 6, "%u", &num) != 1) { cat_errno = E_BADARG; return -1; } delete_set(table, num); *setnump = NL_SETD; } else if (strncmp(buf, "quote", 5) == 0) { char *p = buf + 5; while (*p == ' ' || *p == '\t') p++; /* XXX should \ be allowed as the quote character? */ if (*p == '\0' || *p == '\n') *quotep = -1; else *quotep = *p; } else { cat_errno = E_NOSUCHCOMMAND; return -1; } if (strchr(buf, '\n') == 0) { int c; while ((c = getc(fp)) != '\n' && c != EOF) ; } return 0;}staticVOID delete_set(table, setnum)struct message **table;unsigned setnum;{ int i; for (i = 0; i < HASH_TAB_SIZE; i++) { struct message *p, *nextp; for (p = table[i], table[i] = 0; p; p = nextp) { nextp = p->next; if (p->setnum == setnum) free((char *)p); else { p->next = table[i]; table[i] = p; } } }}staticVOID delete_message(table, setnum, msgnum)struct message **table;unsigned setnum, msgnum;{ struct message **pp; for (pp = &table[hash(setnum, msgnum)]; *pp; pp = &(*pp)->next) if ((*pp)->setnum == setnum && (*pp)->msgnum == msgnum) { struct message *p = *pp; *pp = p->next; free(p->text); free((char *)p); break; }}/* 0 success, -1 error. On error cat_errno is set to the error number. */staticint read_catalog(fp, table)FILE *fp;struct message **table;{ int c; unsigned setnum = NL_SETD; int quote_char = -1; for (;;) { /* start of line */ c = getc(fp); if (c == EOF) break; ++current_lineno; if (isdigit(c)) { if (parse_message(c, fp, table, setnum, quote_char) < 0) return -1; } else if (c == '$') { if (parse_command(fp, table, &setnum, "e_char) < 0) return -1; } else if (c != '\n') { while ((c = getc(fp)) != '\n' && c != EOF) if (c != ' ' && c != '\t') { cat_errno = E_BADLINE; return -1; } if (c == EOF) break; } } return 0;}staticint hash(setnum, msgnum)unsigned setnum, msgnum;{ return ((setnum << 8) + msgnum) % HASH_TAB_SIZE;}#ifdef GENCATstatic char *program_name;static int message_compare P((UNIV, UNIV));static void print_text P((char *, FILE *));static void usage P((void));#ifdef VARARGSstatic void fatal();#elsestatic void fatal P((char *,...));#endifint main(argc, argv)int argc;char **argv;{ FILE *fp; int i, j, nmessages; struct message **list; unsigned setnum; struct message *table[HASH_TAB_SIZE]; program_name = argv[0]; if (argc < 3) usage(); for (i = 0; i < HASH_TAB_SIZE; i++) table[i] = 0; for (i = 1; i < argc; i++) { errno = 0; fp = fopen(argv[i], "r"); if (!fp) { if (i > 1) fatal("can't open `%s': %s", argv[i], strerror(errno)); } else { current_lineno = 0; cat_errno = E_ZERO; if (read_catalog(fp, table) < 0) { assert(cat_errno != E_ZERO); assert(cat_errno < sizeof(cat_errlist)/sizeof(cat_errlist[0])); fatal("%s:%d: %s", argv[i], current_lineno, cat_errlist[cat_errno]); } fclose(fp); } } errno = 0; fp = fopen(argv[1], "w"); if (!fp) fatal("can't open `%s' for output: %s", argv[1], strerror(errno)); nmessages = 0; for (i = 0; i < HASH_TAB_SIZE; i++) { struct message *p; for (p = table[i]; p; p = p->next) nmessages++; } list = (struct message **)malloc(nmessages*sizeof(struct message *)); if (!list) fatal("out of memory"); j = 0; for (i = 0; i < HASH_TAB_SIZE; i++) { struct message *p; for (p = table[i]; p; p = p->next) list[j++] = p; } assert(j == nmessages); qsort((UNIV)list, nmessages, sizeof(struct message *), message_compare); setnum = NL_SETD; for (i = 0; i < nmessages; i++) { struct message *p = list[i]; if (p->setnum != setnum) { setnum = p->setnum; fprintf(fp, "$set %u\n", setnum); } fprintf(fp, "%u ", p->msgnum); print_text(p->text, fp); putc('\n', fp); } if (fclose(fp) == EOF) fatal("error closing `%s'", argv[1]); return 0;}staticVOID usage(){ fprintf(stderr, "usage: %s catfile msgfile...\n", program_name); exit(1);}static#ifdef VARARGSVOID fatal(va_alist) va_dcl#else /* not VARARGS */VOID fatal(char *message,...)#endif /* not VARARGS */{ va_list ap;#ifdef VARARGS char *message; va_start(ap); message = va_arg(ap, char *);#else /* not VARARGS */ va_start(ap, message);#endif /* not VARARGS */ fprintf(stderr, "%s: ", program_name); vfprintf(stderr, message, ap); putc('\n', stderr); va_end(ap); exit(1);}staticint message_compare(p1, p2)UNIV p1;UNIV p2;{ struct message *m1 = *(struct message **)p1; struct message *m2 = *(struct message **)p2; if (m1->setnum < m2->setnum) return -1; if (m1->setnum > m2->setnum) return 1; if (m1->msgnum < m2->msgnum) return -1; if (m1->msgnum > m2->msgnum) return 1; return 0;}staticVOID print_text(s, fp)char *s;FILE *fp;{ for (; *s; s++) { if (*s == '\\') fputs("\\\\", fp); else if (ISASCII(*s) && isprint((unsigned char)*s)) putc(*s, fp); else { switch (*s) { case '\n': fputs("\\n", fp); break; case '\b': fputs("\\b", fp); break; case '\f': fputs("\\f", fp); break; case '\t': fputs("\\t", fp); break; case '\v': fputs("\\v", fp); break; case '\r': fputs("\\r", fp); break; default: fprintf(fp, "\\%03o", (unsigned char)*s); break; } } }}#endif /* GENCAT */#ifdef TESTint main(argc, argv)int argc;char **argv;{ nl_catd catd; int msgnum, setnum; if (argc != 2) { fprintf(stderr, "usage: %s catalogue\n", argv[0]); exit(1); } catd = catopen(argv[1], 0); fprintf(stderr, "Enter set number, message number pairs:\n"); fflush(stderr); while (scanf("%d %d", &setnum, &msgnum) == 2) { char *msg = catgets(catd, setnum, msgnum, "<default>"); fprintf(stderr, "Returned \"%s\"\n", msg); fflush(stderr); } return 0;}#endif /* TEST */#endif /* not HAVE_CAT *//*Local Variables:c-indent-level: 5c-continued-statement-offset: 5c-brace-offset: -5c-argdecl-indent: 0c-label-offset: -5End:*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -