📄 text.c
字号:
inttext_event (int i){ if (te[i].name == NULL) return 0; else return 1;}static voidpevent_load_defaults (){ int i, len; for (i = 0; i < NUM_XP; i++) { if (!text_event (i)) continue; len = strlen (_(te[i].def)); len++; if (pntevts_text[i]) free (pntevts_text[i]); pntevts_text[i] = malloc (len); memcpy (pntevts_text[i], _(te[i].def), len); }}voidpevent_make_pntevts (){ int i, m, len; char out[1024]; for (i = 0; i < NUM_XP; i++) { if (!text_event (i)) continue; if (pntevts[i] != NULL) free (pntevts[i]); if (pevt_build_string (pntevts_text[i], &(pntevts[i]), &m) != 0) { snprintf (out, sizeof (out), _("Error parsing event %s.\nLoading default"), te[i].name); fe_message (out, FALSE); free (pntevts_text[i]); len = strlen (te[i].def) + 1; pntevts_text[i] = malloc (len); memcpy (pntevts_text[i], te[i].def, len); if (pevt_build_string (pntevts_text[i], &(pntevts[i]), &m) != 0) { fprintf (stderr, "XChat CRITICAL *** default event text failed to build!\n"); abort (); } } check_special_chars (pntevts[i], TRUE); }}/* Loading happens at 2 levels: 1) File is read into blocks 2) Pe block is parsed and loaded --AGL *//* Better hope you pass good args.. --AGL */static voidpevent_trigger_load (int *i_penum, char **i_text, char **i_snd){ int penum = *i_penum, len; char *text = *i_text, *snd = *i_snd; if (penum != -1 && text != NULL) { len = strlen (text) + 1; if (pntevts_text[penum]) free (pntevts_text[penum]); pntevts_text[penum] = malloc (len); memcpy (pntevts_text[penum], text, len); if (te[penum].sound) free (te[penum].sound); if (snd) { len = strlen (snd) + 1; te[penum].sound = malloc (len); memcpy (te[penum].sound, snd, len); } else te[penum].sound = NULL; } if (text) free (text); if (snd) free (snd); *i_text = NULL; *i_snd = NULL; *i_penum = 0;}static intpevent_find (char *name, int *i_i){ int i = *i_i, j; j = i + 1; while (1) { if (j == NUM_XP) j = 0; if (j == i) return -1; if (!text_event (j)) { j++; continue; } if (strcmp (te[j].name, name) == 0) { *i_i = j; return j; } j++; }}intpevent_load (char *filename){ /* AGL, I've changed this file and pevent_save, could you please take a look at * the changes and possibly modify them to suit you * //David H */ char *buf, *ibuf; int fd, i = 0, pnt = 0; struct stat st; char *text = NULL, *snd = NULL; int penum = 0; char *ofs; buf = malloc (1000); if (filename == NULL) snprintf (buf, 1000, "%s/pevents.conf", get_xdir ()); else strncpy (buf, filename, 1000); fd = open (buf, O_RDONLY | OFLAGS); free (buf); if (fd < 0) return 1; if (fstat (fd, &st) != 0) return 1; ibuf = malloc (st.st_size); read (fd, ibuf, st.st_size); close (fd); while (buf_get_line (ibuf, &buf, &pnt, st.st_size)) { if (buf[0] == '#') continue; if (strlen (buf) == 0) continue; ofs = strchr (buf, '='); if (!ofs) continue; *ofs = 0; ofs++; if (*ofs == 0) continue; if (strcmp (buf, "event_name") == 0) { if (penum) pevent_trigger_load (&penum, &text, &snd); penum = pevent_find (ofs, &i); continue; } else if (strcmp (buf, "event_text") == 0) { if (text) free (text); text = strdup (ofs); continue; } else if (strcmp (buf, "event_sound") == 0) { if (snd) free (snd); snd = strdup (ofs); continue; } continue; } pevent_trigger_load (&penum, &text, &snd); free (ibuf); return 0;}static voidpevent_check_all_loaded (){ int i, len; for (i = 0; i < NUM_XP; i++) { if (!text_event (i)) continue; if (pntevts_text[i] == NULL) { /*printf ("%s\n", te[i].name); snprintf(out, sizeof(out), "The data for event %s failed to load. Reverting to defaults.\nThis may be because a new version of XChat is loading an old config file.\n\nCheck all print event texts are correct", evtnames[i]); gtkutil_simpledialog(out); */ len = strlen (te[i].def) + 1; pntevts_text[i] = malloc (len); memcpy (pntevts_text[i], te[i].def, len); } }}voidload_text_events (){ /* I don't free these as the only time when we don't need them is once XChat has exit(2)'ed, so why bother ?? --AGL */ pntevts_text = malloc (sizeof (char *) * (NUM_XP)); memset (pntevts_text, 0, sizeof (char *) * (NUM_XP)); pntevts = malloc (sizeof (char *) * (NUM_XP)); memset (pntevts, 0, sizeof (char *) * (NUM_XP)); if (pevent_load (NULL)) pevent_load_defaults (); pevent_check_all_loaded (); pevent_make_pntevts ();}static voiddisplay_event (char *i, struct session *sess, int numargs, char **args){ int len, oi, ii, *ar; char o[4096], d, a, done_all = FALSE; oi = ii = len = d = a = 0; if (i == NULL) return; while (done_all == FALSE) { d = i[ii++]; switch (d) { case 0: memcpy (&len, &(i[ii]), sizeof (int)); ii += sizeof (int); if (oi + len > sizeof (o)) { printf ("Overflow in display_event (%s)\n", i); return; } memcpy (&(o[oi]), &(i[ii]), len); oi += len; ii += len; break; case 1: a = i[ii++]; if (a > numargs) { fprintf (stderr, "XChat DEBUG: display_event: arg > numargs (%d %d %s)\n", a, numargs, i); break; } ar = (int *) args[(int) a]; if (ar == NULL) { printf ("Error args[a] == NULL in display_event\n"); abort (); } len = strlen ((char *) ar); memcpy (&o[oi], ar, len); oi += len; break; case 2: o[oi++] = '\n'; o[oi++] = 0; done_all = TRUE; continue; case 3: if (sess->type == SESS_DIALOG) { if (prefs.dialog_indent_nicks) o[oi++] = '\t'; else o[oi++] = ' '; } else { if (prefs.indent_nicks) o[oi++] = '\t'; else o[oi++] = ' '; } break; } } o[oi] = 0; if (*o == '\n') return; PrintText (sess, o);}intpevt_build_string (char *input, char **output, int *max_arg){ struct pevt_stage1 *s = NULL, *base = NULL, *last = NULL, *next; int clen; char o[4096], d, *obuf, *i; int oi, ii, max = -1, len, x; len = strlen (input); i = malloc (len + 1); memcpy (i, input, len + 1); check_special_chars (i, TRUE); len = strlen (i); clen = oi = ii = 0; for (;;) { if (ii == len) break; d = i[ii++]; if (d != '$') { o[oi++] = d; continue; } if (i[ii] == '$') { o[oi++] = '$'; continue; } if (oi > 0) { s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); if (base == NULL) base = s; if (last != NULL) last->next = s; last = s; s->next = NULL; s->data = malloc (oi + sizeof (int) + 1); s->len = oi + sizeof (int) + 1; clen += oi + sizeof (int) + 1; s->data[0] = 0; memcpy (&(s->data[1]), &oi, sizeof (int)); memcpy (&(s->data[1 + sizeof (int)]), o, oi); oi = 0; } if (ii == len) { fe_message ("String ends with a $", FALSE); return 1; } d = i[ii++]; if (d == 'a') { /* Hex value */ x = 0; if (ii == len) goto a_len_error; d = i[ii++]; d -= '0'; x = d * 100; if (ii == len) goto a_len_error; d = i[ii++]; d -= '0'; x += d * 10; if (ii == len) goto a_len_error; d = i[ii++]; d -= '0'; x += d; if (x > 255) goto a_range_error; o[oi++] = x; continue; a_len_error: fe_message ("String ends in $a", FALSE); return 1; a_range_error: fe_message ("$a value is greater then 255", FALSE); return 1; } if (d == 't') { /* Tab - if tabnicks is set then write '\t' else ' ' */ /*s = g_new (struct pevt_stage1, 1); */ s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); if (base == NULL) base = s; if (last != NULL) last->next = s; last = s; s->next = NULL; s->data = malloc (1); s->len = 1; clen += 1; s->data[0] = 3; continue; } if (d < '1' || d > '9') { snprintf (o, sizeof (o), "Error, invalid argument $%c\n", d); fe_message (o, FALSE); return 1; } d -= '0'; if (max < d) max = d; s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); if (base == NULL) base = s; if (last != NULL) last->next = s; last = s; s->next = NULL; s->data = malloc (2); s->len = 2; clen += 2; s->data[0] = 1; s->data[1] = d - 1; } if (oi > 0) { s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); if (base == NULL) base = s; if (last != NULL) last->next = s; last = s; s->next = NULL; s->data = malloc (oi + sizeof (int) + 1); s->len = oi + sizeof (int) + 1; clen += oi + sizeof (int) + 1; s->data[0] = 0; memcpy (&(s->data[1]), &oi, sizeof (int)); memcpy (&(s->data[1 + sizeof (int)]), o, oi); oi = 0; } s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); if (base == NULL) base = s; if (last != NULL) last->next = s; last = s; s->next = NULL; s->data = malloc (1); s->len = 1; clen += 1; s->data[0] = 2; oi = 0; s = base; obuf = malloc (clen); while (s) { next = s->next; memcpy (&obuf[oi], s->data, s->len); oi += s->len; free (s->data); free (s); s = next; } free (i); if (max_arg) *max_arg = max; if (output) *output = obuf; return 0;}static voidplay_wave (char *file){ char *buf = malloc (512); snprintf (buf, 512, "%s/%s", prefs.sounddir, file); if (access (buf, R_OK) == 0) { snprintf (buf, 512, "%s %s/%s", prefs.soundcmd, prefs.sounddir, file); xchat_exec (buf); } free (buf);}static inttextsignal_handler (struct session *sess, void *b, void *c, void *d, void *e, char f){ /* This handler *MUST* always be the last in the chain because it doesn't call the next handler */ char *args[8]; int numargs, i; if (!sess) return 0; if (!text_event (current_signal)) { printf ("error, textsignal_handler passed non TE signal (%d)\n", current_signal); abort (); } numargs = te[current_signal].num_args; i = 0;#ifdef USE_PERL if (perl_print (te[current_signal].name, sess, b, c, d, e)) return TRUE;#endif if (te[current_signal].sound) play_wave (te[current_signal].sound); args[0] = b; args[1] = c; args[2] = d; args[3] = e; display_event (pntevts[(int) current_signal], sess, numargs, args); return 0;}voidprintevent_setup (){ int evt; struct xp_signal *sig; sig = (struct xp_signal *) malloc (sizeof (struct xp_signal)); sig->signal = -1; sig->naddr = NULL; sig->callback = XP_CALLBACK (textsignal_handler);#ifdef USE_PLUGIN sig->mod = NULL;#endif for (evt = 0; evt < NUM_XP; evt++) { if (!text_event (evt)) continue; g_assert (!sigroots[evt]); sigroots[evt] = g_slist_prepend (sigroots[evt], sig); }}voidpevent_save (char *fn){ int fd, i; char buf[1024]; if (!fn) snprintf (buf, sizeof (buf), "%s/pevents.conf", get_xdir ()); else snprintf (buf, sizeof (buf), "%s", fn); fd = open (buf, O_CREAT | O_TRUNC | O_WRONLY | OFLAGS, 0x180); if (fd < 0) { /* fe_message ("Error opening config file\n", FALSE); If we get here when X-Chat is closing the fe-message causes a nice & hard crash so we have to use perror which doesn't rely on GTK */ perror ("Error opening config file\n"); return; } for (i = 0; i < NUM_XP; i++) { if (!text_event (i)) continue; write (fd, buf, snprintf (buf, sizeof (buf), "event_name=%s\n", te[i].name)); write (fd, buf, snprintf (buf, sizeof (buf), "event_text=%s\n", pntevts_text[i])); if (te[i].sound && te[i].sound[0]) write (fd, buf, snprintf (buf, sizeof (buf), "event_sound=%s\n", te[i].sound)); write (fd, "\n", 1); } close (fd);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -